aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/libmpq/AUTHORS10
-rw-r--r--contrib/libmpq/COPYING339
-rw-r--r--contrib/libmpq/FAQ68
-rw-r--r--contrib/libmpq/Makefile.am26
-rw-r--r--contrib/libmpq/NEWS76
-rw-r--r--contrib/libmpq/README34
-rw-r--r--contrib/libmpq/THANKS21
-rw-r--r--contrib/libmpq/TODO10
-rw-r--r--contrib/libmpq/autogen.sh19
-rw-r--r--contrib/libmpq/bindings/Makefile.am6
-rw-r--r--contrib/libmpq/bindings/d/Makefile.am6
-rw-r--r--contrib/libmpq/bindings/d/dsss.conf2
-rw-r--r--contrib/libmpq/bindings/d/mpq.d318
-rw-r--r--contrib/libmpq/bindings/python/Makefile.am5
-rw-r--r--contrib/libmpq/bindings/python/mpq-info16
-rw-r--r--contrib/libmpq/bindings/python/mpq.py322
-rw-r--r--contrib/libmpq/configure.ac84
-rw-r--r--contrib/libmpq/debian/changelog35
-rw-r--r--contrib/libmpq/debian/compat1
-rw-r--r--contrib/libmpq/debian/control50
-rw-r--r--contrib/libmpq/debian/copyright23
-rw-r--r--contrib/libmpq/debian/libmpq-dev.dirs6
-rw-r--r--contrib/libmpq/debian/libmpq-dev.install6
-rw-r--r--contrib/libmpq/debian/libmpq0.dirs1
-rw-r--r--contrib/libmpq/debian/libmpq0.docs6
-rw-r--r--contrib/libmpq/debian/libmpq0.install1
-rw-r--r--contrib/libmpq/debian/python-mpq.install1
-rw-r--r--contrib/libmpq/debian/rules112
-rw-r--r--contrib/libmpq/doc/Makefile.am5
-rw-r--r--contrib/libmpq/doc/man1/Makefile.am9
-rw-r--r--contrib/libmpq/doc/man1/libmpq-config.169
-rw-r--r--contrib/libmpq/doc/man3/Makefile.am30
-rw-r--r--contrib/libmpq/doc/man3/libmpq.3204
-rw-r--r--contrib/libmpq/doc/man3/libmpq__archive_close.357
-rw-r--r--contrib/libmpq/doc/man3/libmpq__archive_files.350
-rw-r--r--contrib/libmpq/doc/man3/libmpq__archive_offset.351
-rw-r--r--contrib/libmpq/doc/man3/libmpq__archive_open.371
-rw-r--r--contrib/libmpq/doc/man3/libmpq__archive_packed_size.351
-rw-r--r--contrib/libmpq/doc/man3/libmpq__archive_unpacked_size.351
-rw-r--r--contrib/libmpq/doc/man3/libmpq__archive_version.348
-rw-r--r--contrib/libmpq/doc/man3/libmpq__block_close_offset.353
-rw-r--r--contrib/libmpq/doc/man3/libmpq__block_open_offset.365
-rw-r--r--contrib/libmpq/doc/man3/libmpq__block_read.378
-rw-r--r--contrib/libmpq/doc/man3/libmpq__block_unpacked_size.359
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_blocks.354
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_compressed.354
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_encrypted.354
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_imploded.354
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_number.352
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_offset.355
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_packed_size.355
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_read.377
-rw-r--r--contrib/libmpq/doc/man3/libmpq__file_unpacked_size.355
-rw-r--r--contrib/libmpq/doc/man3/libmpq__version.345
-rw-r--r--contrib/libmpq/libmpq-config.in57
-rw-r--r--contrib/libmpq/libmpq.pc.in10
-rw-r--r--contrib/libmpq/libmpq/Makefile.am23
-rw-r--r--contrib/libmpq/libmpq/common.c222
-rw-r--r--contrib/libmpq/libmpq/common.h60
-rw-r--r--contrib/libmpq/libmpq/crypt_buf.h217
-rw-r--r--contrib/libmpq/libmpq/explode.c602
-rw-r--r--contrib/libmpq/libmpq/explode.h94
-rw-r--r--contrib/libmpq/libmpq/extract.c361
-rw-r--r--contrib/libmpq/libmpq/extract.h106
-rw-r--r--contrib/libmpq/libmpq/huffman.c1101
-rw-r--r--contrib/libmpq/libmpq/huffman.h151
-rw-r--r--contrib/libmpq/libmpq/mpq-internal.h155
-rw-r--r--contrib/libmpq/libmpq/mpq.c1033
-rw-r--r--contrib/libmpq/libmpq/mpq.h98
-rw-r--r--contrib/libmpq/libmpq/wave.c250
-rw-r--r--contrib/libmpq/libmpq/wave.h45
-rw-r--r--contrib/libmpq/tools/Makefile.am8
-rw-r--r--contrib/libmpq/tools/crypt_buf_gen.c85
-rw-r--r--contrib/libmpq/win/VS100/libmpq.vcxproj115
-rw-r--r--contrib/libmpq/win/config.h81
-rw-r--r--contrib/libmpq/win/libmpq_VC100.sln31
-rw-r--r--contrib/libmpq/win/libmpq_VC90.sln35
-rw-r--r--contrib/libmpq/win/stdint.h247
-rw-r--r--contrib/vmap_assembler/CMakeLists.txt85
-rw-r--r--contrib/vmap_assembler/VC100/vmap_assembler.vcxproj214
-rw-r--r--contrib/vmap_assembler/VC71/vmap_assembler.vcproj8
-rw-r--r--contrib/vmap_assembler/VC80/vmap_assembler.vcproj198
-rw-r--r--contrib/vmap_assembler/VC90/vmap_assembler.vcproj249
-rw-r--r--contrib/vmap_assembler/vmap_assembler.cpp11
-rw-r--r--contrib/vmap_assembler/vmap_assemblerVC100.sln59
-rw-r--r--contrib/vmap_assembler/vmap_assemblerVC90.sln42
-rw-r--r--contrib/vmap_extractor_v2/CMakeLists.txt26
-rw-r--r--contrib/vmap_extractor_v2/stormdll/StormDll.cpp117
-rw-r--r--contrib/vmap_extractor_v2/stormdll/StormDll.def25
-rw-r--r--contrib/vmap_extractor_v2/stormdll/StormDll.h67
-rw-r--r--contrib/vmap_extractor_v2/stormlib/GfxDecode.cpp697
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SCommon.cpp1074
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SCommon.h88
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SCompression.cpp715
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SFileCompactArchive.cpp691
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SFileCreateArchiveEx.cpp530
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SFileExtractFile.cpp63
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SFileFindFile.cpp291
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SFileOpenArchive.cpp497
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SFileOpenFileEx.cpp403
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SFileReadFile.cpp826
-rw-r--r--contrib/vmap_extractor_v2/stormlib/SListFile.cpp561
-rw-r--r--contrib/vmap_extractor_v2/stormlib/StormDll.h67
-rw-r--r--contrib/vmap_extractor_v2/stormlib/StormLib.h579
-rw-r--r--contrib/vmap_extractor_v2/stormlib/StormPort.h278
-rw-r--r--contrib/vmap_extractor_v2/stormlib/StormPortLinux.cpp168
-rw-r--r--contrib/vmap_extractor_v2/stormlib/StormPortMac.cpp762
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/CHANGES275
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/LICENSE40
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/Makefile-libbz2_so44
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/README185
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/README.COMPILATION.PROBLEMS39
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/README.XML.STUFF31
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/Y2K_INFO34
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bz-common.xsl39
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bz-fo.xsl257
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bz-html.xsl20
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff76
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff.147
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep71
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep.156
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzip.css74
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1454
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1.preformatted399
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.c2107
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.txt391
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzip2recover.c546
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzmore61
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/bzmore.1152
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.c176
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.dsp93
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/entities.xml9
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/format.pl53
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.def27
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.dsp130
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/makefile.msc63
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/manual.html2687
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/manual.pdfbin207093 -> 0 bytes
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/manual.ps68244
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/manual.xml2966
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/mk251.c16
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/sample1.bz2bin32348 -> 0 bytes
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/sample1.refbin98696 -> 0 bytes
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/sample2.bz2bin73732 -> 0 bytes
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/sample2.refbin212340 -> 0 bytes
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/sample3.bz2bin235 -> 0 bytes
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/sample3.ref30007
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/spewG.c39
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/unzcrash.c126
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/words05
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/words14
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/words25
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/words323
-rw-r--r--contrib/vmap_extractor_v2/stormlib/bzip2/xmlproc.sh99
-rw-r--r--contrib/vmap_extractor_v2/stormlib/huffman/huff.cpp1453
-rw-r--r--contrib/vmap_extractor_v2/stormlib/huffman/huff.h142
-rw-r--r--contrib/vmap_extractor_v2/stormlib/pklib/crc32.c72
-rw-r--r--contrib/vmap_extractor_v2/stormlib/pklib/crc32_pk.c72
-rw-r--r--contrib/vmap_extractor_v2/stormlib/pklib/explode.c480
-rw-r--r--contrib/vmap_extractor_v2/stormlib/pklib/implode.c674
-rw-r--r--contrib/vmap_extractor_v2/stormlib/pklib/pklib.h137
-rw-r--r--contrib/vmap_extractor_v2/stormlib/wave/wave.cpp356
-rw-r--r--contrib/vmap_extractor_v2/stormlib/wave/wave.h22
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/ChangeLog481
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/FAQ100
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/INDEX86
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/Makefile.riscos151
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/README147
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/adler32.c48
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/algorithm.txt213
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.pup66
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.sas64
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/compress.c68
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/README.contrib34
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32.asm559
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32c.c200
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/mkgvmt32.bat1
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.def74
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsp651
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsw41
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/README.58643
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/match.S354
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/README.68634
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/match.S327
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlib.mak36
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlibdef.pas169
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.bpr224
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.cpp17
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/readme.txt17
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpg26
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpr225
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.cpp22
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.pas534
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.bpr174
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.cpp42
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/test.cpp24
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.cpp329
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.h142
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream.h307
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream_test.cpp25
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/ChangeLogUnzip38
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/miniunz.c508
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/minizip.c302
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/readme.txt37
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.c1294
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.def15
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.h275
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.c718
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.def5
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.h150
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.def74
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsp651
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsw41
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/makefile.w3263
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/untgz.c522
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/contrib/visual-basic.txt69
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/crc32.c162
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/deflate.c1350
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/deflate.h318
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/descrip.mms48
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/example.c556
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/gzio.c875
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/infblock.c403
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/infblock.h39
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/infcodes.c251
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/infcodes.h27
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/inffast.c183
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/inffast.h17
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/inffixed.h151
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/inflate.c366
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/inftrees.c454
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/inftrees.h58
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/infutil.c87
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/infutil.h98
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/maketree.c85
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/minigzip.c320
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.b32104
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.bor125
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.dj2100
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.emx69
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.msc121
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.tc108
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.w3297
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.wat103
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.def60
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.rc32
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.emx138
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.gcc87
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.nt88
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/nt/zlib.dnt47
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/os2/Makefile.os2136
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/os2/zlib.def51
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/trees.c1214
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/trees.h128
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/uncompr.c58
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/zconf.h279
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/zlib.3107
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/zlib.h893
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/zlib.html971
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/zmemory.c19
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/zutil.c87
-rw-r--r--contrib/vmap_extractor_v2/stormlib/zlib/zutil.h220
-rw-r--r--contrib/vmap_extractor_v2/stormlibdll/DllMain.c24
-rw-r--r--contrib/vmap_extractor_v2/stormlibdll/StormLib.def47
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/CMakeLists.txt16
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/adtfile.cpp67
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/adtfile.h10
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/dbcfile.cpp8
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/dbcfile.h6
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/loadlib/loadlib.h59
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/model.cpp77
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/model.h8
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/modelheaders.h4
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/mpq.cpp143
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/mpq.h80
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/mpq_libmpq.cpp111
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/mpq_libmpq04.h91
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/vec3d.h6
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp413
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/vmapexport.h11
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp11
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/wdtfile.h9
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/wmo.cpp367
-rw-r--r--contrib/vmap_extractor_v2/vmapextract/wmo.h94
-rw-r--r--contrib/vmap_extractor_v2/win/VC100/vmapExtractor3.vcxproj106
-rw-r--r--contrib/vmap_extractor_v2/win/vmapExtractor3_VC100.sln19
-rw-r--r--contrib/vmap_extractor_v2/win/vmapExtractor3_VC90.sln19
-rw-r--r--dep/include/bzip2/bzlib.h (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.h)69
-rw-r--r--dep/include/g3dlite/G3D/AABox.h174
-rw-r--r--dep/include/g3dlite/G3D/Any.h570
-rw-r--r--dep/include/g3dlite/G3D/AnyVal.h512
-rw-r--r--dep/include/g3dlite/G3D/AreaMemoryManager.h93
-rw-r--r--dep/include/g3dlite/G3D/Array.h395
-rw-r--r--dep/include/g3dlite/G3D/AtomicInt32.h164
-rw-r--r--dep/include/g3dlite/G3D/BinaryFormat.h140
-rw-r--r--dep/include/g3dlite/G3D/BinaryInput.h441
-rw-r--r--dep/include/g3dlite/G3D/BinaryOutput.h421
-rw-r--r--dep/include/g3dlite/G3D/BoundsTrait.h20
-rw-r--r--dep/include/g3dlite/G3D/Box.h104
-rw-r--r--dep/include/g3dlite/G3D/Box2D.h121
-rw-r--r--dep/include/g3dlite/G3D/BumpMapPreprocess.h61
-rw-r--r--dep/include/g3dlite/G3D/Capsule.h90
-rw-r--r--dep/include/g3dlite/G3D/CollisionDetection.h1507
-rw-r--r--dep/include/g3dlite/G3D/Color1.h144
-rw-r--r--dep/include/g3dlite/G3D/Color1uint8.h91
-rw-r--r--dep/include/g3dlite/G3D/Color3.h432
-rw-r--r--dep/include/g3dlite/G3D/Color3uint8.h110
-rw-r--r--dep/include/g3dlite/G3D/Color4.h338
-rw-r--r--dep/include/g3dlite/G3D/Color4uint8.h115
-rw-r--r--dep/include/g3dlite/G3D/Cone.h68
-rw-r--r--dep/include/g3dlite/G3D/ConvexPolyhedron.h180
-rw-r--r--dep/include/g3dlite/G3D/CoordinateFrame.h146
-rw-r--r--dep/include/g3dlite/G3D/Crypto.h58
-rw-r--r--dep/include/g3dlite/G3D/Cylinder.h92
-rw-r--r--dep/include/g3dlite/G3D/EqualsTrait.h26
-rw-r--r--dep/include/g3dlite/G3D/G3D.h162
-rw-r--r--dep/include/g3dlite/G3D/G3DAll.h26
-rw-r--r--dep/include/g3dlite/G3D/G3DGameUnits.h42
-rw-r--r--dep/include/g3dlite/G3D/GCamera.h319
-rw-r--r--dep/include/g3dlite/G3D/GImage.h607
-rw-r--r--dep/include/g3dlite/G3D/GLight.h106
-rw-r--r--dep/include/g3dlite/G3D/GMutex.h123
-rw-r--r--dep/include/g3dlite/G3D/GThread.h121
-rw-r--r--dep/include/g3dlite/G3D/GUniqueID.h69
-rw-r--r--dep/include/g3dlite/G3D/HashTrait.h92
-rw-r--r--dep/include/g3dlite/G3D/Image1.h81
-rw-r--r--dep/include/g3dlite/G3D/Image1uint8.h80
-rw-r--r--dep/include/g3dlite/G3D/Image3.h81
-rw-r--r--dep/include/g3dlite/G3D/Image3uint8.h85
-rw-r--r--dep/include/g3dlite/G3D/Image4.h86
-rw-r--r--dep/include/g3dlite/G3D/Image4uint8.h85
-rw-r--r--dep/include/g3dlite/G3D/ImageFormat.h419
-rw-r--r--dep/include/g3dlite/G3D/Intersect.h55
-rw-r--r--dep/include/g3dlite/G3D/KDTree.h (renamed from src/shared/vmap/AABSPTree.h)747
-rw-r--r--dep/include/g3dlite/G3D/Line.h30
-rw-r--r--dep/include/g3dlite/G3D/LineSegment.h115
-rw-r--r--dep/include/g3dlite/G3D/Log.h109
-rw-r--r--dep/include/g3dlite/G3D/Map2D.h667
-rw-r--r--dep/include/g3dlite/G3D/Matrix.h634
-rw-r--r--dep/include/g3dlite/G3D/Matrix2.h69
-rw-r--r--dep/include/g3dlite/G3D/Matrix3.h138
-rw-r--r--dep/include/g3dlite/G3D/Matrix4.h249
-rw-r--r--dep/include/g3dlite/G3D/MemoryManager.h93
-rw-r--r--dep/include/g3dlite/G3D/MeshAlg.h683
-rw-r--r--dep/include/g3dlite/G3D/MeshBuilder.h82
-rw-r--r--dep/include/g3dlite/G3D/NetAddress.h132
-rw-r--r--dep/include/g3dlite/G3D/NetworkDevice.h738
-rw-r--r--dep/include/g3dlite/G3D/ParseError.h59
-rw-r--r--dep/include/g3dlite/G3D/PhysicsFrame.h74
-rw-r--r--dep/include/g3dlite/G3D/Plane.h24
-rw-r--r--dep/include/g3dlite/G3D/PointHashGrid.h917
-rw-r--r--dep/include/g3dlite/G3D/PointKDTree.h1185
-rw-r--r--dep/include/g3dlite/G3D/Pointer.h292
-rw-r--r--dep/include/g3dlite/G3D/PositionTrait.h7
-rw-r--r--dep/include/g3dlite/G3D/PrecomputedRandom.h110
-rw-r--r--dep/include/g3dlite/G3D/Quat.h124
-rw-r--r--dep/include/g3dlite/G3D/Queue.h364
-rw-r--r--dep/include/g3dlite/G3D/Random.h139
-rw-r--r--dep/include/g3dlite/G3D/Ray.h172
-rw-r--r--dep/include/g3dlite/G3D/Rect2D.h417
-rw-r--r--dep/include/g3dlite/G3D/ReferenceCount.h570
-rw-r--r--dep/include/g3dlite/G3D/RegistryUtil.h48
-rw-r--r--dep/include/g3dlite/G3D/Set.h186
-rw-r--r--dep/include/g3dlite/G3D/SmallArray.h155
-rw-r--r--dep/include/g3dlite/G3D/Sphere.h97
-rw-r--r--dep/include/g3dlite/G3D/Spline.h367
-rw-r--r--dep/include/g3dlite/G3D/Stopwatch.h144
-rw-r--r--dep/include/g3dlite/G3D/System.h474
-rw-r--r--dep/include/g3dlite/G3D/Table.h789
-rw-r--r--dep/include/g3dlite/G3D/TextInput.h801
-rw-r--r--dep/include/g3dlite/G3D/TextOutput.h249
-rw-r--r--dep/include/g3dlite/G3D/ThreadSet.h87
-rw-r--r--dep/include/g3dlite/G3D/Triangle.h79
-rw-r--r--dep/include/g3dlite/G3D/UprightFrame.h83
-rw-r--r--dep/include/g3dlite/G3D/Vector2.h206
-rw-r--r--dep/include/g3dlite/G3D/Vector2int16.h82
-rw-r--r--dep/include/g3dlite/G3D/Vector3.h541
-rw-r--r--dep/include/g3dlite/G3D/Vector3int16.h101
-rw-r--r--dep/include/g3dlite/G3D/Vector3int32.h128
-rw-r--r--dep/include/g3dlite/G3D/Vector4.h231
-rw-r--r--dep/include/g3dlite/G3D/Vector4int8.h113
-rw-r--r--dep/include/g3dlite/G3D/WeakCache.h122
-rw-r--r--dep/include/g3dlite/G3D/Welder.h82
-rw-r--r--dep/include/g3dlite/G3D/WrapMode.h93
-rw-r--r--dep/include/g3dlite/G3D/constants.h129
-rw-r--r--dep/include/g3dlite/G3D/debug.h66
-rw-r--r--dep/include/g3dlite/G3D/debugAssert.h233
-rw-r--r--dep/include/g3dlite/G3D/debugPrintf.h62
-rw-r--r--dep/include/g3dlite/G3D/enumclass.h147
-rw-r--r--dep/include/g3dlite/G3D/fileutils.h254
-rw-r--r--dep/include/g3dlite/G3D/filter.h29
-rw-r--r--dep/include/g3dlite/G3D/format.h25
-rw-r--r--dep/include/g3dlite/G3D/g3dfnmatch.h83
-rw-r--r--dep/include/g3dlite/G3D/g3dmath.h633
-rw-r--r--dep/include/g3dlite/G3D/platform.h344
-rw-r--r--dep/include/g3dlite/G3D/prompt.h67
-rw-r--r--dep/include/g3dlite/G3D/serialize.h30
-rw-r--r--dep/include/g3dlite/G3D/splinefunc.h118
-rw-r--r--dep/include/g3dlite/G3D/stringutils.h33
-rw-r--r--dep/include/g3dlite/G3D/uint128.h51
-rw-r--r--dep/include/g3dlite/G3D/units.h126
-rw-r--r--dep/include/g3dlite/G3D/vectorMath.h235
-rw-r--r--dep/src/bzip2/blocksort.c (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/blocksort.c)79
-rw-r--r--dep/src/bzip2/bzlib.c (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.c)105
-rw-r--r--dep/src/bzip2/bzlib.h282
-rw-r--r--dep/src/bzip2/bzlib_private.h (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/bzlib_private.h)98
-rw-r--r--dep/src/bzip2/compress.c (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/compress.c)105
-rw-r--r--dep/src/bzip2/crctable.c (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/crctable.c)60
-rw-r--r--dep/src/bzip2/decompress.c (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/decompress.c)66
-rw-r--r--dep/src/bzip2/huffman.c (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/huffman.c)66
-rw-r--r--dep/src/bzip2/randtable.c (renamed from contrib/vmap_extractor_v2/stormlib/bzip2/randtable.c)60
-rw-r--r--dep/src/g3dlite/AABox.cpp308
-rw-r--r--dep/src/g3dlite/Any.cpp1237
-rw-r--r--dep/src/g3dlite/AnyVal.cpp1379
-rw-r--r--dep/src/g3dlite/AreaMemoryManager.cpp87
-rw-r--r--dep/src/g3dlite/BinaryFormat.cpp81
-rw-r--r--dep/src/g3dlite/BinaryInput.cpp568
-rw-r--r--dep/src/g3dlite/BinaryOutput.cpp522
-rw-r--r--dep/src/g3dlite/Box.cpp213
-rw-r--r--dep/src/g3dlite/Box2D.cpp113
-rw-r--r--dep/src/g3dlite/BumpMapPreprocess.cpp43
-rw-r--r--dep/src/g3dlite/CMakeLists.txt49
-rw-r--r--dep/src/g3dlite/Capsule.cpp179
-rw-r--r--dep/src/g3dlite/CollisionDetection.cpp2455
-rw-r--r--dep/src/g3dlite/Color1.cpp58
-rw-r--r--dep/src/g3dlite/Color1uint8.cpp38
-rw-r--r--dep/src/g3dlite/Color3.cpp384
-rw-r--r--dep/src/g3dlite/Color3uint8.cpp45
-rw-r--r--dep/src/g3dlite/Color4.cpp192
-rw-r--r--dep/src/g3dlite/Color4uint8.cpp47
-rw-r--r--dep/src/g3dlite/Cone.cpp79
-rw-r--r--dep/src/g3dlite/ConvexPolyhedron.cpp457
-rw-r--r--dep/src/g3dlite/CoordinateFrame.cpp436
-rw-r--r--dep/src/g3dlite/Crypto.cpp144
-rw-r--r--dep/src/g3dlite/Crypto_md5.cpp471
-rw-r--r--dep/src/g3dlite/Cylinder.cpp176
-rw-r--r--dep/src/g3dlite/GCamera.cpp502
-rw-r--r--dep/src/g3dlite/GImage.cpp1166
-rw-r--r--dep/src/g3dlite/GImage_bayer.cpp298
-rw-r--r--dep/src/g3dlite/GImage_bmp.cpp717
-rw-r--r--dep/src/g3dlite/GImage_jpeg.cpp446
-rw-r--r--dep/src/g3dlite/GImage_png.cpp266
-rw-r--r--dep/src/g3dlite/GImage_ppm.cpp217
-rw-r--r--dep/src/g3dlite/GImage_tga.cpp193
-rw-r--r--dep/src/g3dlite/GLight.cpp267
-rw-r--r--dep/src/g3dlite/GThread.cpp229
-rw-r--r--dep/src/g3dlite/GUniqueID.cpp78
-rw-r--r--dep/src/g3dlite/Image1.cpp224
-rw-r--r--dep/src/g3dlite/Image1uint8.cpp212
-rw-r--r--dep/src/g3dlite/Image3.cpp225
-rw-r--r--dep/src/g3dlite/Image3uint8.cpp225
-rw-r--r--dep/src/g3dlite/Image4.cpp226
-rw-r--r--dep/src/g3dlite/Image4uint8.cpp222
-rw-r--r--dep/src/g3dlite/ImageFormat.cpp567
-rw-r--r--dep/src/g3dlite/ImageFormat_convert.cpp1307
-rw-r--r--dep/src/g3dlite/Intersect.cpp844
-rw-r--r--dep/src/g3dlite/Line.cpp89
-rw-r--r--dep/src/g3dlite/LineSegment.cpp236
-rw-r--r--dep/src/g3dlite/Log.cpp146
-rw-r--r--dep/src/g3dlite/Makefile.am69
-rw-r--r--dep/src/g3dlite/Matrix.cpp1802
-rw-r--r--dep/src/g3dlite/Matrix3.cpp353
-rw-r--r--dep/src/g3dlite/Matrix4.cpp523
-rw-r--r--dep/src/g3dlite/MemoryManager.cpp91
-rw-r--r--dep/src/g3dlite/MeshAlg.cpp637
-rw-r--r--dep/src/g3dlite/MeshAlgAdjacency.cpp739
-rw-r--r--dep/src/g3dlite/MeshAlgWeld.cpp213
-rw-r--r--dep/src/g3dlite/MeshBuilder.cpp113
-rw-r--r--dep/src/g3dlite/NetAddress.cpp164
-rw-r--r--dep/src/g3dlite/NetworkDevice.cpp1362
-rw-r--r--dep/src/g3dlite/PhysicsFrame.cpp77
-rw-r--r--dep/src/g3dlite/Plane.cpp42
-rw-r--r--dep/src/g3dlite/PrecomputedRandom.cpp125
-rw-r--r--dep/src/g3dlite/Quat.cpp583
-rw-r--r--dep/src/g3dlite/Random.cpp212
-rw-r--r--dep/src/g3dlite/Ray.cpp218
-rw-r--r--dep/src/g3dlite/Rect2D.cpp41
-rw-r--r--dep/src/g3dlite/ReferenceCount.cpp61
-rw-r--r--dep/src/g3dlite/RegistryUtil.cpp290
-rw-r--r--dep/src/g3dlite/Sphere.cpp223
-rw-r--r--dep/src/g3dlite/SplineBase.cpp162
-rw-r--r--dep/src/g3dlite/Stopwatch.cpp119
-rw-r--r--dep/src/g3dlite/System.cpp1329
-rw-r--r--dep/src/g3dlite/TextInput.cpp1136
-rw-r--r--dep/src/g3dlite/TextOutput.cpp452
-rw-r--r--dep/src/g3dlite/ThreadSet.cpp166
-rw-r--r--dep/src/g3dlite/Triangle.cpp110
-rw-r--r--dep/src/g3dlite/UprightFrame.cpp132
-rw-r--r--dep/src/g3dlite/Vector2.cpp224
-rw-r--r--dep/src/g3dlite/Vector2int16.cpp47
-rw-r--r--dep/src/g3dlite/Vector3.cpp238
-rw-r--r--dep/src/g3dlite/Vector3int16.cpp49
-rw-r--r--dep/src/g3dlite/Vector3int32.cpp57
-rw-r--r--dep/src/g3dlite/Vector4.cpp111
-rw-r--r--dep/src/g3dlite/Vector4int8.cpp58
-rw-r--r--dep/src/g3dlite/Welder.cpp416
-rw-r--r--dep/src/g3dlite/WinMain.cpp159
-rw-r--r--dep/src/g3dlite/constants.cpp82
-rw-r--r--dep/src/g3dlite/debugAssert.cpp389
-rw-r--r--dep/src/g3dlite/fileutils.cpp1165
-rw-r--r--dep/src/g3dlite/filter.cpp32
-rw-r--r--dep/src/g3dlite/format.cpp58
-rw-r--r--dep/src/g3dlite/g3dfnmatch.cpp204
-rw-r--r--dep/src/g3dlite/g3dmath.cpp108
-rw-r--r--dep/src/g3dlite/license.cpp73
-rw-r--r--dep/src/g3dlite/license.html172
-rw-r--r--dep/src/g3dlite/prompt.cpp729
-rw-r--r--dep/src/g3dlite/stringutils.cpp275
-rw-r--r--dep/src/g3dlite/uint128.cpp155
-rw-r--r--src/game/Creature.cpp2
-rw-r--r--src/game/DBCEnums.h4
-rw-r--r--src/game/DBCStores.cpp42
-rw-r--r--src/game/DBCStores.h3
-rw-r--r--src/game/DBCStructure.h17
-rw-r--r--src/game/DBCfmt.h1
-rw-r--r--src/game/Level1.cpp9
-rw-r--r--src/game/Map.cpp340
-rw-r--r--src/game/Map.h9
-rw-r--r--src/game/Player.cpp23
-rw-r--r--src/game/Player.h2
-rw-r--r--src/game/Spell.cpp13
-rw-r--r--src/game/SpellEffects.cpp15
-rw-r--r--src/game/Unit.cpp12
-rw-r--r--src/game/Unit.h1
-rw-r--r--src/game/World.cpp1
-rw-r--r--src/game/World.h1
-rw-r--r--src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp4
-rw-r--r--src/scripts/outland/black_temple/boss_teron_gorefiend.cpp2
-rw-r--r--src/shared/vmap/BIH.cpp304
-rw-r--r--src/shared/vmap/BIH.h391
-rw-r--r--src/shared/vmap/BaseModel.cpp98
-rw-r--r--src/shared/vmap/BaseModel.h102
-rw-r--r--src/shared/vmap/CMakeLists.txt32
-rw-r--r--src/shared/vmap/CoordModelMapping.cpp200
-rw-r--r--src/shared/vmap/CoordModelMapping.h143
-rw-r--r--src/shared/vmap/DebugCmdLogger.cpp131
-rw-r--r--src/shared/vmap/DebugCmdLogger.h119
-rw-r--r--src/shared/vmap/IVMapManager.h19
-rw-r--r--src/shared/vmap/ManagedModelContainer.cpp38
-rw-r--r--src/shared/vmap/ManagedModelContainer.h52
-rw-r--r--src/shared/vmap/MapTree.cpp450
-rw-r--r--src/shared/vmap/MapTree.h97
-rw-r--r--src/shared/vmap/ModelContainer.cpp378
-rw-r--r--src/shared/vmap/ModelContainer.h111
-rw-r--r--src/shared/vmap/ModelInstance.cpp219
-rw-r--r--src/shared/vmap/ModelInstance.h81
-rw-r--r--src/shared/vmap/NodeValueAccess.h51
-rw-r--r--src/shared/vmap/ShortBox.h151
-rw-r--r--src/shared/vmap/ShortVector.h137
-rw-r--r--src/shared/vmap/SubModel.cpp251
-rw-r--r--src/shared/vmap/SubModel.h105
-rw-r--r--src/shared/vmap/TileAssembler.cpp770
-rw-r--r--src/shared/vmap/TileAssembler.h57
-rw-r--r--src/shared/vmap/TreeNode.cpp40
-rw-r--r--src/shared/vmap/TreeNode.h226
-rw-r--r--src/shared/vmap/VMapDefinitions.h20
-rw-r--r--src/shared/vmap/VMapFactory.cpp45
-rw-r--r--src/shared/vmap/VMapFactory.h9
-rw-r--r--src/shared/vmap/VMapManager.cpp776
-rw-r--r--src/shared/vmap/VMapManager.h176
-rw-r--r--src/shared/vmap/VMapManager2.cpp336
-rw-r--r--src/shared/vmap/VMapManager2.h114
-rw-r--r--src/shared/vmap/VMapTools.h11
-rw-r--r--src/shared/vmap/WorldModel.cpp535
-rw-r--r--src/shared/vmap/WorldModel.h123
-rw-r--r--src/trinitycore/trinitycore.conf.dist7
566 files changed, 71594 insertions, 153104 deletions
diff --git a/contrib/libmpq/AUTHORS b/contrib/libmpq/AUTHORS
new file mode 100644
index 00000000000..3d7da7bec9a
--- /dev/null
+++ b/contrib/libmpq/AUTHORS
@@ -0,0 +1,10 @@
+Project Initiator:
+
+ * Maik Broemme <mbroemme@plusserver.de>
+
+Developers:
+
+ * Maik Broemme <mbroemme@plusserver.de>
+ * Tilman Sauerbeck <tilman@code-monkey.de>
+ * Forrest Voight <voights@gmail.com>
+ * Georg Lukas <georg@op-co.de>
diff --git a/contrib/libmpq/COPYING b/contrib/libmpq/COPYING
new file mode 100644
index 00000000000..4189933be9f
--- /dev/null
+++ b/contrib/libmpq/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111 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
+
+ Appendix: 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 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/contrib/libmpq/FAQ b/contrib/libmpq/FAQ
new file mode 100644
index 00000000000..52ca9f3c705
--- /dev/null
+++ b/contrib/libmpq/FAQ
@@ -0,0 +1,68 @@
+FAQ - Frequently Asked Questions
+================================
+
+Q: What is libmpq?
+A: libmpq is a library for manipulating MoPaQ mpq archives mostly used
+ used by Blizzard in their games.
+
+Q: What can i do with libmpq?
+A: With libmpq you can write applications which can extract, create
+ and manipulate mpq archives.
+
+Q: Is it legal?
+A: Yes, i think so. I have no idea why it should not, all informations
+ about the fileformat are available.
+
+Q: Is there a description of the functions?
+A: Since version 0.4.0 libmpq comes with a API documentation for
+ developers. The documentation is written as manual pages.
+
+Q: Can i help?
+A: Yes, help is needed, not only with developing, also with testing.
+ A good point to start is using a recent SVN version of libmpq and
+ trying to use it with every mpq archive you could get :)
+
+Q: Can you give a small example to demonstrate the usage?
+A: Of course :) The example below takes first parameter as mpq archive
+ and extracts the first file to a buffer.
+
+ /*
+ * Compile with:
+ *
+ * x86_32:
+ *
+ * gcc \
+ * -D_FILE_OFFSET_BITS=64 \
+ * -D_LARGE_FILES=1 \
+ * -D_LARGEFILE_SOURCE=1 \
+ * mpq-example.c -o mpq-example -lmpq -lz -lbz2 -I/usr/local/include/libmpq
+ *
+ * x86_64:
+ *
+ * gcc \
+ * -D_LARGE_FILES=1 \
+ * mpq-example.c -o mpq-example -lmpq -lz -lbz2 -I/usr/local/include/libmpq
+ */
+
+ #include <mpq.h>
+ #include <stdlib.h>
+ #include <limits.h>
+
+ int main(int argc, char **argv) {
+ mpq_archive_s *mpq_archive;
+ off_t out_size;
+ char *out_buf;
+
+ /* open the mpq archive given as first parameter. */
+ libmpq__archive_open(&mpq_archive, argv[1], -1);
+
+ /* get size of first file (0) and malloc output buffer. */
+ libmpq__file_unpacked_size(mpq_archive, 0, &out_size);
+ out_buf = malloc(out_size);
+
+ /* read, decrypt and unpack file to output buffer. */
+ libmpq__file_read(mpq_archive, 0, out_buf, out_size, NULL);
+
+ /* close the mpq archive. */
+ libmpq__archive_close(mpq_archive);
+ }
diff --git a/contrib/libmpq/Makefile.am b/contrib/libmpq/Makefile.am
new file mode 100644
index 00000000000..0a9b54c2526
--- /dev/null
+++ b/contrib/libmpq/Makefile.am
@@ -0,0 +1,26 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# any directories which should be built and installed.
+SUBDIRS = libmpq bindings doc
+
+# the directories which are part of the distribution.
+DIST_SUBDIRS = $(SUBDIRS)
+
+# libmpq runtime configuration script.
+bin_SCRIPTS = libmpq-config
+
+# pkg-config installation directory.
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libmpq.pc
+
+# extra stuff.
+EXTRA_DIST = \
+ AUTHORS \
+ COPYING \
+ FAQ \
+ INSTALL \
+ NEWS \
+ README \
+ THANKS \
+ TODO
diff --git a/contrib/libmpq/NEWS b/contrib/libmpq/NEWS
new file mode 100644
index 00000000000..74850a8a5bb
--- /dev/null
+++ b/contrib/libmpq/NEWS
@@ -0,0 +1,76 @@
+Changes version 0.4.2 (2008-05-16)
+==================================
+
+ * added full extraction support for protected maps used in
+ warcraft 3.
+
+ * added full extraction support for all blizzard titles until
+ world of warcraft - the burning crusade.
+
+ * added support for archives version 2 with extended header and
+ extended block table.
+
+ * added support for the bzip2 compression algorithm.
+
+ * added support for archives and files inside archive > 2gb.
+
+ * added generic read functions, which will do decryption,
+ decompression or exploding.
+
+ * the info functions are no longer exported by the library and
+ were replaced by separate api functions.
+
+ * the file number and block number are count from 0 instead
+ of 1.
+
+ * added python bindings.
+
+ * linking against libmpq requires from now on the usual largefile
+ macros -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES=1 -D_LARGEFILE_SOURCE=1
+
+Changes version 0.4.1 (2008-04-02)
+==================================
+
+ * memory, speed and stability improvements.
+
+ * split sourcecode into library and utility package.
+
+Changes version 0.4.0 (2008-03-31)
+==================================
+
+ * added robust error handling to make the library and extracting
+ utility more stable.
+
+ * added c++ bindings to public include and moved internal defines
+ and functions to private include.
+
+ * added support for 64-bit architectures and removed any stupid
+ pointer to int arithmetics.
+
+ * added much better member names to the structures to make
+ developers able to understand the code on reading.
+
+ * added full api documentation using manual pages.
+
+ * added full extraction support for all blizzard titles until
+ warcraft 3 - the frozen throne.
+
+ * added support for single sector and stored files (neither
+ compressed nor imploded).
+
+ * added support for files which have compressed size greater than
+ uncompressed size.
+
+ * removed the external listfile database support from 0.3.0 it
+ was a weird implementation.
+
+Changes version 0.3.0 (2004-02-12)
+==================================
+
+ * added listfile database support from external files.
+
+Initial version 0.2.1 (2004-01-17)
+==================================
+
+ * first version which was able to extract some of the older mopaq
+ archives.
diff --git a/contrib/libmpq/README b/contrib/libmpq/README
new file mode 100644
index 00000000000..3f1bd3a1e9f
--- /dev/null
+++ b/contrib/libmpq/README
@@ -0,0 +1,34 @@
+Introduction
+============
+
+'libmpq' is a library which can be easily used in own applications
+to extract, create or manipulate MoPaQ mpq archives.
+
+MPQ, or MoPaQ, is a proprietary archive format created by
+Mike O'Brien, the man hailed as Blizzard's multiplayer engine
+genius, back in 1996 as a general purpose archive for use with
+Diablo, and named narcissistically for its creator
+"Mike O'brien PaCK". The copyrights to it, however, are held by
+Havas Interactive, Blizzard's parent company. The archive format
+is used by many Blizzard titles like Diablo, Diablo 2, Starcraft,
+Warcraft 2: BNE, a newer version in Warcraft 3 and World of
+Warcraft (WoW).
+
+Manual
+======
+
+Since version 0.4.0 the 'libmpq' package comes with a manpage for
+every library function. If you use 'libmpq' first time it is a good
+idea to read the `FAQ' file.
+
+Reporting Bugs
+==============
+
+Bug reports for 'libmpq' can be send to me directly.
+
+ * Maik Broemme <mbroemme@plusserver.de>
+
+Enjoy!
+
+Maik Broemme <mbroemme@plusserver.de>
+http://www.babelize.org/
diff --git a/contrib/libmpq/THANKS b/contrib/libmpq/THANKS
new file mode 100644
index 00000000000..42da1235476
--- /dev/null
+++ b/contrib/libmpq/THANKS
@@ -0,0 +1,21 @@
+'libmpq' was originaly created by Maik Broemme <mbroemme@plusserver.de>
+and i want to thank some people which helped by supplying knowledge, code or
+something else.
+
+ * Romy Trompke <rtnet@web.de>
+ - my lovely girlfriend for her patience
+
+ * Ladislav Zezula <ladik@zezula.net>
+ - stormlib creator
+
+ * Marko Friedemann <marko.friedemann@bmx-chemnitz.de>
+ - initial port of stormlib to linux
+
+ * Tom Amigo <tomamigo@apexmail.com>
+ - first people who decrypts the MoPaQ archive format
+
+ * ShadowFlare <BlakFlare@hiotmail.com>
+ - creator of the ShadowFlare MPQ API
+
+ * Justin Olbrantz (Quantam) <omega@dragonfire.net>
+ - creator of the client using ShadowFlare MPQ API
diff --git a/contrib/libmpq/TODO b/contrib/libmpq/TODO
new file mode 100644
index 00000000000..0c1951f0b46
--- /dev/null
+++ b/contrib/libmpq/TODO
@@ -0,0 +1,10 @@
+Features and functionality which should be added in the future.
+
+ * Porting for big endian systems.
+ * Porting for Windows? :)
+ * Creating mpq archives.
+ * Brute all unknown filenames, Blizzard uses in their
+ archives.
+
+Look at the AUTHORS file if you want help me with 'libmpq', or
+if you have other interesting features which should be added.
diff --git a/contrib/libmpq/autogen.sh b/contrib/libmpq/autogen.sh
new file mode 100644
index 00000000000..16871edd70d
--- /dev/null
+++ b/contrib/libmpq/autogen.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+echo "Generating build information using aclocal, autoheader, automake and autoconf"
+echo "This may take a while ..."
+
+# Touch the timestamps on all the files since CVS messes them up
+directory=`dirname $0`
+touch $directory/configure.ac
+
+# Regenerate configuration files
+libtoolize --copy
+aclocal
+autoheader
+automake --foreign --add-missing --copy
+autoconf
+
+# Run configure for this platform
+#./configure $*
+echo "Now you are ready to run ./configure"
diff --git a/contrib/libmpq/bindings/Makefile.am b/contrib/libmpq/bindings/Makefile.am
new file mode 100644
index 00000000000..b9fefe306ef
--- /dev/null
+++ b/contrib/libmpq/bindings/Makefile.am
@@ -0,0 +1,6 @@
+# any directories which should be built and installed.
+SUBDIRS = d
+
+if HAVE_PYTHON
+SUBDIRS += python
+endif
diff --git a/contrib/libmpq/bindings/d/Makefile.am b/contrib/libmpq/bindings/d/Makefile.am
new file mode 100644
index 00000000000..4de7285ae51
--- /dev/null
+++ b/contrib/libmpq/bindings/d/Makefile.am
@@ -0,0 +1,6 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# install D binding to /usr/include/d by default
+libmpq_includedir = $(includedir)/d
+libmpq_include_HEADERS = mpq.d
diff --git a/contrib/libmpq/bindings/d/dsss.conf b/contrib/libmpq/bindings/d/dsss.conf
new file mode 100644
index 00000000000..252482c4933
--- /dev/null
+++ b/contrib/libmpq/bindings/d/dsss.conf
@@ -0,0 +1,2 @@
+[mpq.d]
+type=sourcelibrary
diff --git a/contrib/libmpq/bindings/d/mpq.d b/contrib/libmpq/bindings/d/mpq.d
new file mode 100644
index 00000000000..aa35d136990
--- /dev/null
+++ b/contrib/libmpq/bindings/d/mpq.d
@@ -0,0 +1,318 @@
+/*
+ * mpq.d -- D programming language module for libmpq
+ *
+ * Copyright (c) 2008 Georg Lukas <georg@op-co.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 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 module is written to support Phobos. Patches to allow binding to
+ * Tango are welcome.
+ */
+
+module mpq;
+
+/* the following pragma does not work on DMD/Linux, generates a warning on
+ * GDC/Linux and has not been tested on Windows. Commented out for now. */
+// pragma(lib, "libmpq");
+
+import std.string; // for format() and toStringz()
+import std.traits; // for ParameterTypeTuple!()
+
+/* XXX: this assumes that libmpq is compiled with Large File Support on */
+alias long off_t;
+
+/* libmpq error return values */
+const LIBMPQ_ERROR_OPEN = -1; /* open error on file. */
+const LIBMPQ_ERROR_CLOSE = -2; /* close error on file. */
+const LIBMPQ_ERROR_SEEK = -3; /* lseek error on file. */
+const LIBMPQ_ERROR_READ = -4; /* read error on file. */
+const LIBMPQ_ERROR_WRITE = -5; /* write error on file. */
+const LIBMPQ_ERROR_MALLOC = -6; /* memory allocation error. */
+const LIBMPQ_ERROR_FORMAT = -7; /* format errror. */
+const LIBMPQ_ERROR_NOT_INITIALIZED = -8; /* init() wasn't called. */
+const LIBMPQ_ERROR_SIZE = -9; /* buffer size is to small. */
+const LIBMPQ_ERROR_EXIST = -10; /* file or block does not exist in archive. */
+const LIBMPQ_ERROR_DECRYPT = -11; /* we don't know the decryption seed. */
+const LIBMPQ_ERROR_UNPACK = -12; /* error on unpacking file. */
+
+/** libmpq internal meta-data for an archive */
+struct mpq_archive_s;
+
+extern(C) {
+
+/* libmpq__generic information about library. */
+char *libmpq__version();
+
+/* libmpq__generic mpq archive information. */
+int libmpq__archive_open(mpq_archive_s **mpq_archive, char *mpq_filename, off_t archive_offset);
+int libmpq__archive_close(mpq_archive_s *mpq_archive);
+int libmpq__archive_packed_size(mpq_archive_s *mpq_archive, off_t *packed_size);
+int libmpq__archive_unpacked_size(mpq_archive_s *mpq_archive, off_t *unpacked_size);
+int libmpq__archive_offset(mpq_archive_s *mpq_archive, off_t *offset);
+int libmpq__archive_version(mpq_archive_s *mpq_archive, uint *version_);
+int libmpq__archive_files(mpq_archive_s *mpq_archive, uint *files);
+
+/* libmpq__generic file processing functions. */
+int libmpq__file_packed_size(mpq_archive_s *mpq_archive, uint file_number, off_t *packed_size);
+int libmpq__file_unpacked_size(mpq_archive_s *mpq_archive, uint file_number, off_t *unpacked_size);
+int libmpq__file_offset(mpq_archive_s *mpq_archive, uint file_number, off_t *offset);
+int libmpq__file_blocks(mpq_archive_s *mpq_archive, uint file_number, uint *blocks);
+int libmpq__file_encrypted(mpq_archive_s *mpq_archive, uint file_number, uint *encrypted);
+int libmpq__file_compressed(mpq_archive_s *mpq_archive, uint file_number, uint *compressed);
+int libmpq__file_imploded(mpq_archive_s *mpq_archive, uint file_number, uint *imploded);
+int libmpq__file_number(mpq_archive_s *mpq_archive, char *filename, uint *number);
+int libmpq__file_read(mpq_archive_s *mpq_archive, uint file_number, ubyte *out_buf, off_t out_size, off_t *transferred);
+
+/* libmpq__generic block processing functions. */
+int libmpq__block_open_offset(mpq_archive_s *mpq_archive, uint file_number);
+int libmpq__block_close_offset(mpq_archive_s *mpq_archive, uint file_number);
+int libmpq__block_unpacked_size(mpq_archive_s *mpq_archive, uint file_number, uint block_number, off_t *unpacked_size);
+int libmpq__block_read(mpq_archive_s *mpq_archive, uint file_number, uint block_number, ubyte *out_buf, off_t out_size, off_t *transferred);
+
+}
+
+
+/** exception class for failed libmpq calls */
+class MPQException : Exception {
+ const string[] Errors = [
+ "unknown error",
+ "open error on file",
+ "close error on file",
+ "lseek error on file",
+ "read error on file",
+ "write error on file",
+ "memory allocation error",
+ "format errror",
+ "init() wasn't called",
+ "buffer size is to small",
+ "file or block does not exist in archive",
+ "we don't know the decryption seed",
+ "error on unpacking file"];
+
+ public int errno;
+ this(char[] fnname = "unknown_function", int errno = 0) {
+
+ this.errno = errno;
+ if (-errno >= Errors.length)
+ errno = 0;
+ super(std.string.format("Error in %s(): %s (%d)",
+ fnname, Errors[-errno], errno));
+ }
+}
+
+
+/** template to wrap function calls and throw exceptions in case of error
+ *
+ * thanks for the idea to while(nan) blog,
+ * http://while-nan.blogspot.com/2007/06/wrapping-functions-for-fun-and-profit.html
+ *
+ * use: MPQ_CHECKERR(libmpq__archive_open)(&m, "foo.mpq", -1);
+ * returns the retval of archive_open on success;
+ * throws an MPQException on failure.
+ *
+ * @param Fn libmpq__function reference
+ * @param args libmpq__function parameters
+ * @return return value of libmpq__function on success
+ * @throw MPQException on error
+ */
+int MPQ_CHECKERR(alias Fn)(ParameterTypeTuple!(Fn) args)
+{
+ int result = Fn(args);
+ if (result < 0) {
+ /* XXX: relying on non-specified stringof() behaviour */
+ throw new MPQException((&Fn).stringof[2..$], result);
+ }
+ return result;
+}
+
+
+/** mixin alias to wrap library functions into MPQ_CHECKERR.
+ *
+ * alias mpq.func_name(...) to MPQ_CHECKERR(libmpq__func_name)(...)
+ * @param func_name name of the function to be wrapped
+ */
+template MPQ_FUNC(char[] func_name) {
+ const char[] MPQ_FUNC = "alias MPQ_CHECKERR!(libmpq__" ~ func_name ~ ") " ~ func_name ~ ";";
+}
+
+alias libmpq__version libversion; /* must be direct alias because it returns char*, not error int */
+mixin(MPQ_FUNC!("archive_open"));
+mixin(MPQ_FUNC!("archive_close"));
+mixin(MPQ_FUNC!("archive_packed_size"));
+mixin(MPQ_FUNC!("archive_unpacked_size"));
+mixin(MPQ_FUNC!("archive_offset"));
+mixin(MPQ_FUNC!("archive_version"));
+mixin(MPQ_FUNC!("archive_files"));
+mixin(MPQ_FUNC!("file_packed_size"));
+mixin(MPQ_FUNC!("file_unpacked_size"));
+mixin(MPQ_FUNC!("file_offset"));
+mixin(MPQ_FUNC!("file_blocks"));
+mixin(MPQ_FUNC!("file_encrypted"));
+mixin(MPQ_FUNC!("file_compressed"));
+mixin(MPQ_FUNC!("file_imploded"));
+mixin(MPQ_FUNC!("file_number"));
+mixin(MPQ_FUNC!("file_read"));
+mixin(MPQ_FUNC!("block_open_offset"));
+mixin(MPQ_FUNC!("block_close_offset"));
+mixin(MPQ_FUNC!("block_unpacked_size"));
+mixin(MPQ_FUNC!("block_read"));
+
+/** getter function named name for returning archive_* single values:
+ *
+ * <type> Archive.<name>() { return libmpq__archive_<name>() }
+ *
+ * @param type return type for the original function reference
+ * @param name name of the original function
+ * @param name2 name for the prototype (defaults to name, used for "version")
+ * @return getter function mixin
+ */
+template MPQ_A_GET(char[] type, char[] name, char[] name2 = name) {
+ const char[] MPQ_A_GET = type ~ " " ~ name2 ~ "() { " ~
+ type ~ " ret; " ~
+ "archive_" ~ name ~ "(m, &ret); return ret;" ~
+ "}";
+}
+
+/** wrapper class for an MPQ Archive
+ *
+ * syntax: auto a = new mpq.Archive("somefile.mpq");
+ */
+class Archive {
+ mpq_archive_s *m;
+ File listfile;
+ char[][] listfiledata;
+
+ this(char[] archivename, off_t offset = -1) {
+ archive_open(&m, toStringz(archivename), offset);
+ }
+
+ mixin(MPQ_A_GET!("off_t", "packed_size"));
+ mixin(MPQ_A_GET!("off_t", "unpacked_size"));
+ mixin(MPQ_A_GET!("off_t", "offset"));
+ mixin(MPQ_A_GET!("uint", "version", "version_"));
+ mixin(MPQ_A_GET!("uint", "files"));
+
+ ~this() {
+ archive_close(m);
+ }
+
+ mpq_archive_s* archive() {
+ return m;
+ }
+
+ File opIndex(char[] fname) {
+ return new File(this, fname);
+ }
+ File opIndex(int fno) {
+ return new File(this, fno);
+ }
+
+ char[][] filelist() {
+ try {
+ if (!listfile) {
+ listfile = this["(listfile)"];
+ listfiledata = (cast(char[])listfile.read()).splitlines();
+ }
+ return listfiledata;
+ } catch (MPQException e) {
+ return [];
+ }
+ }
+
+ /+uint filenumber(char[] filename) {
+ try {
+ if (!listfile) {
+ listfile = this["(listfile)"];
+ listfiledata = (cast(char[])listfile.read()).splitlines();
+ }
+ return listfiledata;
+ } catch (MPQException e) {
+ return [];
+ }
+ }+/
+
+}
+
+
+/** getter function named name for returning file_* single values:
+ *
+ * <type> File.<name>() { return libmpq__file_<name>() }
+ *
+ * @param type return type for the original function reference
+ * @param name name of the original function
+ * @param name2 name for the prototype (defaults to name, used for "version")
+ * @return getter function mixin
+ */
+template MPQ_F_GET(char[] type, char[] name, char[] name2 = name) {
+ const char[] MPQ_F_GET = type ~ " " ~ name2 ~ "() { " ~
+ type ~ " ret; " ~
+ "file_" ~ name ~ "(am, fileno, &ret); " ~
+ "return ret;" ~
+ "}";
+}
+
+/** wrapper class for a single file in an MPQ Archive
+ *
+ * syntax:
+ * auto a = new mpq.Archive("somefile.mpq");
+ * auto f = a["(listfile)"];
+ * auto f2 = a[0];
+ * auto f3 = new File(a, "(listfile)");
+ */
+class File {
+ Archive a;
+ mpq_archive_s* am;
+ char[] filename;
+ uint fileno;
+
+ this(Archive a, int fileno) {
+ this.a = a;
+ this.am = a.archive();
+ if (fileno >= a.files) {
+ throw new MPQException(format("File(%d)", fileno),
+ LIBMPQ_ERROR_EXIST);
+ }
+ this.filename = format("file%04d.xxx", fileno);
+ this.fileno = fileno;
+ }
+
+ this(Archive a, char[] filename) {
+ this.a = a;
+ this.am = a.archive();
+ this.filename = filename;
+ /* this line will throw an exception when the file is not there */
+ mpq.file_number(am, toStringz(filename), &this.fileno);
+ }
+
+ mixin(MPQ_F_GET!("off_t", "packed_size"));
+ mixin(MPQ_F_GET!("off_t", "unpacked_size"));
+ mixin(MPQ_F_GET!("off_t", "offset"));
+ mixin(MPQ_F_GET!("uint", "blocks"));
+ mixin(MPQ_F_GET!("uint", "encrypted"));
+ mixin(MPQ_F_GET!("uint", "compressed"));
+ mixin(MPQ_F_GET!("uint", "imploded"));
+
+ uint no() { return fileno; }
+ char[] name() { return filename; }
+
+ ubyte[] read() {
+ ubyte[] content;
+ content.length = this.unpacked_size();
+ off_t trans;
+ mpq.file_read(am, fileno, content.ptr, content.length, &trans);
+ content.length = trans;
+ return content;
+ }
+}
diff --git a/contrib/libmpq/bindings/python/Makefile.am b/contrib/libmpq/bindings/python/Makefile.am
new file mode 100644
index 00000000000..6971a9b2f6d
--- /dev/null
+++ b/contrib/libmpq/bindings/python/Makefile.am
@@ -0,0 +1,5 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# library information and headers which should not be installed.
+python_PYTHON = mpq.py
diff --git a/contrib/libmpq/bindings/python/mpq-info b/contrib/libmpq/bindings/python/mpq-info
new file mode 100644
index 00000000000..2c67aa1d0cc
--- /dev/null
+++ b/contrib/libmpq/bindings/python/mpq-info
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+
+from __future__ import division
+
+import sys
+
+import mpq
+
+archive = mpq.Archive(sys.argv[1])
+
+print "Name: %s" % sys.argv[1]
+print "Version: %s" % archive.filename
+print "Offset: %s" % archive.offset
+print "Packed size: %s" % archive.packed_size
+print "Unpacked size: %s" % archive.unpacked_size
+print "Compression ratio: %s" % (archive.packed_size/archive.unpacked_size)
diff --git a/contrib/libmpq/bindings/python/mpq.py b/contrib/libmpq/bindings/python/mpq.py
new file mode 100644
index 00000000000..cf6ecaae800
--- /dev/null
+++ b/contrib/libmpq/bindings/python/mpq.py
@@ -0,0 +1,322 @@
+"""wrapper for libmpq"""
+
+# 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.
+
+import ctypes
+import ctypes.util
+import os
+
+libmpq = ctypes.CDLL(ctypes.util.find_library("mpq"))
+
+class Error(Exception):
+ pass
+
+errors = {
+ -1: (IOError, "open"),
+ -2: (IOError, "close"),
+ -3: (IOError, "seek"),
+ -4: (IOError, "read"),
+ -5: (IOError, "write"),
+ -6: (MemoryError,),
+ -7: (Error, "file is not an mpq or is corrupted"),
+ -8: (AssertionError, "not initialized"),
+ -9: (AssertionError, "buffer size too small"),
+ -10: (IndexError, "file not in archive"),
+ -11: (AssertionError, "decrypt"),
+ -12: (AssertionError, "unpack"),
+}
+
+def check_error(result, func, arguments, errors=errors):
+ try:
+ error = errors[result]
+ except KeyError:
+ return result
+ else:
+ raise error[0](*error[1:])
+
+libmpq.libmpq__version.restype = ctypes.c_char_p
+
+libmpq.libmpq__archive_open.errcheck = check_error
+libmpq.libmpq__archive_close.errcheck = check_error
+libmpq.libmpq__archive_packed_size.errcheck = check_error
+libmpq.libmpq__archive_unpacked_size.errcheck = check_error
+libmpq.libmpq__archive_offset.errcheck = check_error
+libmpq.libmpq__archive_version.errcheck = check_error
+libmpq.libmpq__archive_files.errcheck = check_error
+
+libmpq.libmpq__file_packed_size.errcheck = check_error
+libmpq.libmpq__file_unpacked_size.errcheck = check_error
+libmpq.libmpq__file_offset.errcheck = check_error
+libmpq.libmpq__file_blocks.errcheck = check_error
+libmpq.libmpq__file_encrypted.errcheck = check_error
+libmpq.libmpq__file_compressed.errcheck = check_error
+libmpq.libmpq__file_imploded.errcheck = check_error
+libmpq.libmpq__file_number.errcheck = check_error
+libmpq.libmpq__file_read.errcheck = check_error
+
+libmpq.libmpq__block_open_offset.errcheck = check_error
+libmpq.libmpq__block_close_offset.errcheck = check_error
+libmpq.libmpq__block_unpacked_size.errcheck = check_error
+libmpq.libmpq__block_read.errcheck = check_error
+
+__version__ = libmpq.libmpq__version()
+
+
+class Reader(object):
+ def __init__(self, file, libmpq=libmpq):
+ self._file = file
+ self._pos = 0
+ self._buf = []
+ self._cur_block = 0
+ libmpq.libmpq__block_open_offset(self._file._archive._mpq,
+ self._file.number)
+
+ def __iter__(self):
+ return self
+
+ def __repr__(self):
+ return "iter(%r)" % self._file
+
+ def seek(self, offset, whence=os.SEEK_SET, os=os):
+ if whence == os.SEEK_SET:
+ pass
+ elif whence == os.SEEK_CUR:
+ offset += self._pos
+ elif whence == os.SEEK_END:
+ offset += self._file.unpacked_size
+ else:
+ raise ValueError, "invalid whence"
+
+ if offset >= self._pos:
+ self.read(offset - self._pos)
+ else:
+ self._pos = 0
+ self._buf = []
+ self._cur_block = 0
+ self.read(offset)
+
+ def tell(self):
+ return self._pos
+
+ def _read_block(self, ctypes=ctypes, libmpq=libmpq):
+ block_size = ctypes.c_uint64()
+ libmpq.libmpq__block_unpacked_size(self._file._archive._mpq,
+ self._file.number, self._cur_block, ctypes.byref(block_size))
+ block_data = ctypes.create_string_buffer(block_size.value)
+ libmpq.libmpq__block_read(self._file._archive._mpq,
+ self._file.number, self._cur_block,
+ block_data, ctypes.c_uint64(len(block_data)), None)
+ self._buf.append(block_data.raw)
+ self._cur_block += 1
+
+ def read(self, size=-1):
+ while size < 0 or sum(map(len, self._buf)) < size:
+ if self._cur_block == self._file.blocks:
+ break
+ self._read_block()
+ buf = "".join(self._buf)
+ if size < 0:
+ ret = buf
+ self._buf = []
+ else:
+ ret = buf[:size]
+ self._buf = [buf[size:]]
+ self._pos += len(ret)
+ return ret
+
+ def readline(self, os=os):
+ line = []
+ while True:
+ char = self.read(1)
+ if char == "":
+ break
+ if char not in '\r\n' and line and line[-1] in '\r\n':
+ self.seek(-1, os.SEEK_CUR)
+ break
+ line.append(char)
+ return ''.join(line)
+
+ def next(self):
+ line = self.readline()
+ if not line:
+ raise StopIteration
+ return line
+
+ def readlines(self, sizehint=-1):
+ res = []
+ while sizehint < 0 or sum(map(len, res)) < sizehint:
+ line = self.readline()
+ if not line:
+ break
+ res.append(line)
+ return res
+
+ xreadlines = __iter__
+
+ def __del__(self, libmpq=libmpq):
+ libmpq.libmpq__block_close_offset(self._file._archive._mpq,
+ self._file.number)
+
+
+class File(object):
+ def __init__(self, archive, number, ctypes=ctypes, libmpq=libmpq):
+ self._archive = archive
+ self.number = number
+
+ for name, atype in [
+ ("packed_size", ctypes.c_uint64),
+ ("unpacked_size", ctypes.c_uint64),
+ ("offset", ctypes.c_uint64),
+ ("blocks", ctypes.c_uint32),
+ ("encrypted", ctypes.c_uint32),
+ ("compressed", ctypes.c_uint32),
+ ("imploded", ctypes.c_uint32),
+ ]:
+ data = atype()
+ func = getattr(libmpq, "libmpq__file_"+name)
+ func(self._archive._mpq, self.number, ctypes.byref(data))
+ setattr(self, name, data.value)
+
+ def __str__(self, ctypes=ctypes, libmpq=libmpq):
+ data = ctypes.create_string_buffer(self.unpacked_size)
+ libmpq.libmpq__file_read(self._archive._mpq, self.number,
+ data, ctypes.c_uint64(len(data)), None)
+ return data.raw
+
+ def __repr__(self):
+ return "%r[%i]" % (self._archive, self.number)
+
+ def __iter__(self, Reader=Reader):
+ return Reader(self)
+
+
+class Archive(object):
+ def __init__(self, source, ctypes=ctypes, File=File, libmpq=libmpq):
+ self._source = source
+ if isinstance(source, File):
+ assert not source.encrypted
+ assert not source.compressed
+ assert not source.imploded
+ self.filename = source._archive.filename
+ offset = source._archive.offset + source.offset
+ else:
+ self.filename = source
+ offset = -1
+
+ self._mpq = ctypes.c_void_p()
+ libmpq.libmpq__archive_open(ctypes.byref(self._mpq), self.filename,
+ ctypes.c_uint64(offset))
+ self._opened = True
+
+ for field_name, field_type in [
+ ("packed_size", ctypes.c_uint64),
+ ("unpacked_size", ctypes.c_uint64),
+ ("offset", ctypes.c_uint64),
+ ("version", ctypes.c_uint32),
+ ("files", ctypes.c_uint32),
+ ]:
+ func = getattr(libmpq, "libmpq__archive_" + field_name)
+ data = field_type()
+ func(self._mpq, ctypes.byref(data))
+ setattr(self, field_name, data.value)
+
+ def __del__(self, libmpq=libmpq):
+ if getattr(self, "_opened", False):
+ libmpq.libmpq__archive_close(self._mpq)
+
+ def __len__(self):
+ return self.files
+
+ def __contains__(self, item, ctypes=ctypes, libmpq=libmpq):
+ if isinstance(item, str):
+ data = ctypes.c_uint32()
+ try:
+ libmpq.libmpq__file_number(self._mpq, ctypes.c_char_p(item),
+ ctypes.byref(data))
+ except IndexError:
+ return False
+ return True
+ return 0 <= item < self.files
+
+ def __getitem__(self, item, ctypes=ctypes, File=File, libmpq=libmpq):
+ if isinstance(item, str):
+ data = ctypes.c_int()
+ libmpq.libmpq__file_number(self._mpq, ctypes.c_char_p(item),
+ ctypes.byref(data))
+ item = data.value
+ else:
+ if not 0 <= item < self.files:
+ raise IndexError, "file not in archive"
+ return File(self, item)
+
+ def __repr__(self):
+ return "mpq.Archive(%r)" % self._source
+
+# Remove clutter - everything except Error and Archive.
+del os, check_error, ctypes, errors, File, libmpq, Reader
+
+if __name__ == "__main__":
+ import sys, random
+ archive = Archive(sys.argv[1])
+ print repr(archive)
+ for k, v in archive.__dict__.iteritems():
+ #if k[0] == '_': continue
+ print " " * (4 - 1), k, v
+ assert '(listfile)' in archive
+ assert 0 in archive
+ assert len(archive) == archive.files
+ files = [x.strip() for x in archive['(listfile)']]
+ files.extend(xrange(archive.files))
+ for key in files: #sys.argv[2:] if sys.argv[2:] else xrange(archive.files):
+ file = archive[key]
+ print
+ print " " * (4 - 1), repr(file)
+ for k, v in file.__dict__.iteritems():
+ #if k[0] == '_': continue
+ print " " * (8 - 1), k, v
+
+ a = str(file)
+
+ b = iter(file).read()
+
+ reader = iter(file)
+ c = []
+ while True:
+ l = random.randrange(1, 10)
+ d = reader.read(l)
+ if not d: break
+ assert len(d) <= l
+ c.append(d)
+ c = "".join(c)
+
+ d = []
+ reader.seek(0)
+ for line in reader:
+ d.append(line)
+ d = "".join(d)
+
+ assert a == b == c == d, map(hash, [a,b,c,d])
+ assert len(a) == file.unpacked_size
+
+ repr(iter(file))
+
+
+ reader.seek(0)
+ a = reader.readlines()
+
+ reader.seek(0)
+ b = list(reader)
+
+ assert a == b
diff --git a/contrib/libmpq/configure.ac b/contrib/libmpq/configure.ac
new file mode 100644
index 00000000000..d274eab07c6
--- /dev/null
+++ b/contrib/libmpq/configure.ac
@@ -0,0 +1,84 @@
+# the autoconf initilization.
+AC_INIT(libmpq, 0.4.2, [mbroemme@plusserver.de], [libmpq])
+
+# detect the canonical host and target build environment.
+AC_CANONICAL_SYSTEM
+
+# initialize autoconf and automake system.
+AM_INIT_AUTOMAKE([no-dependencies])
+AC_CONFIG_HEADERS([config.h:config.h.in])
+
+# notices.
+AC_PREREQ(2.53)
+AC_REVISION($Revision: 1.6 $)
+
+# checking for programs.
+AC_PROG_LIBTOOL
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_SYS_LARGEFILE
+AC_FUNC_FSEEKO
+
+# check if we need to export some largefile flags.
+if test "$enable_largefile" != no; then
+ if test "$ac_cv_sys_file_offset_bits" != 'no'; then
+ if test -z "$LFS_CFLAGS" ; then
+ LFS_CFLAGS="-D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+ else
+ LFS_CFLAGS="$LFS_CFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+ fi
+ fi
+ if test "$ac_cv_sys_large_files" != 'no'; then
+ if test -z "$LFS_CFLAGS" ; then
+ LFS_CFLAGS="-D_LARGE_FILES=1"
+ else
+ LFS_CFLAGS="$LFS_CFLAGS -D_LARGE_FILES=1"
+ fi
+ fi
+ if test "$ac_cv_sys_largefile_source" != 'no'; then
+ if test -z "$LFS_CFLAGS" ; then
+ LFS_CFLAGS="-D_LARGEFILE_SOURCE=1"
+ else
+ LFS_CFLAGS="$LFS_CFLAGS -D_LARGEFILE_SOURCE=1"
+ fi
+ fi
+fi
+
+# export largefile flags.
+AC_SUBST(LFS_CFLAGS)
+
+# check for zlib library.
+AC_CHECK_HEADER([zlib.h], [], [AC_MSG_ERROR([*** zlib.h is required, install zlib header files])])
+AC_CHECK_LIB([z], [inflateEnd], [], [AC_MSG_ERROR([*** inflateEnd is required, install zlib library files])])
+
+# check for bzlib2 library.
+AC_CHECK_HEADER([bzlib.h], [], [AC_MSG_ERROR([*** bzlib.h is required, install bzip2 header files])])
+AC_CHECK_LIB([bz2], [BZ2_bzDecompressInit], [], [AC_MSG_ERROR([*** BZ2_bzDecompressInit is required, install bzip2 library files])])
+
+# When we're running gcc 4 or greater, compile with -fvisibility=hidden.
+AC_TRY_COMPILE([
+#if !defined(__GNUC__) || (__GNUC__ < 4)
+#error not gcc4
+#endif
+], [], [CFLAGS="$CFLAGS -fvisibility=hidden"])
+
+# find python for binding
+AM_PATH_PYTHON([2.4],,[:])
+AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :])
+
+# configuration files.
+AC_CONFIG_FILES([libmpq.pc])
+AC_CONFIG_FILES([libmpq-config],[chmod +x libmpq-config])
+
+# creating files.
+AC_OUTPUT([
+Makefile
+libmpq/Makefile
+bindings/Makefile
+bindings/d/Makefile
+bindings/python/Makefile
+doc/Makefile
+doc/man1/Makefile
+doc/man3/Makefile
+tools/Makefile
+])
diff --git a/contrib/libmpq/debian/changelog b/contrib/libmpq/debian/changelog
new file mode 100644
index 00000000000..55d2d918755
--- /dev/null
+++ b/contrib/libmpq/debian/changelog
@@ -0,0 +1,35 @@
+libmpq (0.4.2-svn288-1) unstable; urgency=low
+
+ [ babyface ]
+ * Due to the nature of MPQ archives which can have valid block entries
+ * removed function libmpq__init() and libmpq__shutdown(), because they
+ are no longer required and libmpq__file_name(), because it is up to
+ the application to provide listfile support
+ * updated documentation to latest API changes
+ * removed API documentation for removed function prototypes
+ * removed no longer required files from target
+
+ [ forrestv ]
+ * mpq.py fix
+ * spelling - huffmann to huffman
+ * changed pkware/pkzip to pkzip and used constants instead of numbers
+ in extract.c
+ * sanified huffman decoder a bit
+ * cleanup + update of mpq.py
+ * Added support for library finding on platforms besides Linux.
+ * python bindings - sequence methods on Archive, example code
+
+ [ georg ]
+ * libmpq: file number search now continued over hashtable end
+ * debian debug package
+
+ -- Georg Lukas <georg@op-co.de> Fri, 22 May 2009 22:38:26 +0200
+
+libmpq (0.4.2-svn270-1) unstable; urgency=low
+
+ * First debian package
+ * compatible to new libmpq API (post 0.4.2)
+ * contains preliminary python-mpq package
+
+ -- Georg Lukas <georg@op-co.de> Tue, 07 Oct 2008 14:38:58 +0200
+
diff --git a/contrib/libmpq/debian/compat b/contrib/libmpq/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/contrib/libmpq/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/contrib/libmpq/debian/control b/contrib/libmpq/debian/control
new file mode 100644
index 00000000000..f35bb060015
--- /dev/null
+++ b/contrib/libmpq/debian/control
@@ -0,0 +1,50 @@
+Source: libmpq
+Priority: extra
+Maintainer: Georg Lukas <georg@op-co.de>
+Build-Depends: debhelper (>= 7), autotools-dev, libbz2-dev
+Standards-Version: 3.7.3
+Section: libs
+Homepage: https://libmpq.org/
+
+Package: libmpq-dev
+Section: libdevel
+Architecture: any
+Depends: libmpq0 (= ${binary:Version})
+Description: Headers for libmpq, a library for MoPaQ mpq archives
+ libmpq is a library for extracting and manipulating MoPaQ mpq archives.
+ This package provides header files and bindings for applications using
+ the libmpq library for the following languages:
+ * C
+ * Python
+ * D
+
+Package: libmpq0
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: A library for extracting and manipulating MoPaQ mpq archives
+ MPQ, or MoPaQ, is a proprietary archive format created by
+ Mike O'Brien, the man hailed as Blizzard's multiplayer engine
+ genius, back in 1996 as a general purpose archive for use with
+ Diablo, and named narcissistically for its creator
+ "Mike O'brien PaCK". The copyrights to it, however, are held by
+ Havas Interactive, Blizzard's parent company. The archive format
+ is used by many Blizzard titles like Diablo, Diablo 2, Starcraft,
+ Warcraft 2: BNE, a newer version in Warcraft 3 and World of
+ Warcraft (WoW).
+
+Package: libmpq0-dbg
+Section: libdevel
+Architecture: any
+Depends: libmpq0 (= ${binary:Version})
+Description: Debug symbols for libmpq0 library package
+
+Package: python-mpq
+Architecture: all
+Depends: ${python:Depends}
+XB-Python-Version: ${python:Versions}
+XS-Python-Version: current
+Description: Python bindings for libmpq, a library for MoPaQ mpq archives
+ libmpq is a library for extracting and manipulating MoPaQ mpq archives.
+ This package provides the python bindings for libmpq.
+
diff --git a/contrib/libmpq/debian/copyright b/contrib/libmpq/debian/copyright
new file mode 100644
index 00000000000..f014cf14de7
--- /dev/null
+++ b/contrib/libmpq/debian/copyright
@@ -0,0 +1,23 @@
+This package was debianized by Georg Lukas <georg@op-co.de> on
+Fri, 04 Jul 2008 18:17:08 +0200.
+
+It was downloaded from <https://libmpq.org/>
+
+Upstream Author:
+
+ Maik Broemme <mbroemme@plusserver.de>
+
+Copyright:
+
+ Copyright (C) 2008 Maik Broemme
+
+License:
+
+ 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.
+
+
+The Debian packaging is (C) 2008, Georg Lukas <georg@op-co.de> and
+is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
diff --git a/contrib/libmpq/debian/libmpq-dev.dirs b/contrib/libmpq/debian/libmpq-dev.dirs
new file mode 100644
index 00000000000..7b6c7ee6ec1
--- /dev/null
+++ b/contrib/libmpq/debian/libmpq-dev.dirs
@@ -0,0 +1,6 @@
+usr/bin
+usr/lib
+usr/lib/pkgconfig
+usr/include
+usr/share/man/man1
+usr/share/man/man3
diff --git a/contrib/libmpq/debian/libmpq-dev.install b/contrib/libmpq/debian/libmpq-dev.install
new file mode 100644
index 00000000000..4e6ab3278e3
--- /dev/null
+++ b/contrib/libmpq/debian/libmpq-dev.install
@@ -0,0 +1,6 @@
+usr/bin/*
+usr/include/*
+usr/lib/lib*.a
+usr/lib/pkgconfig/*
+usr/lib/*.la
+usr/share/man/man?/*
diff --git a/contrib/libmpq/debian/libmpq0.dirs b/contrib/libmpq/debian/libmpq0.dirs
new file mode 100644
index 00000000000..68457717bd8
--- /dev/null
+++ b/contrib/libmpq/debian/libmpq0.dirs
@@ -0,0 +1 @@
+usr/lib
diff --git a/contrib/libmpq/debian/libmpq0.docs b/contrib/libmpq/debian/libmpq0.docs
new file mode 100644
index 00000000000..5ac7060850c
--- /dev/null
+++ b/contrib/libmpq/debian/libmpq0.docs
@@ -0,0 +1,6 @@
+FAQ
+NEWS
+README
+TODO
+THANKS
+AUTHORS
diff --git a/contrib/libmpq/debian/libmpq0.install b/contrib/libmpq/debian/libmpq0.install
new file mode 100644
index 00000000000..8aa4466a68e
--- /dev/null
+++ b/contrib/libmpq/debian/libmpq0.install
@@ -0,0 +1 @@
+usr/lib/lib*.so*
diff --git a/contrib/libmpq/debian/python-mpq.install b/contrib/libmpq/debian/python-mpq.install
new file mode 100644
index 00000000000..a7aba2013b0
--- /dev/null
+++ b/contrib/libmpq/debian/python-mpq.install
@@ -0,0 +1 @@
+usr/lib/python?.?
diff --git a/contrib/libmpq/debian/rules b/contrib/libmpq/debian/rules
new file mode 100644
index 00000000000..5d11fe010db
--- /dev/null
+++ b/contrib/libmpq/debian/rules
@@ -0,0 +1,112 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
+CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
+else
+CROSS= --build $(DEB_BUILD_GNU_TYPE)
+endif
+
+
+
+
+# shared library versions, option 1
+version=2.0.5
+major=2
+# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
+#version=`ls src/.libs/lib*.so.* | \
+# awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
+#major=`ls src/.libs/lib*.so.* | \
+# awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
+
+config.status: configure
+ dh_testdir
+ # Add here commands to configure the package.
+ifneq "$(wildcard /usr/share/misc/config.sub)" ""
+ cp -f /usr/share/misc/config.sub config.sub
+endif
+ifneq "$(wildcard /usr/share/misc/config.guess)" ""
+ cp -f /usr/share/misc/config.guess config.guess
+endif
+ ./configure $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs"
+
+
+build: build-stamp
+build-stamp: config.status
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+
+ # Add here commands to clean up after the build process.
+ [ ! -f Makefile ] || $(MAKE) distclean
+ rm -f config.sub config.guess
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/tmp
+ $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+ dh_pysupport usr/lib/python?.?/site-packages
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+ dh_install
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip --dbg-package=libmpq0-dbg
+ dh_compress
+ dh_fixperms
+# dh_perl
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/contrib/libmpq/doc/Makefile.am b/contrib/libmpq/doc/Makefile.am
new file mode 100644
index 00000000000..e7ccd5f4518
--- /dev/null
+++ b/contrib/libmpq/doc/Makefile.am
@@ -0,0 +1,5 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# any directories which should be built and installed.
+SUBDIRS = man1 man3
diff --git a/contrib/libmpq/doc/man1/Makefile.am b/contrib/libmpq/doc/man1/Makefile.am
new file mode 100644
index 00000000000..055f1aab533
--- /dev/null
+++ b/contrib/libmpq/doc/man1/Makefile.am
@@ -0,0 +1,9 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# manual page directory.
+EXTRA_DIST = $(man_MANS)
+
+# manual pages for the installed binaries.
+man_MANS = \
+ libmpq-config.1
diff --git a/contrib/libmpq/doc/man1/libmpq-config.1 b/contrib/libmpq/doc/man1/libmpq-config.1
new file mode 100644
index 00000000000..c025f5ce4f4
--- /dev/null
+++ b/contrib/libmpq/doc/man1/libmpq-config.1
@@ -0,0 +1,69 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 1 2008-02-10 "The MoPaQ archive library"
+.SH NAME
+libmpq-config \- script to get information about the installed version of libmpq.
+.SH SYNOPSIS
+.B libmpq-config
+[\-\-prefix\fI[=DIR]\fP] [\-\-exec\-prefix\fI[=DIR]\fP] [\-\-version]
+.br
+[\-\-cflags] [\-\-libs] [\-\-static\-libs]
+.SH DESCRIPTION
+.PP
+\fIlibmpq-config\fP is a tool that is used to determine the compiler and linker flags that should be used to compile and link programs that use \fIlibmpq\fP. Finally, it's also used internally by the .m4 macros for GNU autoconf that are included with \fIlibmpq\fP.
+.SH OPTIONS
+\fIlibmpq-config\fP accepts the following options:
+.TP 8
+.B \-\-version
+.ti 15
+Print the currently installed version of \fIlibmpq\fP on the standard output.
+.TP 8
+.B \-\-libs
+.ti 15
+Print the linker flags that are necessary to link \fIlibmpq\fP to a program.
+.TP 8
+.B \-\-static\-libs
+.ti 15
+Print the linker flags that are necessary to statically link \fIlibmpq\fP to a program.
+.TP 8
+.B \-\-cflags
+.ti 15
+Print the compiler flags that are necessary to compile a program that use \fIlibmpq\fP.
+.TP 8
+.B \-\-prefix=PREFIX
+.ti 15
+If specified, use PREFIX instead of the installation prefix that \fIlibmpq\fP was built with when computing the output for the \-\-cflags and \-\-libs options. This option is also used for the exec prefix if \-\-exec\-prefix was not specified. This option must be specified before any \-\-libs or \-\-cflags options.
+.TP 8
+.B \-\-exec\-prefix=PREFIX
+.ti 15
+If specified, use PREFIX instead of the installation exec prefix that \fIlibmpq\fP was built with when computing the output for the \-\-cflags and \-\-libs options. This option must be specified before any \-\-libs or \-\-cflags options.
+.SH NOTE
+Instead of using this configuration script you should better use the pkg-config version because this would be more platform independent and makes the usage within GNU autoconf much easier.
+.SH SEE ALSO
+\fBlibmpq\fR(3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/Makefile.am b/contrib/libmpq/doc/man3/Makefile.am
new file mode 100644
index 00000000000..80bff4e7461
--- /dev/null
+++ b/contrib/libmpq/doc/man3/Makefile.am
@@ -0,0 +1,30 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# manual page directory.
+EXTRA_DIST = $(man_MANS)
+
+# manual pages for the installed binaries.
+man_MANS = \
+ libmpq.3 \
+ libmpq__archive_close.3 \
+ libmpq__archive_files.3 \
+ libmpq__archive_offset.3 \
+ libmpq__archive_open.3 \
+ libmpq__archive_packed_size.3 \
+ libmpq__archive_unpacked_size.3 \
+ libmpq__archive_version.3 \
+ libmpq__block_close_offset.3 \
+ libmpq__block_open_offset.3 \
+ libmpq__block_read.3 \
+ libmpq__block_unpacked_size.3 \
+ libmpq__file_blocks.3 \
+ libmpq__file_compressed.3 \
+ libmpq__file_encrypted.3 \
+ libmpq__file_imploded.3 \
+ libmpq__file_number.3 \
+ libmpq__file_offset.3 \
+ libmpq__file_packed_size.3 \
+ libmpq__file_read.3 \
+ libmpq__file_unpacked_size.3 \
+ libmpq__version.3
diff --git a/contrib/libmpq/doc/man3/libmpq.3 b/contrib/libmpq/doc/man3/libmpq.3
new file mode 100644
index 00000000000..349451f87b1
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq.3
@@ -0,0 +1,204 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-04-29 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "const char *libmpq__version();"
+.sp
+.BI "int32_t libmpq__archive_open("
+.BI " mpq_archive_s **" "mpq_archive",
+.BI " const char *" "mpq_filename",
+.BI " off_t " "archive_offset"
+.BI ");"
+.sp
+.BI "int32_t libmpq__archive_close("
+.BI " mpq_archive_s *" "mpq_archive"
+.BI ");"
+.sp
+.BI "int32_t libmpq__archive_packed_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " off_t *" "packed_size"
+.BI ");"
+.sp
+.BI "int32_t libmpq__archive_unpacked_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " off_t *" "unpacked_size"
+.BI ");"
+.sp
+.BI "int32_t libmpq__archive_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " off_t *" "offset"
+.BI ");"
+.sp
+.BI "int32_t libmpq__archive_version("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t *" "version"
+.BI ");"
+.sp
+.BI "int32_t libmpq__archive_files("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t *" "files"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_packed_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "packed_size"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_unpacked_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "unpacked_size"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "offset"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_blocks("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "blocks"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_encrypted("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "encrypted"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_compressed("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "compressed"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_imploded("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "imploded"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_number("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " const char *" "filename",
+.BI " uint32_t *" "number"
+.BI ");"
+.sp
+.BI "int32_t libmpq__file_read("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint8_t *" "out_buf",
+.BI " off_t " "out_size",
+.BI " off_t *" "transferred"
+.BI ");"
+.sp
+.BI "int32_t libmpq__block_open_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number"
+.BI ");"
+.sp
+.BI "int32_t libmpq__block_close_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number"
+.BI ");"
+.sp
+.BI "int32_t libmpq__block_packed_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t " "block_number",
+.BI " off_t *" "packed_size"
+.BI ");"
+.sp
+.BI "int32_t libmpq__block_unpacked_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t " "block_number",
+.BI " off_t *" "unpacked_size"
+.BI ");"
+.sp
+.BI "int32_t libmpq__block_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t " "block_number",
+.BI " off_t *" "offset"
+.BI ");"
+.sp
+.BI "int32_t libmpq__block_seed("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t " "block_number",
+.BI " uint32_t *" "seed"
+.BI ");"
+.sp
+.BI "int32_t libmpq__block_read("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t " "block_number",
+.BI " uint8_t *" "out_buf",
+.BI " off_t " "out_size",
+.BI " off_t *" "transferred"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+The \fIlibmpq\fP library supports decrypting, decompressing, exploding and various manipulations of the MoPaQ archive files. It uses \fIzlib(3)\fP and \fIbzip2(1)\fP compression library. At this moment \fIlibmpq\fP is not able to create MoPaQ archives, this limitation will be removed in a future version.
+.SH SEE ALSO
+.BR libmpq__version (3),
+.BR libmpq__archive_open (3),
+.BR libmpq__archive_close (3),
+.BR libmpq__archive_packed_size (3),
+.BR libmpq__archive_unpacked_size (3),
+.BR libmpq__archive_offset (3),
+.BR libmpq__archive_version (3),
+.BR libmpq__archive_files (3),
+.BR libmpq__file_packed_size (3),
+.BR libmpq__file_unpacked_size (3),
+.BR libmpq__file_offset (3),
+.BR libmpq__file_blocks (3),
+.BR libmpq__file_encrypted (3),
+.BR libmpq__file_compressed (3),
+.BR libmpq__file_imploded (3),
+.BR libmpq__file_number (3),
+.BR libmpq__file_read (3),
+.BR libmpq__block_open_offset (3),
+.BR libmpq__block_close_offset (3),
+.BR libmpq__block_packed_size (3),
+.BR libmpq__block_unpacked_size (3),
+.BR libmpq__block_offset (3),
+.BR libmpq__block_seed (3),
+.BR libmpq__block_read (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__archive_close.3 b/contrib/libmpq/doc/man3/libmpq__archive_close.3
new file mode 100644
index 00000000000..dfc652a6721
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__archive_close.3
@@ -0,0 +1,57 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-04-29 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__archive_close("
+.BI " mpq_archive_s *" "mpq_archive"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__archive_close\fP() to close a mpq archive which was opened by \fBlibmpq__archive_open\fP(). The function frees the archive structure itself and the contents of it.
+.LP
+The \fBlibmpq__archive_close\fP() function one takes one argument of the archive structure \fImpq_archive\fP which has to be set by \fBlibmpq__archive_open\fP.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_CLOSE
+The given file could not be closed.
+.SH SEE ALSO
+.BR libmpq__archive_open (3),
+.BR libmpq__archive_packed_size (3),
+.BR libmpq__archive_unpacked_size (3),
+.BR libmpq__archive_offset (3),
+.BR libmpq__archive_version (3),
+.BR libmpq__archive_files (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__archive_files.3 b/contrib/libmpq/doc/man3/libmpq__archive_files.3
new file mode 100644
index 00000000000..6663b99161a
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__archive_files.3
@@ -0,0 +1,50 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-14 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__archive_files("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t *" "files"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__archive_files\fP() to get the number of files inside the archive. It will count only valid files and skip files which have deleted or freed hash entries.
+.LP
+The \fBlibmpq__archive_files\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument is a reference to the number of \fIfiles\fP in the archive.
+.SH RETURN VALUE
+On success, a zero is returned.
+.SH SEE ALSO
+.BR libmpq__file_blocks (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__archive_offset.3 b/contrib/libmpq/doc/man3/libmpq__archive_offset.3
new file mode 100644
index 00000000000..696ac5e809f
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__archive_offset.3
@@ -0,0 +1,51 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-14 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__archive_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " off_t *" "offset"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__archive_offset\fP() to get the offset of the archive, which is the absolute position in the file. It also supports archives within archives.
+.LP
+The \fBlibmpq__archive_offset\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument is a reference to the archive starting position \fIoffset\fP in file.
+.SH RETURN VALUE
+On success, a zero is returned.
+.SH SEE ALSO
+.BR libmpq__file_offset (3),
+.BR libmpq__block_offset (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__archive_open.3 b/contrib/libmpq/doc/man3/libmpq__archive_open.3
new file mode 100644
index 00000000000..02c021f8948
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__archive_open.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-04-29 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__archive_open("
+.BI " mpq_archive_s **" "mpq_archive",
+.BI " const char *" "mpq_filename",
+.BI " off_t " "archive_offset"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__archive_open\fP() to open a given mpq archive for later use to extract or manipulate files inside the archive. It will create all required file structures and you have to call \fBlibmpq__archive_close\fP() on success to clean the opened structures. On failure there is no need to call \fBlibmpq__archive_close\fP() because everything will be cleaned up.
+.LP
+The \fBlibmpq__archive_open\fP() function takes as first argument a reference to the archive structure \fImpq_archive\fP and will open the file \fImpq_filename\fP to the structure pointed to by \fImpq_archive\fP. The last argument, \fIarchive_offset\fP is normally -1, but can be specified when the archive offset is known, or not 512-byte aligned.
+.SH RETURN VALUE
+On success, *\fImpq_archive\fP is set to a new \fBmpq_archive_s\fP* and zero is returned, and on error one of the following constants is returned.
+.TP
+.B LIBMPQ_ERROR_OPEN
+The given file could not be opened.
+.TP
+.B LIBMPQ_ERROR_MALLOC
+Not enough memory for creating required structures.
+.TP
+.B LIBMPQ_ERROR_SEEK
+Seeking in file failed.
+.TP
+.B LIBMPQ_ERROR_FORMAT
+The given file is no valid mpq archive.
+.TP
+.B LIBMPQ_ERROR_READ
+Reading in archive failed.
+.SH SEE ALSO
+.BR libmpq__archive_close (3),
+.BR libmpq__archive_packed_size (3),
+.BR libmpq__archive_unpacked_size (3),
+.BR libmpq__archive_offset (3),
+.BR libmpq__archive_version (3),
+.BR libmpq__archive_files (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__archive_packed_size.3 b/contrib/libmpq/doc/man3/libmpq__archive_packed_size.3
new file mode 100644
index 00000000000..6c3061f2031
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__archive_packed_size.3
@@ -0,0 +1,51 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-04-29 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__archive_packed_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " off_t *" "packed_size"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__archive_packed_size\fP() to get the packed size of all files in the archive. It will count compressed and imploded files as well as stored only.
+.LP
+The \fBlibmpq__archive_packed_size\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument is a reference to the compressed, imploded or stored size \fIpacked_size\fP of file.
+.SH RETURN VALUE
+On success, a zero is returned.
+.SH SEE ALSO
+.BR libmpq__file_packed_size (3),
+.BR libmpq__block_packed_size (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__archive_unpacked_size.3 b/contrib/libmpq/doc/man3/libmpq__archive_unpacked_size.3
new file mode 100644
index 00000000000..d2ba923c8f0
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__archive_unpacked_size.3
@@ -0,0 +1,51 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-04-29 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__archive_unpacked_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " off_t *" "unpacked_size"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__archive_unpacked_size\fP() to get the unpacked size of all files in the archive. It will count uncompressed and exploded files as well as stored only.
+.LP
+The \fBlibmpq__archive_unpacked_size\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument is a reference to the uncompressed, exploded or stored size \fIunpacked_size\fP of file.
+.SH RETURN VALUE
+On success, a zero is returned.
+.SH SEE ALSO
+.BR libmpq__file_unpacked_size (3),
+.BR libmpq__block_unpacked_size (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__archive_version.3 b/contrib/libmpq/doc/man3/libmpq__archive_version.3
new file mode 100644
index 00000000000..1764046895a
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__archive_version.3
@@ -0,0 +1,48 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-14 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__archive_version("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t *" "version"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__archive_version\fP() to get the archive version. Currently there exist two known versions, version 1 which supports archives until 2GB total size and version 2 which supports archives above 2GB total size and both are supported.
+.LP
+The \fBlibmpq__archive_version\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument is a reference to the \fIversion\fP of archive.
+.SH RETURN VALUE
+On success, a zero is returned.
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__block_close_offset.3 b/contrib/libmpq/doc/man3/libmpq__block_close_offset.3
new file mode 100644
index 00000000000..1ec0c06f70d
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__block_close_offset.3
@@ -0,0 +1,53 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__block_close_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__block_close_offset\fP() to close the block offset table for the given file. It will close the block offset table regardless of compression (compressed, imploded or stored) type of file.
+.LP
+The \fBlibmpq__block_close_offset\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file to close.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File or block does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__block_open_offset (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__block_open_offset.3 b/contrib/libmpq/doc/man3/libmpq__block_open_offset.3
new file mode 100644
index 00000000000..a60b133f406
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__block_open_offset.3
@@ -0,0 +1,65 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__block_open_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__block_open_offset\fP() to open the block offset table for the given file. It will open the block offset table regardless of compression (compressed, imploded or stored) type of file.
+.LP
+The \fBlibmpq__block_open_offset\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file to open.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File or block does not exist in archive.
+.TP
+.B LIBMPQ_ERROR_SEEK
+Seeking in file failed.
+.TP
+.B LIBMPQ_ERROR_MALLOC
+Not enough memory for creating required structures.
+.TP
+.B LIBMPQ_ERROR_READ
+Reading in archive failed.
+.TP
+.B LIBMPQ_ERROR_DECRYPT
+Decrypting block failed.
+.SH SEE ALSO
+.BR libmpq__block_close_offset (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__block_read.3 b/contrib/libmpq/doc/man3/libmpq__block_read.3
new file mode 100644
index 00000000000..3272c64c7ed
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__block_read.3
@@ -0,0 +1,78 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__block_read("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t " "block_number,
+.BI " uint8_t *" "out_buf",
+.BI " off_t " "out_size",
+.BI " off_t " "transferred"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__block_read\fP() to read a given block into memory. If the block is encrypted it will be first decrypted and then if it is packed (compressed or imploded) it will be unpacked.
+.LP
+The \fBlibmpq__block_read\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file, the third argument \fIblock_number\fP is the number of block. The fourth argument \fIout_buf\fP is the output data buffer which contains the extracted data and the fifth argument \fIout_size\fP is the size of \fIout_buf\fP. The sixth argument is a reference to the \fItransferred\fP bytes of the file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+Block does not exist in archive.
+.TP
+.B LIBMPQ_ERROR_OPEN
+Block offset table was not opened by calling \fBlibmpq__block_open_offset\fP(), or it was closed by an \fBlibmpq__block_close_offset\fP() call.
+.TP
+.B LIBMPQ_ERROR_SIZE
+The output buffer is to small.
+.TP
+.B LIBMPQ_ERROR_SEEK
+Seeking in file failed.
+.TP
+.B LIBMPQ_ERROR_MALLOC
+Not enough memory for creating required structures.
+.TP
+.B LIBMPQ_ERROR_READ
+Reading in archive failed.
+.TP
+.B LIBMPQ_ERROR_DECRYPT
+Decrypting block failed.
+.TP
+.B LIBMPQ_ERROR_UNPACK
+Unpacking block failed.
+.SH SEE ALSO
+.BR libmpq__file_read (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__block_unpacked_size.3 b/contrib/libmpq/doc/man3/libmpq__block_unpacked_size.3
new file mode 100644
index 00000000000..a21ca48159a
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__block_unpacked_size.3
@@ -0,0 +1,59 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__block_unpacked_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t " "block_number",
+.BI " off_t *" "unpacked_size"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__block_unpacked_size\fP() to get the unpacked size of a given block in the file. It will return a valid size for compressed and imploded blocks as well as stored only.
+.LP
+The \fBlibmpq__block_unpacked_size\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file, the third argument \fIblock_number\fP is the number of block and the fourth argument is a reference to the uncompressed, exploded or stored size \fIunpacked_size\fP of block.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File or block does not exist in archive.
+.TP
+.B LIBMPQ_ERROR_OPEN
+Block offset table was not opened by calling \fBlibmpq__block_open_offset\fP(), or it was closed by an \fBlibmpq__block_close_offset\fP() call.
+.SH SEE ALSO
+.BR libmpq__archive_unpacked_size (3),
+.BR libmpq__file_unpacked_size (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_blocks.3 b/contrib/libmpq/doc/man3/libmpq__file_blocks.3
new file mode 100644
index 00000000000..85baeffc603
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_blocks.3
@@ -0,0 +1,54 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_blocks("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t *" "blocks"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_blocks\fP() to get the number of blocks for a given file. It will count all blocks for files stored in multiple sectors or count one for files stored in single sector.
+.LP
+The \fBlibmpq__file_blocks\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file and the third argument is a reference to the number of \fIblocks\fP of the file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__archive_files (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_compressed.3 b/contrib/libmpq/doc/man3/libmpq__file_compressed.3
new file mode 100644
index 00000000000..24b44f0b666
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_compressed.3
@@ -0,0 +1,54 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_compressed("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t *" "compressed"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_compressed\fP() to get the compression status of the given file. It will return true for compressed files and false otherwise.
+.LP
+The \fBlibmpq__file_compressed\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file and the third argument is a reference to the compression status \fIcompressed\fP of the file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__archive_files (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_encrypted.3 b/contrib/libmpq/doc/man3/libmpq__file_encrypted.3
new file mode 100644
index 00000000000..798f4019c7a
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_encrypted.3
@@ -0,0 +1,54 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_encrypted("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t *" "encrypted"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_encrypted\fP() to get the encryption status of the given file. It will return true for encrypted files and false otherwise.
+.LP
+The \fBlibmpq__file_encrypted\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file and the third argument is a reference to the encryption status \fIencrypted\fP of the file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__archive_files (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_imploded.3 b/contrib/libmpq/doc/man3/libmpq__file_imploded.3
new file mode 100644
index 00000000000..9adce38cb5f
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_imploded.3
@@ -0,0 +1,54 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_imploded("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint32_t *" "imploded"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_imploded\fP() to get the implosion status of the given file. It will return true for imploded files and false otherwise.
+.LP
+The \fBlibmpq__file_imploded\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file and the third argument is a reference to the implosion status \fIimploded\fP of the file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__archive_files (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_number.3 b/contrib/libmpq/doc/man3/libmpq__file_number.3
new file mode 100644
index 00000000000..8d7a47769ee
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_number.3
@@ -0,0 +1,52 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_number("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " const char *" "filename",
+.BI " uint32_t *" "number"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_number\fP() to get the number of a given file in the archive. This function will return a file number regardless of a known or opened listfile.
+.LP
+The \fBlibmpq__file_number\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfilename\fP is the name of the file and the third argument is a reference to the \fInumber\fP of the file.
+.SH RETURN VALUE
+On success, the number of the file is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_offset.3 b/contrib/libmpq/doc/man3/libmpq__file_offset.3
new file mode 100644
index 00000000000..392a66d0b04
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_offset.3
@@ -0,0 +1,55 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-15 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_offset("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "offset"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_offset\fP() to get the offset of the file, which is the absolute position in the archive. It also supports archives within archives.
+.LP
+The \fBlibmpq__file_offset\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file and the third argument is a reference to the file starting position \fIoffset\fP in archive.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__archive_offset (3),
+.BR libmpq__block_offset (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_packed_size.3 b/contrib/libmpq/doc/man3/libmpq__file_packed_size.3
new file mode 100644
index 00000000000..b584ddf77dd
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_packed_size.3
@@ -0,0 +1,55 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-15 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_packed_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "packed_size"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_packed_size\fP() to get the packed size of a given file in the archive. It will return a valid size for compressed and imploded files as well as stored only.
+.LP
+The \fBlibmpq__file_packed_size\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file and the third argument is a reference to the compressed, imploded or stored size \fIpacked_size\fP of file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__archive_packed_size (3),
+.BR libmpq__block_packed_size (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_read.3 b/contrib/libmpq/doc/man3/libmpq__file_read.3
new file mode 100644
index 00000000000..cbfafbd0f4f
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_read.3
@@ -0,0 +1,77 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-16 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_read("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " uint8_t *" "out_buf",
+.BI " off_t " "out_size",
+.BI " off_t *" "transferred"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_read\fP() to read a given file into memory. If the file is encrypted it will be first decrypted and then if it is packed (compressed or imploded) it will be unpacked.
+.LP
+The \fBlibmpq__file_read\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the file to extract, the third argument \fIout_buf\fP is the output data buffer which contains the extracted data. The fourth argument \fIout_size\fP is the size of \fIout_buf\fP and the fifth argument is a reference to the \fItransferred\fP bytes of the file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.TP
+.B LIBMPQ_ERROR_OPEN
+Block offset table was not opened by calling \fBlibmpq__block_open_offset\fP(), or it was closed by an \fBlibmpq__block_close_offset\fP() call.
+.TP
+.B LIBMPQ_ERROR_SIZE
+The output buffer is to small.
+.TP
+.B LIBMPQ_ERROR_SEEK
+Seeking in file failed.
+.TP
+.B LIBMPQ_ERROR_MALLOC
+Not enough memory for creating required structures.
+.TP
+.B LIBMPQ_ERROR_READ
+Reading in archive failed.
+.TP
+.B LIBMPQ_ERROR_DECRYPT
+Decrypting file failed.
+.TP
+.B LIBMPQ_ERROR_UNPACK
+Unpacking file failed.
+.SH SEE ALSO
+.BR libmpq__block_read (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__file_unpacked_size.3 b/contrib/libmpq/doc/man3/libmpq__file_unpacked_size.3
new file mode 100644
index 00000000000..a81cf7a4e76
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__file_unpacked_size.3
@@ -0,0 +1,55 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-05-15 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "int32_t libmpq__file_unpacked_size("
+.BI " mpq_archive_s *" "mpq_archive",
+.BI " uint32_t " "file_number",
+.BI " off_t *" "unpacked_size"
+.BI ");"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__file_unpacked_size\fP() to get the unpacked size of a given file in the archive. It will return a valid size for compressed and imploded files as well as stored only.
+.LP
+The \fBlibmpq__file_unpacked_size\fP() function takes as first argument the archive structure \fImpq_archive\fP which have to be allocated first and opened by \fBlibmpq__archive_open\fP(). The second argument \fIfile_number\fP is the number of file and the third argument is a reference to the uncompressed, exploded or stored size \fIunpacked_size\fP of file.
+.SH RETURN VALUE
+On success, a zero is returned and on error one of the following constants.
+.TP
+.B LIBMPQ_ERROR_EXIST
+File does not exist in archive.
+.SH SEE ALSO
+.BR libmpq__archive_unpacked_size (3),
+.BR libmpq__block_unpacked_size (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/doc/man3/libmpq__version.3 b/contrib/libmpq/doc/man3/libmpq__version.3
new file mode 100644
index 00000000000..5500d7314f5
--- /dev/null
+++ b/contrib/libmpq/doc/man3/libmpq__version.3
@@ -0,0 +1,45 @@
+.\" Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.TH libmpq 3 2008-03-31 "The MoPaQ archive library"
+.SH NAME
+libmpq \- cross-platform C library for manipulating mpq archives.
+.SH SYNOPSIS
+.nf
+.B
+#include <mpq.h>
+.sp
+.BI "const char *libmpq__version();"
+.fi
+.SH DESCRIPTION
+.PP
+Call \fBlibmpq__version\fP() to get information about the version of the library, it is useful to create minimum required version verifications.
+.SH RETURN VALUE
+The function returns the library version.
+.SH SEE ALSO
+.BR libmpq (3)
+.SH AUTHOR
+Check documentation.
+.TP
+libmpq is (c) 2003-2008
+.B Maik Broemme <mbroemme@plusserver.de>
+.PP
+The above e-mail address can be used to send bug reports, feedbacks or library enhancements.
diff --git a/contrib/libmpq/libmpq-config.in b/contrib/libmpq/libmpq-config.in
new file mode 100644
index 00000000000..d345efdbe09
--- /dev/null
+++ b/contrib/libmpq/libmpq-config.in
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+exec_prefix_set=no
+
+usage="\
+Usage: libmpq-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]"
+
+if test "$#" -eq "0"; then
+ echo "${usage}" 1>&2
+ exit 1
+fi
+
+while test "$#" -gt "0"; do
+ case "$1" in
+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ case "$1" in
+ --prefix=*)
+ prefix="$optarg"
+ if test "$exec_prefix_set" = "no" ; then
+ exec_prefix="$optarg"
+ fi
+ ;;
+ --prefix)
+ echo "$prefix"
+ ;;
+ --exec-prefix=*)
+ exec_prefix="$optarg"
+ exec_prefix_set=yes
+ ;;
+ --exec-prefix)
+ echo "$exec_prefix"
+ ;;
+ --version)
+ echo "@VERSION@"
+ ;;
+ --cflags)
+ largefile="@LFS_CFLAGS@"
+ includes=-I@includedir@/libmpq
+ echo "$includes $largefile"
+ ;;
+ --libs)
+ libdirs="-L@libdir@"
+ echo "$libdirs -lmpq"
+ ;;
+ *)
+ echo "${usage}" 1>&2
+ exit 1
+ ;;
+ esac
+ shift
+done
+
diff --git a/contrib/libmpq/libmpq.pc.in b/contrib/libmpq/libmpq.pc.in
new file mode 100644
index 00000000000..8c53bea35a0
--- /dev/null
+++ b/contrib/libmpq/libmpq.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libmpq
+Description: GPL version of the libmpq library
+Version: @VERSION@
+Libs: -L${libdir} -lmpq
+Cflags: -I${includedir}/libmpq @LFS_CFLAGS@
diff --git a/contrib/libmpq/libmpq/Makefile.am b/contrib/libmpq/libmpq/Makefile.am
new file mode 100644
index 00000000000..409e3dfe02f
--- /dev/null
+++ b/contrib/libmpq/libmpq/Makefile.am
@@ -0,0 +1,23 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# library information and headers which should not be installed.
+lib_LTLIBRARIES = libmpq.la
+noinst_HEADERS = common.h explode.h extract.h huffman.h mpq-internal.h wave.h
+
+# directory where the include files will be installed.
+libmpq_includedir = $(includedir)/libmpq
+
+# header files to install.
+libmpq_include_HEADERS = mpq.h
+
+libmpq_la_SOURCES = $(GENERAL_SRCS)
+libmpq_la_LDFLAGS = -release $(PACKAGE_VERSION)
+
+GENERAL_SRCS = \
+ common.c \
+ huffman.c \
+ extract.c \
+ explode.c \
+ mpq.c \
+ wave.c
diff --git a/contrib/libmpq/libmpq/common.c b/contrib/libmpq/libmpq/common.c
new file mode 100644
index 00000000000..91b259f5515
--- /dev/null
+++ b/contrib/libmpq/libmpq/common.c
@@ -0,0 +1,222 @@
+/*
+ * common.c -- shared functions used by mpq-tools.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.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 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.
+ */
+
+/* generic includes. */
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#if HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+
+/* libmpq main includes. */
+#include "mpq.h"
+#include "mpq-internal.h"
+
+/* libmpq generic includes. */
+#include "extract.h"
+
+#include "common.h"
+
+/* the global shared decryption buffer. it's a static array compiled into the
+ * library, and can be re-created by compiling and running crypt_buf_gen.c
+ */
+#include "crypt_buf.h"
+
+/* function to return the hash to a given string. */
+uint32_t libmpq__hash_string(const char *key, uint32_t offset) {
+
+ /* some common variables. */
+ uint32_t seed1 = 0x7FED7FED;
+ uint32_t seed2 = 0xEEEEEEEE;
+
+ /* one key character. */
+ uint32_t ch;
+
+ /* prepare seeds. */
+ while (*key != 0) {
+ ch = toupper(*key++);
+ seed1 = crypt_buf[offset + ch] ^ (seed1 + seed2);
+ seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
+ }
+
+ return seed1;
+}
+
+/* function to encrypt a block. */
+int32_t libmpq__encrypt_block(uint32_t *in_buf, uint32_t in_size, uint32_t seed) {
+
+ /* some common variables. */
+ uint32_t seed2 = 0xEEEEEEEE;
+ uint32_t ch;
+
+ /* we're processing the data 4 bytes at a time. */
+ for (; in_size >= 4; in_size -= 4) {
+ seed2 += crypt_buf[0x400 + (seed & 0xFF)];
+ ch = *in_buf ^ (seed + seed2);
+ seed = ((~seed << 0x15) + 0x11111111) | (seed >> 0x0B);
+ seed2 = *in_buf + seed2 + (seed2 << 5) + 3;
+ *in_buf++ = ch;
+ }
+
+ /* if no error was found, return decrypted bytes. */
+ return LIBMPQ_SUCCESS;
+}
+
+
+/* function to decrypt a block. */
+int32_t libmpq__decrypt_block(uint32_t *in_buf, uint32_t in_size, uint32_t seed) {
+
+ /* some common variables. */
+ uint32_t seed2 = 0xEEEEEEEE;
+ uint32_t ch;
+
+ /* we're processing the data 4 bytes at a time. */
+ for (; in_size >= 4; in_size -= 4) {
+ seed2 += crypt_buf[0x400 + (seed & 0xFF)];
+ ch = *in_buf ^ (seed + seed2);
+ seed = ((~seed << 0x15) + 0x11111111) | (seed >> 0x0B);
+ seed2 = ch + seed2 + (seed2 << 5) + 3;
+ *in_buf++ = ch;
+ }
+
+ /* if no error was found, return decrypted bytes. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* function to detect decryption key. */
+int32_t libmpq__decrypt_key(uint8_t *in_buf, uint32_t in_size, uint32_t block_size) {
+
+ /* some common variables. */
+ uint32_t saveseed1;
+
+ /* temp = seed1 + seed2 */
+ uint32_t temp;
+ uint32_t i = 0;
+
+ /* temp = seed1 + buffer[0x400 + (seed1 & 0xFF)] */
+ temp = (*(uint32_t *)in_buf ^ in_size) - 0xEEEEEEEE;
+
+ /* try all 255 possibilities. */
+ for (i = 0; i < 0x100; i++) {
+
+ /* some common variables. */
+ uint32_t seed1;
+ uint32_t seed2 = 0xEEEEEEEE;
+ uint32_t ch;
+ uint32_t ch2;
+
+ /* try the first uint32_t's (we exactly know the value). */
+ seed1 = temp - crypt_buf[0x400 + i];
+ seed2 += crypt_buf[0x400 + (seed1 & 0xFF)];
+ ch = ((uint32_t *)in_buf)[0] ^ (seed1 + seed2);
+
+ if (ch != in_size) {
+ continue;
+ }
+
+ /* add one because we are decrypting block positions. */
+ saveseed1 = seed1 + 1;
+ ch2 = ch;
+
+ /*
+ * if ok, continue and test the second value. we don't know exactly the value,
+ * but we know that the second one has lower 16 bits set to zero (no compressed
+ * block is larger than 0xFFFF bytes)
+ */
+ seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
+ seed2 = ch + seed2 + (seed2 << 5) + 3;
+ seed2 += crypt_buf[0x400 + (seed1 & 0xFF)];
+ ch = ((uint32_t *)in_buf)[1] ^ (seed1 + seed2);
+
+ /* check if we found the file seed. */
+ if ((ch - ch2) <= block_size) {
+
+ /* file seed found, so return it. */
+ return saveseed1;
+ }
+ }
+
+ /* if no file seed was found return with error. */
+ return LIBMPQ_ERROR_DECRYPT;
+}
+
+/* function to decompress or explode a block from mpq archive. */
+int32_t libmpq__decompress_block(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size, uint32_t compression_type) {
+
+ /* some common variables. */
+ int32_t tb = 0;
+
+ /* check if buffer is not compressed. */
+ if (compression_type == LIBMPQ_FLAG_COMPRESS_NONE) {
+
+ /* no compressed data, so copy input buffer to output buffer. */
+ memcpy(out_buf, in_buf, out_size);
+
+ /* store number of bytes copied. */
+ tb = out_size;
+ }
+
+ /* check if one compression mode is used. */
+ else if (compression_type == LIBMPQ_FLAG_COMPRESS_PKZIP ||
+ compression_type == LIBMPQ_FLAG_COMPRESS_MULTI) {
+
+ /* check if block is really compressed, some blocks have set the compression flag, but are not compressed. */
+ if (in_size < out_size) {
+
+ /* check if we are using pkzip compression algorithm. */
+ if (compression_type == LIBMPQ_FLAG_COMPRESS_PKZIP) {
+
+ /* decompress using pkzip. */
+ if ((tb = libmpq__decompress_pkzip(in_buf, in_size, out_buf, out_size)) < 0) {
+
+ /* something on decompression failed. */
+ return tb;
+ }
+ }
+
+ /* check if we are using multiple compression algorithm. */
+ else if (compression_type == LIBMPQ_FLAG_COMPRESS_MULTI) {
+
+ /*
+ * check if it is a file compressed by blizzard's multiple compression, note that storm.dll
+ * version 1.0.9 distributed with warcraft 3 passes the full path name of the opened archive
+ * as the new last parameter.
+ */
+ if ((tb = libmpq__decompress_multi(in_buf, in_size, out_buf, out_size)) < 0) {
+
+ /* something on decompression failed. */
+ return tb;
+ }
+ }
+ } else {
+
+ /* block has set compression flag, but is not compressed, so copy data to output buffer. */
+ memcpy(out_buf, in_buf, out_size);
+
+ /* save the number of transferred bytes. */
+ tb = in_size;
+ }
+ }
+
+ /* if no error was found, return transferred bytes. */
+ return tb;
+}
diff --git a/contrib/libmpq/libmpq/common.h b/contrib/libmpq/libmpq/common.h
new file mode 100644
index 00000000000..12d6008debb
--- /dev/null
+++ b/contrib/libmpq/libmpq/common.h
@@ -0,0 +1,60 @@
+/*
+ * common.h -- header functions used by mpq-tools.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.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 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 _COMMON_H
+#define _COMMON_H
+
+/* function to return the hash to a given string. */
+uint32_t libmpq__hash_string(
+ const char *key,
+ uint32_t offset
+);
+
+/* function to encrypt a block. */
+int32_t libmpq__encrypt_block(
+ uint32_t *in_buf,
+ uint32_t in_size,
+ uint32_t seed
+);
+
+/* function to decrypt a block. */
+int32_t libmpq__decrypt_block(
+ uint32_t *in_buf,
+ uint32_t in_size,
+ uint32_t seed
+);
+
+/* function to detect decryption key. */
+int32_t libmpq__decrypt_key(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint32_t block_size
+);
+
+/* function to decompress or explode block from archive. */
+int32_t libmpq__decompress_block(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size,
+ uint32_t compression_type
+);
+
+#endif /* _COMMON_H */
diff --git a/contrib/libmpq/libmpq/crypt_buf.h b/contrib/libmpq/libmpq/crypt_buf.h
new file mode 100644
index 00000000000..34184b017fe
--- /dev/null
+++ b/contrib/libmpq/libmpq/crypt_buf.h
@@ -0,0 +1,217 @@
+/* DO NOT CHANGE! this file is auto-generated by crypt_buf_gen.c */
+static const uint32_t crypt_buf[0x500] = {
+ 0x55c636e2, 0x02be0170, 0x584b71d4, 0x2984f00e, 0xb682c809, 0x91cf876b,
+ 0x775a9c24, 0x597d5ca5, 0x5a1afeb2, 0xd3e9ce0d, 0x32cdcdf8, 0xb18201cd,
+ 0x3cce05ce, 0xa55d13be, 0xbb0afe71, 0x9376ab33, 0x848f645e, 0x87e45a45,
+ 0x45b86017, 0x5e656ca8, 0x1b851a95, 0x2542dbd7, 0xab4df9e4, 0x5976ae9b,
+ 0x6c317e7d, 0xcddd2f94, 0x3c3c13e5, 0x335b1371, 0x31a592ca, 0x51e4fc4c,
+ 0xf7db5b2f, 0x8abdbe41, 0x8beaa674, 0x20d6b319, 0xde6c9a9d, 0xc5ac84e5,
+ 0x445a5feb, 0x94958cb0, 0x1e7d3847, 0xf35d29b0, 0xca5cceda, 0xb732c8b5,
+ 0xfdcc41dd, 0x0edcec16, 0x9d01feae, 0x1165d38e, 0x9ee193c8, 0xbf33b13c,
+ 0x61bc0dfc, 0xef3e7be9, 0xf8d4d4c5, 0xc79b7694, 0x5a255943, 0x0b3dd20a,
+ 0x9d1ab5a3, 0xcfa8ba57, 0x5e6d7069, 0xcb89b731, 0x3dc0d15b, 0x0d4d7e7e,
+ 0x97e37f2b, 0xfefc2bb1, 0xf95b16b5, 0x27a55b93, 0x45f22729, 0x4c986630,
+ 0x7c666862, 0x5fa40847, 0xa3f16205, 0x791b7764, 0x386b36d6, 0x6e6c3fef,
+ 0xc75855db, 0x4abc7dc7, 0x4a328f9b, 0xcef20c0f, 0x60b88f07, 0xf7bb4b8f,
+ 0x830b5192, 0x94f711ec, 0x20250752, 0x399d21a3, 0xe5c0840d, 0xe76cffa5,
+ 0x624fab29, 0x5df133e6, 0x83e0b9b8, 0xc5796bfb, 0x4a7ab2d0, 0xba59a821,
+ 0x03a81e4c, 0xcd3adfdb, 0x32b26b8c, 0x8e35c533, 0x9e6300e9, 0x8cf92ac5,
+ 0x880d18eb, 0x131a53b3, 0x2ed2dc64, 0xb23257c1, 0xa06450c1, 0x1b92cb8e,
+ 0x72ed730e, 0x19a685f0, 0x82836483, 0x42d94e8a, 0xee9bd6f6, 0x556d0b6a,
+ 0xba65589a, 0xde24cce4, 0x53329f6c, 0xc754fe8b, 0x503d2dc7, 0x10027ba4,
+ 0xd3b60a8b, 0x68e68d83, 0x0a9128a9, 0x595fa35f, 0x0b03b5be, 0x150a45c4,
+ 0xb1629cce, 0xe5f7497b, 0x8a7098a4, 0xb8233e69, 0x8ea0f978, 0x5b579970,
+ 0xeab14318, 0x4b28b263, 0xb6766cef, 0x06782877, 0x155c6dd0, 0xc711333c,
+ 0xf819cedf, 0x00eb1d68, 0xd6fffa6e, 0x439e5962, 0xd765d6db, 0xcb0bcee9,
+ 0x6d3c5647, 0x965466f3, 0x0ca983c9, 0x74ecc1ce, 0xfc0563b6, 0x42b08fee,
+ 0xc5b38853, 0xfe502ceb, 0x7b432faf, 0xc309e610, 0x2c3997d8, 0x43774654,
+ 0x15bd9d2c, 0xed6a420d, 0xc7ff520c, 0xb8a97fd1, 0x5e4d60cc, 0xb9738d11,
+ 0xda2181ff, 0x73ac2597, 0x3a8eec8d, 0xac85e779, 0xf3f975d6, 0xb9fe7b91,
+ 0x0f155d1e, 0x2860b6dd, 0x835977cb, 0xb0607436, 0x9cab7f6b, 0x8ab91186,
+ 0xc12b51e9, 0x20084e8b, 0x44ba8ead, 0xa542b130, 0x82bcd5c4, 0xcc747f4e,
+ 0x0f1909d8, 0xda242e1c, 0x6f7d1aa0, 0xd2626486, 0x88d0781e, 0xab695ccd,
+ 0xfa569145, 0xb4feb55c, 0xbe47e896, 0xe70a7a88, 0xd56185a2, 0xacf4c871,
+ 0x09282332, 0x1ddeeaa8, 0x590c7adb, 0xf4a97667, 0xbfd85705, 0x0ea77ccc,
+ 0xa9f85364, 0x83195869, 0x8bfb041a, 0xdb842f5c, 0xd6f0f315, 0xa7756ea7,
+ 0x0a51b439, 0xa9edf8a3, 0xd9084e2f, 0x827407f8, 0xd4ac8284, 0x09739d0d,
+ 0xb3bb6cfc, 0xd539c77d, 0x6bbc9ac0, 0x35c641aa, 0x934c96b0, 0xd17af317,
+ 0x29c6baef, 0xb275cdac, 0xd72662de, 0x9f5c2544, 0xc1a98f75, 0xd98e8f9a,
+ 0x47bd5c86, 0x70c610a6, 0xb5482ed4, 0x23b9c68c, 0x3c1bae66, 0x69556e7f,
+ 0xd902f5e0, 0x653d195b, 0xde6541fb, 0x07bcc6ac, 0xc6ee7788, 0x801534d4,
+ 0x2c1f35c0, 0xd9de614d, 0xbdccac85, 0xb4d4a0da, 0x242d549b, 0x9d964796,
+ 0xb9ceb982, 0x59fa99a9, 0xd8986cc1, 0x9e90c1a1, 0x01bbd82f, 0xd7f1c5fd,
+ 0xdd847eba, 0x883d305d, 0x25f13152, 0x4a92694d, 0x77f1e601, 0x8024e6e7,
+ 0x02a5f53d, 0x9c3ef4d9, 0xaf403ccc, 0xe2ad03c0, 0x46edf6ec, 0x6f9bd3e6,
+ 0xcc24ad7a, 0x47afab12, 0x82298df7, 0x708c9eec, 0x76f8c1b1, 0xb39459d2,
+ 0x3f1e26d9, 0xe1811be7, 0x56ed1c4d, 0xc9d18af8, 0xe828060e, 0x91cada2e,
+ 0x5ccbf9b7, 0xf1a552d4, 0x3c9d4343, 0xe1008785, 0x2adfeebf, 0xf90240a0,
+ 0x3d08cce7, 0x426e6fb0, 0x573c984f, 0x13a843ae, 0x406b7439, 0x636085d9,
+ 0x5000ba9a, 0xad4a47ab, 0xaf001d8d, 0x419907ae, 0x185c8f96, 0xe5e9ed4d,
+ 0x61764133, 0xd3703d97, 0xac98f0c6, 0xdbc3a37c, 0x85f010c4, 0x90491e32,
+ 0xf12e18bf, 0xc88c96e1, 0xd3fbd6d9, 0xe3c28b08, 0xd5bf08cc, 0xb1e78859,
+ 0x2546ddcf, 0xb030b200, 0xaafd2811, 0x55b22d21, 0xd38bf567, 0x469c7a2b,
+ 0x5ad05792, 0xa1a5981e, 0x7dfb8384, 0x34d1ca0a, 0x7eb0dbe0, 0xd61ce0f6,
+ 0x398068b7, 0xe6406d1f, 0x95ae6b47, 0xe4281230, 0xb0843061, 0xa70a3a68,
+ 0xe340f625, 0x72dcbffd, 0x8eb8afcd, 0x18b6661f, 0x17ef5a5c, 0x000c5b22,
+ 0x6ba13836, 0x6165e383, 0x74481c5b, 0xe56f0711, 0xa26f5024, 0x5ff22e60,
+ 0x31a5e829, 0xa1094bf0, 0xc680ec6c, 0x8cf327d7, 0xebf1348a, 0x6a227d2f,
+ 0x74065184, 0x8df65112, 0x2bbd05ee, 0xe4d00ed6, 0x2980ee1a, 0x6ae1da73,
+ 0xe84614da, 0x6c9906ab, 0xcf8e02db, 0xd3723e97, 0x92f66caf, 0xac8491c7,
+ 0xaec65696, 0xb98997cf, 0xfa16c762, 0x6d73c65f, 0x205d22a6, 0x4dd3aaa5,
+ 0x2deb6bc0, 0x9f37686c, 0x71a5282b, 0x376bb9e0, 0x7fff2a1b, 0xde67982f,
+ 0x9cbf33ce, 0x2e6dab37, 0x6e3424b9, 0x0ee143bc, 0x832a60d9, 0xbb6329e1,
+ 0x13f6befd, 0x5965fb84, 0xf60b233c, 0x3d695183, 0x433224a1, 0xb5d9cae5,
+ 0x82459bab, 0x9f21b311, 0xaf6c5247, 0xb447b13a, 0x7b2676c3, 0xc38979cd,
+ 0x8526ae25, 0xc550ad5b, 0x685099a7, 0x65e9c2bd, 0xe5c6dc36, 0xe10b37a9,
+ 0x88016878, 0xce81d4e4, 0x24d6fc80, 0x4106152d, 0x6d4f5f90, 0xc4dc74be,
+ 0xdb48676c, 0x6cb569b7, 0xf3bf598f, 0x042b08d9, 0x02ccb2de, 0xb1056f65,
+ 0x47994af4, 0xfa141ba4, 0x9376ab2e, 0x07a76737, 0x75e7e6fc, 0x449d80a1,
+ 0x03b7259d, 0xf6df358a, 0x5a75d5b9, 0x47286923, 0x3b1a30ef, 0xeebe3d6a,
+ 0x9db1aa00, 0x007a90d9, 0x24667071, 0x019c73cf, 0x69039bcd, 0x95900744,
+ 0x6518b1eb, 0x6905f202, 0xee3951b2, 0xe141fca9, 0x797fa832, 0x5a95e55b,
+ 0xd6263b15, 0x5b61f394, 0x897acb1c, 0x005f83a9, 0x22420f71, 0xf495176e,
+ 0x7e138f3d, 0x1392e384, 0x373bf7aa, 0x8e512816, 0xa960b3ca, 0x0474d74c,
+ 0xffacd6d7, 0x2ef5ed9e, 0x60992aaa, 0x7e690e99, 0x23c0749d, 0xd8e29105,
+ 0x555d5909, 0x15631bfe, 0xa69c5a1c, 0x501017ca, 0x99438048, 0x38733ac7,
+ 0xe682e2c8, 0xd4655fd6, 0x956e4c04, 0x347df643, 0x2f4b177b, 0x93ed3aa4,
+ 0xa77e1dd5, 0x7ae55702, 0xd2a52fd9, 0xef8ba18c, 0xb7d3c1ee, 0x8078ba8d,
+ 0xab5aaadb, 0x752be08f, 0x068b31c1, 0x078aae3c, 0xaa5a8343, 0x123d9268,
+ 0x2ceaee43, 0x8ebdb239, 0x650251f3, 0x04883648, 0x8c62e12e, 0x12b32167,
+ 0xe5112e9a, 0x10002548, 0x3e7a818d, 0x077e5327, 0xf140cc21, 0x6ce7d75d,
+ 0x9b99f9a5, 0x3215741c, 0xb6aadbae, 0x738768dc, 0x82a3742f, 0x76517020,
+ 0xdd872ad8, 0x9d0902b2, 0x7d1a6b04, 0x49381592, 0x63a652a5, 0x0c15e626,
+ 0xe22f70d6, 0x01e84385, 0xb29de134, 0x20c5000e, 0xe961f443, 0x2d31662e,
+ 0x3ce6bc28, 0x34f9dd94, 0xfa45de53, 0x497588bd, 0x9468215b, 0x0777fa5c,
+ 0x6f7114c0, 0xe0e82694, 0xe4371986, 0x57112de2, 0xe0cac289, 0xf2a3cee0,
+ 0x6a41e1b9, 0xbfcea77d, 0xf927fd52, 0x69747d98, 0xbea76cdb, 0x8dd39557,
+ 0x04db5ece, 0x2a0885c8, 0x3be4e8ee, 0x21d785dc, 0x09de7c0e, 0x3258ea33,
+ 0x51922982, 0xee8dd024, 0x3df6965d, 0x30c1237b, 0xf7f6686a, 0x9faca186,
+ 0x7c400076, 0x85acef8a, 0xf4b6d220, 0xddc3481c, 0x439eaec4, 0x717bbe63,
+ 0x8259faa7, 0xd682bd68, 0x932a8610, 0x38bf0a7f, 0x6212e2c7, 0x88ee3168,
+ 0xb3c27047, 0x6133cb1e, 0x15295506, 0x5ae66246, 0x1d208ddd, 0xa91d3dba,
+ 0xc315968d, 0x6aa2664b, 0x716d0cca, 0x891f4956, 0x80866bff, 0xbd56c847,
+ 0x9093425a, 0x28dd9e87, 0x84ef3e08, 0x690a49d6, 0x6a7eff82, 0xabcfe400,
+ 0x3d3be5ca, 0x381b650c, 0x4b7c8622, 0x3e0246f3, 0xa3561654, 0x9488865c,
+ 0x3aef1bf2, 0x5e5d68a2, 0xd32f1ddc, 0x51972bf0, 0x177a213b, 0x469375c2,
+ 0x37640bd0, 0xfc3324c8, 0x07091a09, 0x2d63d3fb, 0x2153f023, 0x48223875,
+ 0x61a55826, 0x8c136538, 0x49f71d98, 0x84c7d51e, 0x85551a73, 0x13d604c5,
+ 0xd701a626, 0x87b844ca, 0x741eb29d, 0x2a2c977c, 0xc797ca03, 0x6c4085d7,
+ 0x2dacf79b, 0x734fa2eb, 0xcc290557, 0xfa1e75e4, 0x06b29a27, 0xbece2a7a,
+ 0x70a4554b, 0xc935942e, 0xa764bbc1, 0x1fe391d6, 0x7807f0c2, 0x40606ed9,
+ 0xe5153086, 0xe91d7dd2, 0xed5d3ba9, 0xaa14b64a, 0x83b24dd9, 0xec1ff5cd,
+ 0xba33ead3, 0xe4ef735c, 0xbc062438, 0xd8bfd523, 0x473d1e04, 0x2007f8a7,
+ 0xb02903ed, 0x86ea8ada, 0x95ab69cf, 0xfd1f9809, 0x9cb3d8bb, 0x51f45958,
+ 0x9cdd4276, 0xc245865e, 0x8f0c836b, 0x4ee7dc07, 0xf6368d9d, 0xef2c1dc1,
+ 0xee56b54b, 0xbd62ce2f, 0xf4916aad, 0xc81cb594, 0x41729f49, 0x24bef0a4,
+ 0xdef487a9, 0x222e05b8, 0x8d3bf5c6, 0x11b55009, 0xad09d2b3, 0x19db9fd1,
+ 0xd7427085, 0x33dbfc8b, 0x526b9378, 0x790e1bc8, 0xb2998a00, 0xa5641703,
+ 0x0676d249, 0x6b9185cc, 0x30e4348f, 0x82c52f65, 0x57c7dc24, 0x489c1ecd,
+ 0x9fcab02a, 0x56d61117, 0xfe869cac, 0x55fc5140, 0x7fbbb382, 0x9e5afc79,
+ 0x10047c99, 0xfc9f5984, 0x56587e2d, 0xb98193f0, 0x98fe5e8e, 0x29b15b6b,
+ 0x9561f055, 0xbb0caa25, 0x1e4ecc15, 0x23f5393b, 0x0845b458, 0xceff67ca,
+ 0xb099900c, 0x00b1564f, 0x39eef3d1, 0xfcc1bf84, 0xac8893b5, 0x6484bf0e,
+ 0x91c02ab3, 0x8c0c0c70, 0x686fa8c6, 0xe171bed6, 0xdfae37df, 0xd5a1a4e7,
+ 0xe3eb49a1, 0x5e6014e0, 0x205b21ac, 0xfd58b3da, 0x2e7c07cd, 0xef2cc85a,
+ 0xd7587b46, 0xf417847d, 0x8a30cec1, 0x70984f6c, 0xf0b63388, 0xc220c98d,
+ 0xede62936, 0x92c0a7b3, 0x1ef371e8, 0x2005f7af, 0x91a47265, 0xb0cf5504,
+ 0xd500aba8, 0xcb5c4bd3, 0x9b3bcbc3, 0xcf6644b5, 0xce9488ef, 0x003fc96e,
+ 0xaa42222f, 0x4844f3d0, 0x4db89d77, 0x08681aae, 0x662f3a28, 0x761552db,
+ 0x1df7a17a, 0x93feed9a, 0xcc496a4f, 0xa217cfcd, 0x3ba3c930, 0x268f7e77,
+ 0x0797b4a1, 0x8bebfc51, 0x068930c4, 0x16c874e2, 0xc242da24, 0xfb229f76,
+ 0xa0795b02, 0x689fc036, 0x17a73732, 0xd21aec00, 0xac00a692, 0x5b217f18,
+ 0xae421624, 0x2bc05cc0, 0x48c1db7a, 0x4f4e63b4, 0x1667f04e, 0x34020f94,
+ 0x972b2555, 0x9a07355b, 0x01665970, 0x7db60c6f, 0x3ad7103b, 0x5c3d09c0,
+ 0xeea3dada, 0x88c21c10, 0x102436d7, 0x6a3b3400, 0xeb523c4c, 0xfb97d896,
+ 0x964cb86b, 0xdd878038, 0x0529da4d, 0x0b1468a5, 0x18739ac8, 0xf7f26668,
+ 0xf64f4471, 0x5c14f5c3, 0x44a081fb, 0x39ac7e37, 0x8a17c26b, 0x868f5e67,
+ 0x3931978d, 0x6edf7817, 0x4951cc67, 0x943407f3, 0xcc5e748f, 0x2b7ee729,
+ 0xcbb320f0, 0x11fec8e7, 0xfccfc658, 0x03454354, 0x373aa1ec, 0x1d58fe9a,
+ 0x064710ae, 0xa88aa0ba, 0xd183a23e, 0x40d150a3, 0xf531b8d1, 0xa7d99f85,
+ 0x11838cd5, 0xb19e64b3, 0x3d67a5e9, 0xb02c5ac6, 0x99b9b9e8, 0x4c202b7a,
+ 0x15f261d3, 0xa84c2d0d, 0x50f185a6, 0x33ba41d5, 0x39791013, 0x4baff44e,
+ 0xeeeeaa1c, 0xe0488314, 0x559ccd2b, 0xa104f445, 0x636f37c4, 0x264d5e3b,
+ 0x75c17f35, 0x75424131, 0xbb115739, 0x74fe755a, 0x7d3a7aa6, 0x2d8be784,
+ 0x83ed154a, 0xfc2673d8, 0x44dd4a7f, 0x79056cc8, 0x82cc8831, 0x9d3c1b7c,
+ 0xe9453bfa, 0x24315694, 0x661f3253, 0x75549f5c, 0xbb2b63ed, 0x67e00d96,
+ 0xf48966c7, 0x0d7bea56, 0xc25f92ef, 0xa947a79d, 0xde4adf6f, 0xac0f0342,
+ 0xd3eb246b, 0xa4aa118e, 0x3c3e6a46, 0x457f4441, 0xa50a406f, 0x6c508d9f,
+ 0xe9ac18e7, 0x1ecdb4ba, 0x39ac7e3a, 0x7fb304fa, 0x6f38f8e8, 0x4aecea6d,
+ 0x61035e73, 0x81708907, 0xebc07205, 0x90fd7614, 0xb52d217f, 0x6c4de195,
+ 0x1dd49084, 0x64ee482c, 0x94c7a521, 0x540c09d8, 0x75df8dd5, 0x414131f7,
+ 0x3698fd76, 0xf784db4f, 0xf8c97a03, 0x048f39b9, 0x3bf4f0bd, 0x8cb50992,
+ 0x9b58d9ee, 0xe5ab79cc, 0x9a5f6052, 0xbd9591b0, 0xfad2232b, 0x5a632254,
+ 0x0286e618, 0x8ad3c8f7, 0xe4060176, 0x754c4617, 0x5c10490b, 0x6f7d6fff,
+ 0x2187b42a, 0x5775095b, 0x02f4c663, 0x5a5dca06, 0xfe4ad4c7, 0x53e19f7d,
+ 0x59ff46b5, 0xbcc42ba5, 0xfd2f4a97, 0xbed6d905, 0x95629b6b, 0x21a1c0db,
+ 0xaa10b45d, 0xe6ef6d58, 0x2892cf4d, 0x9fed6c10, 0x1e386bf7, 0x9be0c6e8,
+ 0x2b2f15ef, 0x19f5ac7b, 0x7aff0e72, 0x31da576f, 0x30252cb4, 0x577960ac,
+ 0x166e9e5a, 0xa9374a61, 0x71369c96, 0x7ff826ae, 0xe8175326, 0xcabbfd33,
+ 0x0191190e, 0x699d3c3e, 0x36b40b22, 0xb3950513, 0x9b889bfa, 0xa52a5007,
+ 0xac290fed, 0x3b4e4a4f, 0xb753d8d6, 0x3c531f22, 0x582f6427, 0xa9cd93a9,
+ 0x546e39ae, 0x242faad2, 0xd2e0f747, 0x09f6325d, 0x59d48719, 0xad7eb66e,
+ 0xd5512878, 0x56debf9d, 0x5107e5a5, 0xf1c00aa4, 0x814ccca8, 0x600d90f0,
+ 0x9be97619, 0x915fa5f2, 0x2b5628dd, 0xa33d5f5a, 0x595df7c1, 0x6966215d,
+ 0x50ec8337, 0xf1d21372, 0x0ee2eefb, 0xad9e70b7, 0xab0d2fe4, 0xcf277b5d,
+ 0x62585a2c, 0x835a7844, 0x74b1fa6b, 0x49baffd5, 0x2ea9c864, 0x129311a8,
+ 0xbdfa1867, 0x83ca5997, 0x9d1db719, 0x84bb79e6, 0x9e3f99f2, 0x313f6101,
+ 0x1b99245b, 0xd15d8fb2, 0xcef90f81, 0x2945268d, 0xdbbcf573, 0xb1021886,
+ 0x9ee7ec1d, 0x1cf824f7, 0x7eaa2e32, 0x69c0a2b5, 0x7494419c, 0xe253d7d3,
+ 0x48da3d12, 0x45b8b571, 0xdb4d147a, 0xd82d8dde, 0x265d10a2, 0xb0a6eb9a,
+ 0x7e1c93a6, 0x36fe2f46, 0xdcad6b00, 0x05439191, 0xb0ce5484, 0x61d1c309,
+ 0x8da62a03, 0x06d0fe2f, 0xbac6dd3c, 0xca2006f3, 0x8321b1af, 0x0411a6f3,
+ 0xe8918eac, 0x21a2c152, 0x91c0d54f, 0x6aaa14fa, 0xdd22a440, 0x88cb2075,
+ 0x7a4eb813, 0x67afa071, 0xd8d98c9c, 0x31f10d47, 0x6ff1a8a8, 0x2faaf0a1,
+ 0x48a221bb, 0x3be6948b, 0xaa79e79b, 0x0ea7278c, 0x7a3857ef, 0x49b7fe55,
+ 0xd51cb931, 0x041c018d, 0x00b90501, 0x45ea7881, 0x8fc1dbcf, 0xb80b32a9,
+ 0xabacd2e9, 0x677bdc40, 0xecace542, 0x6d6514eb, 0x31c09ff7, 0x5e6c1abd,
+ 0x1c391d0f, 0x0e9d77f1, 0x7119392d, 0x6be9b0ba, 0x6194fa77, 0x45e62148,
+ 0x42234af2, 0xc3239d66, 0x939cbdbc, 0x56200d9c, 0x6b275208, 0x001a61f3,
+ 0xccc2a546, 0x4b722be0, 0xee25f2b7, 0x6d86cf9e, 0xaa6be0cd, 0x4dcda7b6,
+ 0x78d4aa13, 0x36ea7ad9, 0x3f29d700, 0xdeea2d84, 0x6a6af5bd, 0x18afb81c,
+ 0xd8e4e73c, 0x8aa708ba, 0x658b94d9, 0xa676478c, 0xcfa10c22, 0x25593c74,
+ 0x8d962235, 0x5f980270, 0x3df6ebc0, 0x8e7d92fa, 0xc3ee55e1, 0xd5f72447,
+ 0x02b0fa95, 0x52b0b520, 0x70d2c11f, 0x3a6fdd6c, 0x193aa698, 0x5496f7d5,
+ 0x4208931b, 0x7a4106ec, 0x83e86840, 0xf49b6f8c, 0xba3d9a51, 0x55f54ddd,
+ 0x2de51372, 0x9afb571b, 0x3ab35406, 0xad64ff1f, 0xc77764fe, 0x7f864466,
+ 0x416d9cd4, 0xa2489278, 0xe30b86e4, 0x0b5231b6, 0xba67aed6, 0xe5ab2467,
+ 0x60028b90, 0x1d9e20c6, 0x2a7c692a, 0x6b691cdb, 0x9e51f817, 0x9b763dec,
+ 0x3d29323f, 0xcfe12b68, 0x754b459b, 0xa2238047, 0xd9c55514, 0x6bdcffc1,
+ 0x693e6340, 0x82383fe7, 0x1916ea5f, 0xec7bcd59, 0x72de165a, 0xe79a1617,
+ 0x8ec86234, 0xa8f0d284, 0x20c90226, 0x7bf98884, 0x28a58331, 0x3ec3fa6e,
+ 0x4ce0895b, 0xc353b4d0, 0x33ef064f, 0x21e5e210, 0xc8bb589d, 0xe85dcab2,
+ 0xac65829f, 0xa7bf92d0, 0x05a6174d, 0x25a50c2e, 0xe5c78777, 0x3d75021f,
+ 0x4baa9c98, 0x23bdc884, 0x9653bbd7, 0xbadce7f5, 0xc283a484, 0xc040df2e,
+ 0x9370a841, 0x2f316022, 0x36eed231, 0xac2cbc0c, 0x13c0a49b, 0xcdd12997,
+ 0x07fe91b2, 0xcd7eabcd, 0x2c01271d, 0x18432df8, 0x599c6bc7, 0x75e93d5a,
+ 0xb67a6ee2, 0x8e738e16, 0xff9073fd, 0xaf77026a, 0xf86ea2fc, 0x91509ea3,
+ 0x33a78dc6, 0x4f79234a, 0x3a7535bc, 0x3539fcb1, 0x3103ee52, 0x4f6f1e69,
+ 0x6bb3ebbc, 0x4cb77555, 0x8dd1e999, 0x2ade439d, 0x11521fae, 0xb94d2545,
+ 0x8dde9abd, 0x1909393f, 0xb792a23d, 0x749c455b, 0xb5b60f2c, 0x380459ce,
+ 0x0dad5820, 0xb130845b, 0x291cbd52, 0xde9a5bb7, 0x51def961, 0x515b6408,
+ 0xca6e823e, 0x382e6e74, 0xeebe3d71, 0x4c8f0c6a, 0xe676dcea, 0x14e1dc7c,
+ 0x6f7fc634, 0xcf85a943, 0xd39ea96e, 0x136e7c93, 0x7164b304, 0xf32f1333,
+ 0x35c34034, 0xde39d721, 0x91a87439, 0xc410111f, 0x29f17aac, 0x1316a6ff,
+ 0x12f194ee, 0x420b9499, 0xf72db0dc, 0x690b9f93, 0x17d14bb2, 0x8f931ab8,
+ 0x217500bc, 0x875413f8, 0x98b2e43d, 0xc51f9571, 0x54cebdca, 0x0719cc79,
+ 0xf3c7080d, 0xe4286771, 0xa3eab3cd, 0x4a6b00e0, 0x11cf0759, 0x7e897379,
+ 0x5b32876c, 0x5e8cd4f6, 0x0cedfa64, 0x919ac2c7, 0xb214f3b3, 0x0e89c38c,
+ 0xf0c43a39, 0xeae10522, 0x835bce06, 0x9eec43c2, 0xea26a9d6, 0x69531821,
+ 0x6725b24a, 0xda81b0e2, 0xd5b4ae33, 0x080f99fb, 0x15a83daf, 0x29dfc720,
+ 0x91e1900f, 0x28163d58, 0x83d107a2, 0x4eac149a, 0x9f71da18, 0x61d5c4fa,
+ 0xe3ab2a5f, 0xc7b0d63f, 0xb3cc752a, 0x61ebcfb6, 0x26ffb52a, 0xed789e3f,
+ 0xaa3bc958, 0x455a8788, 0xc9c082a9, 0x0a1bef0e, 0xc29a5a7e, 0x150d4735,
+ 0x943809e0, 0x69215510, 0xef0b0da9, 0x3b4e9fb3, 0xd8b5d04c, 0xc7a023a8,
+ 0xb0d50288, 0x64821375, 0xc260e8cf, 0x8496bd2c, 0xff4f5435, 0x0fb5560c,
+ 0x7cd74a52, 0x93589c80, 0x88975c47, 0x83bda89d, 0x8bcc4296, 0x01b82c21,
+ 0xfd821dbf, 0x26520b47, 0x04983e19, 0xd3e1ca27, 0x782c580f, 0x326ff573,
+ 0xc157bcc7, 0x4f5e6b84, 0x44ebfbfb, 0xda26d9d8, 0x6cd9d08e, 0x1719f1d8,
+ 0x715c0487, 0x2c2d3c92, 0x53faaba9, 0xbc836146, 0x510c92d6, 0xe089f82a,
+ 0x4680171f, 0x369f00de, 0x70ec2331, 0x0e253d55, 0xdafb9717, 0xe5dd922d,
+ 0x95915d21, 0xa0202f96, 0xa161cc47, 0xeacfa6f1, 0xed5e9189, 0xdab87684,
+ 0xa4b76d4a, 0xfa704897, 0x631f10ba, 0xd39da8f9, 0x5db4c0e4, 0x16fde42a,
+ 0x2dff7580, 0xb56fec7e, 0xc3ffb370, 0x8e6f36bc, 0x6097d459, 0x514d5d36,
+ 0xa5a737e2, 0x3977b9b3, 0xfd31a0ca, 0x903368db, 0xe8370d61, 0x98109520,
+ 0xade23cac, 0x99f82e04, 0x41de7ea3, 0x84a1c295, 0x09191be0, 0x30930d02,
+ 0x1c9fa44a, 0xc406b6d7, 0xeedca152, 0x6149809c, 0xb0099ef4, 0xc5f653a5,
+ 0x4c10790d, 0x7303286c
+};
diff --git a/contrib/libmpq/libmpq/explode.c b/contrib/libmpq/libmpq/explode.c
new file mode 100644
index 00000000000..2d778d25c39
--- /dev/null
+++ b/contrib/libmpq/libmpq/explode.c
@@ -0,0 +1,602 @@
+/*
+ * explode.c -- explode function of pkware data compression library.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+ *
+ * This source was adepted from the C++ version of pkware.cpp included
+ * in stormlib. The C++ version belongs to the following authors:
+ *
+ * Ladislav Zezula <ladik@zezula.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* generic includes. */
+#include <string.h>
+
+/* libmpq main includes. */
+#include "mpq.h"
+
+/* libmpq generic includes. */
+#include "explode.h"
+
+/* tables used for data extraction. */
+static const uint8_t pkzip_dist_bits[] = {
+ 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
+};
+
+/* tables used for data extraction. */
+static const uint8_t pkzip_dist_code[] = {
+ 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
+ 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
+ 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
+ 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
+};
+
+/* tables used for data extraction. */
+static const uint8_t pkzip_clen_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
+};
+
+/* tables used for data extraction. */
+static const uint16_t pkzip_len_base[] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
+};
+
+/* tables used for data extraction. */
+static const uint8_t pkzip_slen_bits[] = {
+ 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
+};
+
+/* tables used for data extraction. */
+static const uint8_t pkzip_len_code[] = {
+ 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
+};
+
+/* tables used for data extraction. */
+static const uint8_t pkzip_bits_asc[] = {
+ 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
+ 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
+ 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
+ 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
+ 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
+ 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
+ 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
+};
+
+/* tables used for data extraction. */
+static const uint16_t pkzip_code_asc[] = {
+ 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
+ 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
+ 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
+ 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
+ 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
+ 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
+ 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
+ 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
+ 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
+ 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
+ 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
+ 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
+ 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
+ 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
+ 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
+ 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
+ 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
+ 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
+ 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
+ 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
+ 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
+ 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
+ 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
+ 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
+ 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
+ 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
+ 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
+ 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
+ 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
+ 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
+ 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
+ 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
+};
+
+/* local unused variables. */
+char pkware_copyright[] = "PKWARE Data Compression Library for Win32\r\n"
+ "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
+ "Patent No. 5,051,745\r\n"
+ "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
+ "Version 1.11\r\n";
+
+/* skips given number of bits. */
+static int32_t skip_bit(pkzip_cmp_s *mpq_pkzip, uint32_t bits) {
+
+ /* check if number of bits required is less than number of bits in the buffer. */
+ if (bits <= mpq_pkzip->extra_bits) {
+ mpq_pkzip->extra_bits -= bits;
+ mpq_pkzip->bit_buf >>= bits;
+ return 0;
+ }
+
+ /* load input buffer if necessary. */
+ mpq_pkzip->bit_buf >>= mpq_pkzip->extra_bits;
+ if (mpq_pkzip->in_pos == mpq_pkzip->in_bytes) {
+ mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf);
+ if ((mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param)) == 0) {
+ return 1;
+ }
+ mpq_pkzip->in_pos = 0;
+ }
+
+ /* update bit buffer. */
+ mpq_pkzip->bit_buf |= (mpq_pkzip->in_buf[mpq_pkzip->in_pos++] << 8);
+ mpq_pkzip->bit_buf >>= (bits - mpq_pkzip->extra_bits);
+ mpq_pkzip->extra_bits = (mpq_pkzip->extra_bits - bits) + 8;
+
+ /* if no error was found, return zero. */
+ return 0;
+}
+
+/* this function generate the decode tables used for decryption. */
+static void generate_tables_decode(int32_t count, uint8_t *bits, const uint8_t *code, uint8_t *buf2) {
+
+ /* some common variables. */
+ int32_t i;
+
+ /* EBX - count */
+ for (i = count-1; i >= 0; i--) {
+
+ /* some common variables. */
+ uint32_t idx1 = code[i];
+ uint32_t idx2 = 1 << bits[i];
+
+ /* loop until table is ready. */
+ do {
+ buf2[idx1] = (uint8_t)i;
+ idx1 += idx2;
+ } while (idx1 < 0x100);
+ }
+}
+
+/* this function generate the tables for ascii decompression. */
+static void generate_tables_ascii(pkzip_cmp_s *mpq_pkzip) {
+
+ /* some common variables. */
+ const uint16_t *code_asc = &pkzip_code_asc[0xFF];
+ uint32_t acc;
+ uint32_t add;
+ uint16_t count;
+
+ /* loop through ascii table. */
+ for (count = 0x00FF; code_asc >= pkzip_code_asc; code_asc--, count--) {
+ uint8_t *bits_asc = mpq_pkzip->bits_asc + count;
+ uint8_t bits_tmp = *bits_asc;
+
+ /* check if byte is finished. */
+ if (bits_tmp <= 8) {
+ add = (1 << bits_tmp);
+ acc = *code_asc;
+ do {
+ mpq_pkzip->offs_2c34[acc] = (uint8_t)count;
+ acc += add;
+ } while (acc < 0x100);
+ } else {
+ if ((acc = (*code_asc & 0xFF)) != 0) {
+ mpq_pkzip->offs_2c34[acc] = 0xFF;
+ if (*code_asc & 0x3F) {
+
+ /* decrease bit by four. */
+ bits_tmp -= 4;
+ *bits_asc = bits_tmp;
+ add = (1 << bits_tmp);
+ acc = *code_asc >> 4;
+ do {
+ mpq_pkzip->offs_2d34[acc] = (uint8_t)count;
+ acc += add;
+ } while (acc < 0x100);
+ } else {
+
+ /* decrease bit by six. */
+ bits_tmp -= 6;
+ *bits_asc = bits_tmp;
+ add = (1 << bits_tmp);
+ acc = *code_asc >> 6;
+ do {
+ mpq_pkzip->offs_2e34[acc] = (uint8_t)count;
+ acc += add;
+ } while (acc < 0x80);
+ }
+ } else {
+
+ /* decrease bit by eight. (one byte) */
+ bits_tmp -= 8;
+ *bits_asc = bits_tmp;
+ add = (1 << bits_tmp);
+ acc = *code_asc >> 8;
+ do {
+ mpq_pkzip->offs_2eb4[acc] = (uint8_t)count;
+ acc += add;
+ } while (acc < 0x100);
+ }
+ }
+ }
+}
+
+/*
+ * decompress the imploded data using coded literals.
+ *
+ * returns: 0x000 - 0x0FF : one byte from compressed file.
+ * 0x100 - 0x305 : copy previous block. (0x100 = 1 byte)
+ * 0x306 : out of buffer?
+ */
+static uint32_t decode_literal(pkzip_cmp_s *mpq_pkzip) {
+
+ /* number of bits to skip. */
+ uint32_t bits;
+
+ /* position in buffers. */
+ uint32_t value;
+
+ /* check if bit the current buffer is set, if not return the next byte. */
+ if (mpq_pkzip->bit_buf & 1) {
+
+ /* skip current bit in the buffer. */
+ if (skip_bit(mpq_pkzip, 1)) {
+ return 0x306;
+ }
+
+ /* the next bits are position in buffers. */
+ value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)];
+
+ /* get number of bits to skip. */
+ if (skip_bit(mpq_pkzip, mpq_pkzip->slen_bits[value])) {
+ return 0x306;
+ }
+
+ /* check bits. */
+ if ((bits = mpq_pkzip->clen_bits[value]) != 0) {
+
+ /* some common variables. */
+ uint32_t val2 = mpq_pkzip->bit_buf & ((1 << bits) - 1);
+
+ /* check if we should skip one bit. */
+ if (skip_bit(mpq_pkzip, bits)) {
+
+ /* check position if we should skip the bit. */
+ if ((value + val2) != 0x10E) {
+ return 0x306;
+ }
+ }
+
+ /* fill values. */
+ value = mpq_pkzip->len_base[value] + val2;
+ }
+
+ /* return number of bytes to repeat. */
+ return value + 0x100;
+ }
+
+ /* skip one bit. */
+ if (skip_bit(mpq_pkzip, 1)) {
+ return 0x306;
+ }
+
+ /* check the binary compression type, read 8 bits and return them as one byte. */
+ if (mpq_pkzip->cmp_type == LIBMPQ_PKZIP_CMP_BINARY) {
+
+ /* fill values. */
+ value = mpq_pkzip->bit_buf & 0xFF;
+
+ /* check if we should skip one bit. */
+ if (skip_bit(mpq_pkzip, 8)) {
+ return 0x306;
+ }
+
+ /* return value from bit buffer. */
+ return value;
+ }
+
+ /* check if ascii compression is used. */
+ if (mpq_pkzip->bit_buf & 0xFF) {
+
+ /* fill values. */
+ value = mpq_pkzip->offs_2c34[mpq_pkzip->bit_buf & 0xFF];
+
+ /* check value. */
+ if (value == 0xFF) {
+ if (mpq_pkzip->bit_buf & 0x3F) {
+
+ /* check if four bits are in bit buffer for skipping. */
+ if (skip_bit(mpq_pkzip, 4)) {
+ return 0x306;
+ }
+
+ /* fill values. */
+ value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF];
+ } else {
+
+ /* check if six bits are in bit buffer for skipping. */
+ if (skip_bit(mpq_pkzip, 6)) {
+ return 0x306;
+ }
+
+ /* fill values. */
+ value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F];
+ }
+ }
+ } else {
+
+ /* check if eight bits are in bit buffer for skipping. */
+ if (skip_bit(mpq_pkzip, 8)) {
+ return 0x306;
+ }
+
+ /* fill values. */
+ value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF];
+ }
+
+ /* return out of buffer error (0x306) or position in buffer. */
+ return skip_bit(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value;
+}
+
+/* this function retrieves the number of bytes to move back. */
+static uint32_t decode_distance(pkzip_cmp_s *mpq_pkzip, uint32_t length) {
+
+ /* some common variables. */
+ uint32_t pos = mpq_pkzip->pos1[(mpq_pkzip->bit_buf & 0xFF)];
+
+ /* number of bits to skip. */
+ uint32_t skip = mpq_pkzip->dist_bits[pos];
+
+ /* skip the appropriate number of bits. */
+ if (skip_bit(mpq_pkzip, skip) == 1) {
+ return 0;
+ }
+
+ /* check if length is two. */
+ if (length == 2) {
+ pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03);
+
+ /* skip the bits. */
+ if (skip_bit(mpq_pkzip, 2) == 1) {
+ return 0;
+ }
+ } else {
+ pos = (pos << mpq_pkzip->dsize_bits) | (mpq_pkzip->bit_buf & mpq_pkzip->dsize_mask);
+
+ /* skip the bits */
+ if (skip_bit(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) {
+ return 0;
+ }
+ }
+
+ /* return the bytes to move back. */
+ return pos + 1;
+}
+
+/*
+ * function loads data from the input buffer used by mpq_pkzip
+ * "implode" and "explode" function as user defined callback and
+ * returns number of bytes loaded.
+ *
+ * char *buf - pointer to a buffer where to store loaded data.
+ * uint32_t *size - maximum number of bytes to read.
+ * void *param - custom pointer, parameter of implode/explode.
+ */
+static uint32_t data_read_input(char *buf, uint32_t *size, void *param) {
+
+ /* some common variables. */
+ pkzip_data_s *info = (pkzip_data_s *)param;
+ uint32_t max_avail = (info->in_bytes - info->in_pos);
+ uint32_t to_read = *size;
+
+ /* check the case when not enough data available. */
+ if (to_read > max_avail) {
+ to_read = max_avail;
+ }
+
+ /* load data and increment offsets. */
+ memcpy(buf, info->in_buf + info->in_pos, to_read);
+ info->in_pos += to_read;
+
+ /* return bytes read. */
+ return to_read;
+}
+
+/*
+ * function for store output data used by mpq_pkzip "implode" and
+ * "explode" as userdefined callback.
+ *
+ * char *buf - pointer to data to be written.
+ * uint32_t *size - number of bytes to write.
+ * void *param - custom pointer, parameter of implode/explode.
+ */
+static void data_write_output(char *buf, uint32_t *size, void *param) {
+
+ /* some common variables. */
+ pkzip_data_s *info = (pkzip_data_s *)param;
+ uint32_t max_write = (info->max_out - info->out_pos);
+ uint32_t to_write = *size;
+
+ /* check the case when not enough space in the output buffer. */
+ if (to_write > max_write) {
+ to_write = max_write;
+ }
+
+ /* write output data and increments offsets. */
+ memcpy(info->out_buf + info->out_pos, buf, to_write);
+ info->out_pos += to_write;
+}
+
+/* this function extract the data from input stream. */
+static uint32_t expand(pkzip_cmp_s *mpq_pkzip) {
+
+ /* number of bytes to copy. */
+ uint32_t copy_bytes;
+
+ /* one byte from compressed file. */
+ uint32_t one_byte;
+
+ /* some common variables. */
+ uint32_t result;
+
+ /* initialize output buffer position. */
+ mpq_pkzip->out_pos = 0x1000;
+
+ /* check if end of data or error, so terminate decompress. */
+ while ((result = one_byte = decode_literal(mpq_pkzip)) < 0x305) {
+
+ /* check if one byte is greater than 0x100, which means 'repeat n - 0xFE bytes'. */
+ if (one_byte >= 0x100) {
+
+ /* ECX */
+ uint8_t *source;
+
+ /* EDX */
+ uint8_t *target;
+
+ /* some common variables. */
+ uint32_t copy_length = one_byte - 0xFE;
+ uint32_t move_back;
+
+ /* get length of data to copy. */
+ if ((move_back = decode_distance(mpq_pkzip, copy_length)) == 0) {
+ result = 0x306;
+ break;
+ }
+
+ /* target and source pointer. */
+ target = &mpq_pkzip->out_buf[mpq_pkzip->out_pos];
+ source = target - move_back;
+ mpq_pkzip->out_pos += copy_length;
+
+ /* copy until nothing left. */
+ while (copy_length-- > 0) {
+ *target++ = *source++;
+ }
+ } else {
+
+ /* byte is 0x100 great, so add one byte. */
+ mpq_pkzip->out_buf[mpq_pkzip->out_pos++] = (uint8_t)one_byte;
+ }
+
+ /* check if number of extracted bytes has reached 1/2 of output buffer, so flush output buffer. */
+ if (mpq_pkzip->out_pos >= 0x2000) {
+
+ /* copy decompressed data into user buffer. */
+ copy_bytes = 0x1000;
+ mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], &copy_bytes, mpq_pkzip->param);
+
+ /* check if there are some data left, keep them alive. */
+ memcpy(mpq_pkzip->out_buf, &mpq_pkzip->out_buf[0x1000], mpq_pkzip->out_pos - 0x1000);
+ mpq_pkzip->out_pos -= 0x1000;
+ }
+ }
+
+ /* copy the rest. */
+ copy_bytes = mpq_pkzip->out_pos - 0x1000;
+ mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], &copy_bytes, mpq_pkzip->param);
+
+ /* return copied bytes. */
+ return result;
+}
+
+/* this function explode the data stream. */
+uint32_t libmpq__do_decompress_pkzip(uint8_t *work_buf, void *param) {
+
+ /* some common variables. */
+ pkzip_cmp_s *mpq_pkzip = (pkzip_cmp_s *)work_buf;
+
+ /* set the whole work buffer to zeros. */
+ memset(mpq_pkzip, 0, sizeof(pkzip_cmp_s));
+
+ /* initialize work struct and load compressed data. */
+ mpq_pkzip->read_buf = data_read_input;
+ mpq_pkzip->write_buf = data_write_output;
+ mpq_pkzip->param = param;
+ mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf);
+ mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param);
+
+ /* check if we have pkzip data. */
+ if (mpq_pkzip->in_bytes <= 4) {
+ return LIBMPQ_PKZIP_CMP_BAD_DATA;
+ }
+
+ /* get the compression type. */
+ mpq_pkzip->cmp_type = mpq_pkzip->in_buf[0];
+
+ /* get the dictionary size. */
+ mpq_pkzip->dsize_bits = mpq_pkzip->in_buf[1];
+
+ /* initialize 16-bit bit buffer. */
+ mpq_pkzip->bit_buf = mpq_pkzip->in_buf[2];
+
+ /* extra (over 8) bits. */
+ mpq_pkzip->extra_bits = 0;
+
+ /* position in input buffer. */
+ mpq_pkzip->in_pos = 3;
+
+ /* check if valid dictionary size. */
+ if (4 > mpq_pkzip->dsize_bits || mpq_pkzip->dsize_bits > 6) {
+ return LIBMPQ_PKZIP_CMP_INV_DICTSIZE;
+ }
+
+ /* shifted by 'sar' instruction. */
+ mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits);
+
+ /* check if we are using binary compression. */
+ if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_BINARY) {
+
+ /* check if we are using ascii compression. */
+ if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_ASCII) {
+ return LIBMPQ_PKZIP_CMP_INV_MODE;
+ }
+
+ /* create ascii buffer. */
+ memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc));
+ generate_tables_ascii(mpq_pkzip);
+ }
+
+ /* create the tables for decode. */
+ memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits));
+ generate_tables_decode(0x10, mpq_pkzip->slen_bits, pkzip_len_code, mpq_pkzip->pos2);
+
+ /* create the tables for decode. */
+ memcpy(mpq_pkzip->clen_bits, pkzip_clen_bits, sizeof(mpq_pkzip->clen_bits));
+ memcpy(mpq_pkzip->len_base, pkzip_len_base, sizeof(mpq_pkzip->len_base));
+ memcpy(mpq_pkzip->dist_bits, pkzip_dist_bits, sizeof(mpq_pkzip->dist_bits));
+ generate_tables_decode(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1);
+
+ /* check if data extraction works. */
+ if (expand(mpq_pkzip) != 0x306) {
+ return LIBMPQ_PKZIP_CMP_NO_ERROR;
+ }
+
+ /* something failed, so return error. */
+ return LIBMPQ_PKZIP_CMP_ABORT;
+}
diff --git a/contrib/libmpq/libmpq/explode.h b/contrib/libmpq/libmpq/explode.h
new file mode 100644
index 00000000000..84bbde77bee
--- /dev/null
+++ b/contrib/libmpq/libmpq/explode.h
@@ -0,0 +1,94 @@
+/*
+ * explode.h -- header file for pkware data decompression library
+ * used by mpq-tools.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+ *
+ * This source was adepted from the C++ version of pklib.h included
+ * in stormlib. The C++ version belongs to the following authors:
+ *
+ * Ladislav Zezula <ladik@zezula.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _EXPLODE_H
+#define _EXPLODE_H
+
+/* define compression constants and return values. */
+#define LIBMPQ_PKZIP_CMP_BINARY 0 /* binary compression. */
+#define LIBMPQ_PKZIP_CMP_ASCII 1 /* ascii compression. */
+#define LIBMPQ_PKZIP_CMP_NO_ERROR 0
+#define LIBMPQ_PKZIP_CMP_INV_DICTSIZE 1
+#define LIBMPQ_PKZIP_CMP_INV_MODE 2
+#define LIBMPQ_PKZIP_CMP_BAD_DATA 3
+#define LIBMPQ_PKZIP_CMP_ABORT 4
+
+#ifdef _MSC_VER
+#pragma pack(push,1)
+#endif
+
+/* compression structure. */
+typedef struct {
+ uint32_t offs0000; /* 0000 - start. */
+ uint32_t cmp_type; /* 0004 - compression type (binary or ascii). */
+ uint32_t out_pos; /* 0008 - position in output buffer. */
+ uint32_t dsize_bits; /* 000C - dict size (4, 5, 6 for 0x400, 0x800, 0x1000). */
+ uint32_t dsize_mask; /* 0010 - dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000). */
+ uint32_t bit_buf; /* 0014 - 16-bit buffer for processing input data. */
+ uint32_t extra_bits; /* 0018 - number of extra (above 8) bits in bit buffer. */
+ uint32_t in_pos; /* 001C - position in in_buf. */
+ uint32_t in_bytes; /* 0020 - number of bytes in input buffer. */
+ void *param; /* 0024 - custom parameter. */
+ uint32_t (*read_buf)(char *buf, uint32_t *size, void *param); /* 0028 offset.*/
+ void (*write_buf)(char *buf, uint32_t *size, void *param); /* 002C offset. */
+ uint8_t out_buf[0x2000]; /* 0030 - output circle buffer, starting position is 0x1000. */
+ uint8_t offs_2030[0x204]; /* 2030 - whats that? */
+ uint8_t in_buf[0x800]; /* 2234 - buffer for data to be decompressed. */
+ uint8_t pos1[0x100]; /* 2A34 - positions in buffers. */
+ uint8_t pos2[0x100]; /* 2B34 - positions in buffers. */
+ uint8_t offs_2c34[0x100]; /* 2C34 - buffer. */
+ uint8_t offs_2d34[0x100]; /* 2D34 - buffer. */
+ uint8_t offs_2e34[0x80]; /* 2EB4 - buffer. */
+ uint8_t offs_2eb4[0x100]; /* 2EB4 - buffer. */
+ uint8_t bits_asc[0x100]; /* 2FB4 - buffer. */
+ uint8_t dist_bits[0x40]; /* 30B4 - numbers of bytes to skip copied block length. */
+ uint8_t slen_bits[0x10]; /* 30F4 - numbers of bits for skip copied block length. */
+ uint8_t clen_bits[0x10]; /* 3104 - number of valid bits for copied block. */
+ uint16_t len_base[0x10]; /* 3114 - buffer. */
+#ifdef _MSC_VER
+} pkzip_cmp_s;
+#pragma pack(pop)
+#else
+} __attribute__ ((packed)) pkzip_cmp_s;
+#endif
+
+/* data structure. */
+typedef struct {
+ uint8_t *in_buf; /* pointer to input data buffer. */
+ uint32_t in_pos; /* current offset in input data buffer. */
+ int32_t in_bytes; /* number of bytes in the input buffer. */
+ uint8_t *out_buf; /* pointer to output data buffer. */
+ uint32_t out_pos; /* position in the output buffer. */
+ int32_t max_out; /* maximum number of bytes in the output buffer. */
+} pkzip_data_s;
+
+/* decompress the stream using pkzip compression. */
+uint32_t libmpq__do_decompress_pkzip(
+ uint8_t *work_buf,
+ void *param
+);
+
+#endif /* _EXPLODE_H */
diff --git a/contrib/libmpq/libmpq/extract.c b/contrib/libmpq/libmpq/extract.c
new file mode 100644
index 00000000000..11de1071683
--- /dev/null
+++ b/contrib/libmpq/libmpq/extract.c
@@ -0,0 +1,361 @@
+/*
+ * extract.c -- global extracting function for all known file compressions
+ * in a mpq archive.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.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 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.
+ */
+
+/* generic includes. */
+#include <stdlib.h>
+#include <string.h>
+
+/* zlib includes. */
+#include <zlib.h>
+#include <bzlib.h>
+
+/* libmpq main includes. */
+#include "mpq.h"
+
+/* libmpq generic includes. */
+#include "explode.h"
+#include "extract.h"
+#include "huffman.h"
+#include "wave.h"
+
+/* table with decompression bits and functions. */
+static decompress_table_s dcmp_table[] = {
+ {LIBMPQ_COMPRESSION_HUFFMAN, libmpq__decompress_huffman}, /* decompression using huffman trees. */
+ {LIBMPQ_COMPRESSION_ZLIB, libmpq__decompress_zlib}, /* decompression with the zlib library. */
+ {LIBMPQ_COMPRESSION_PKZIP, libmpq__decompress_pkzip}, /* decompression with pkware data compression library. */
+ {LIBMPQ_COMPRESSION_BZIP2, libmpq__decompress_bzip2}, /* decompression with bzip2 library. */
+ {LIBMPQ_COMPRESSION_WAVE_MONO, libmpq__decompress_wave_mono}, /* decompression for mono waves. */
+ {LIBMPQ_COMPRESSION_WAVE_STEREO, libmpq__decompress_wave_stereo} /* decompression for stereo waves. */
+};
+
+/* this function decompress a stream using huffman algorithm. */
+int32_t libmpq__decompress_huffman(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size) {
+
+ /* TODO: make typdefs of this structs? */
+ /* some common variables. */
+ int32_t tb = 0;
+ struct huffman_tree_s *ht;
+ struct huffman_input_stream_s *is;
+
+ /* allocate memory for the huffman tree. */
+ if ((ht = malloc(sizeof(struct huffman_tree_s))) == NULL ||
+ (is = malloc(sizeof(struct huffman_input_stream_s))) == NULL) {
+
+ /* memory allocation problem. */
+ return LIBMPQ_ERROR_MALLOC;
+ }
+
+ /* cleanup structures. */
+ memset(ht, 0, sizeof(struct huffman_tree_s));
+ memset(is, 0, sizeof(struct huffman_input_stream_s));
+
+ /* initialize input stream. */
+ is->bit_buf = *(uint32_t *)in_buf;
+ in_buf += sizeof(int32_t);
+ is->in_buf = (uint8_t *)in_buf;
+ is->bits = 32;
+
+// TODO: add all the mallocs to init function and add function libmpq__huffman_tree_free() */
+// if ((result = libmpq__huffman_tree_init(ht, LIBMPQ_HUFF_DECOMPRESS)) < 0) {
+//
+// /* something on zlib initialization failed. */
+// return LIBMPQ_ERROR_UNPACK;
+// }
+
+ /* initialize the huffman tree for decompression. */
+ libmpq__huffman_tree_init(ht, LIBMPQ_HUFF_DECOMPRESS);
+
+ /* save the number of copied bytes. */
+ tb = libmpq__do_decompress_huffman(ht, is, out_buf, out_size);
+
+ /* free structures. */
+ free(is);
+ free(ht);
+
+ /* return transferred bytes. */
+ return tb;
+}
+
+/* this function decompress a stream using zlib algorithm. */
+int32_t libmpq__decompress_zlib(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size) {
+
+ /* some common variables. */
+ int32_t result = 0;
+ int32_t tb = 0;
+ z_stream z;
+
+ /* fill the stream structure for zlib. */
+ z.next_in = (Bytef *)in_buf;
+ z.avail_in = (uInt)in_size;
+ z.total_in = in_size;
+ z.next_out = (Bytef *)out_buf;
+ z.avail_out = (uInt)out_size;
+ z.total_out = 0;
+ z.zalloc = NULL;
+ z.zfree = NULL;
+
+ /* initialize the decompression structure, storm.dll uses zlib version 1.1.3. */
+ if ((result = inflateInit(&z)) != Z_OK) {
+
+ /* something on zlib initialization failed. */
+ return result;
+ }
+
+ /* call zlib to decompress the data. */
+ if ((result = inflate(&z, Z_FINISH)) != Z_STREAM_END) {
+
+ /* something on zlib decompression failed. */
+ return result;
+ }
+
+ /* save transferred bytes. */
+ tb = z.total_out;
+
+ /* cleanup zlib. */
+ if ((result = inflateEnd(&z)) != Z_OK) {
+
+ /* something on zlib finalization failed. */
+ return result;
+ }
+
+ /* return transferred bytes. */
+ return tb;
+}
+
+/* this function decompress a stream using pkzip algorithm. */
+int32_t libmpq__decompress_pkzip(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size) {
+
+ /* some common variables. */
+ int32_t tb = 0;
+ uint8_t *work_buf;
+ pkzip_data_s info;
+
+ /* allocate memory for pkzip data structure. */
+ if ((work_buf = malloc(sizeof(pkzip_cmp_s))) == NULL) {
+
+ /* memory allocation problem. */
+ return LIBMPQ_ERROR_MALLOC;
+ }
+
+ /* cleanup. */
+ memset(work_buf, 0, sizeof(pkzip_cmp_s));
+
+ /* fill data information structure. */
+ info.in_buf = in_buf;
+ info.in_pos = 0;
+ info.in_bytes = in_size;
+ info.out_buf = out_buf;
+ info.out_pos = 0;
+ info.max_out = out_size;
+
+ /* do the decompression. */
+ if ((tb = libmpq__do_decompress_pkzip(work_buf, &info)) < 0) {
+
+ /* free working buffer. */
+ free(work_buf);
+
+ /* something failed on pkzip decompression. */
+ return tb;
+ }
+
+ /* save transferred bytes. */
+ tb = info.out_pos;
+
+ /* free working buffer. */
+ free(work_buf);
+
+ /* return transferred bytes. */
+ return tb;
+}
+
+/* this function decompress a stream using bzip2 library. */
+int32_t libmpq__decompress_bzip2(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size) {
+
+ /* some common variables. */
+ int32_t result = 0;
+ int32_t tb = 0;
+ bz_stream strm;
+
+ /* initialize the bzlib decompression. */
+ strm.bzalloc = NULL;
+ strm.bzfree = NULL;
+
+ /* initialize the structure. */
+ if ((result = BZ2_bzDecompressInit(&strm, 0, 0)) != BZ_OK) {
+
+ /* something on bzlib initialization failed. */
+ return result;
+ }
+
+ /* fill the stream structure for bzlib. */
+ strm.next_in = (char *)in_buf;
+ strm.avail_in = in_size;
+ strm.next_out = (char *)out_buf;
+ strm.avail_out = out_size;
+
+ /* do the decompression. */
+ while (BZ2_bzDecompress(&strm) != BZ_STREAM_END);
+
+ /* save transferred bytes. */
+ tb = strm.total_out_lo32;
+
+ /* cleanup of bzip stream. */
+ BZ2_bzDecompressEnd(&strm);
+
+ /* return transferred bytes. */
+ return tb;
+}
+
+/* this function decompress a stream using wave algorithm. (1 channel) */
+int32_t libmpq__decompress_wave_mono(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size) {
+
+ /* some common variables. */
+ int32_t tb = 0;
+
+ /* save the number of copied bytes. */
+ if ((tb = libmpq__do_decompress_wave(out_buf, out_size, in_buf, in_size, 1)) < 0) {
+
+ /* something on wave decompression failed. */
+ return tb;
+ }
+
+ /* return transferred bytes. */
+ return tb;
+}
+
+/* this function decompress a stream using wave algorithm. (2 channels) */
+int32_t libmpq__decompress_wave_stereo(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size) {
+
+ /* some common variables. */
+ int32_t tb = 0;
+
+ /* save the number of copied bytes. */
+ if ((tb = libmpq__do_decompress_wave(out_buf, out_size, in_buf, in_size, 2)) < 0) {
+
+ /* something on wave decompression failed. */
+ return tb;
+ }
+
+ /* return transferred bytes. */
+ return tb;
+}
+
+/* this function decompress a stream using a combination of the other compression algorithm. */
+int32_t libmpq__decompress_multi(uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size) {
+
+ /* some common variables. */
+ int32_t tb = 0;
+ uint32_t count = 0;
+ uint32_t entries = (sizeof(dcmp_table) / sizeof(decompress_table_s));
+ uint8_t *temp_buf = NULL;
+ uint8_t *work_buf = 0;
+ uint8_t decompress_flag, decompress_unsupp;
+ uint32_t i;
+
+ /* get applied compression types. */
+ decompress_flag = decompress_unsupp = *in_buf++;
+
+ /* decrement data size. */
+ in_size--;
+
+ /* search decompression table type and get all types of compression. */
+ for (i = 0; i < entries; i++) {
+
+ /* check if have to apply this decompression. */
+ if (decompress_flag & dcmp_table[i].mask) {
+
+ /* increase counter for used compression algorithms. */
+ count++;
+ /* this algorithm is supported, remove from unsupp mask */
+ decompress_unsupp &= ~dcmp_table[i].mask;
+ }
+ }
+
+ /* check if there is some method unhandled. (e.g. compressed by future versions) */
+ if (decompress_unsupp) {
+
+ /* compression type is unknown and we need to implement it. :) */
+ return LIBMPQ_ERROR_UNPACK;
+ }
+
+ /* if multiple decompressions should be made, we need temporary buffer for the data. */
+ if (count > 1) {
+
+ /* allocate memory for temporary buffer. */
+ if ((temp_buf = malloc(out_size)) == NULL) {
+
+ /* memory allocation problem. */
+ return LIBMPQ_ERROR_MALLOC;
+ }
+
+ /* cleanup. */
+ memset(temp_buf, 0, out_size);
+ }
+
+ /* apply all decompressions. */
+ for (i = 0, count = 0; i < entries; i++) {
+
+ /* check if not used this kind of compression. */
+ if (decompress_flag & dcmp_table[i].mask) {
+
+ /* if multiple decompressions should be made, we need temporary buffer for the data. */
+ if (count == 0) {
+
+ /* use output buffer as working buffer. */
+ work_buf = out_buf;
+ } else {
+
+ /* use temporary buffer as working buffer. */
+ work_buf = temp_buf;
+ }
+
+ /* decompress buffer using corresponding function. */
+ if ((tb = dcmp_table[i].decompress(in_buf, in_size, work_buf, out_size)) < 0) {
+
+ /* free temporary buffer. */
+ free(temp_buf);
+
+ /* something on decompression failed. */
+ return tb;
+ }
+
+ /* move output size to source size for next compression. */
+ in_size = out_size;
+ in_buf = work_buf;
+
+ /* increase counter. */
+ count++;
+ }
+ }
+
+ /* if output buffer is not the same like target buffer, we have to copy data (this will happen on multiple decompressions). */
+ if (work_buf != out_buf) {
+
+ /* copy buffer. */
+ memcpy(out_buf, in_buf, out_size);
+ }
+
+ /* free temporary buffer. */
+ free(temp_buf);
+
+ /* return transferred bytes. */
+ return tb;
+}
diff --git a/contrib/libmpq/libmpq/extract.h b/contrib/libmpq/libmpq/extract.h
new file mode 100644
index 00000000000..d6ea794f162
--- /dev/null
+++ b/contrib/libmpq/libmpq/extract.h
@@ -0,0 +1,106 @@
+/*
+ * extract.h -- header for the extraction functions used by mpq-tools.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.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 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 _EXTRACT_H
+#define _EXTRACT_H
+
+/* define compression types for multilpe compressions. */
+#define LIBMPQ_COMPRESSION_HUFFMAN 0x01 /* huffman compression. (used on wave files only and introduced in starcraft) */
+#define LIBMPQ_COMPRESSION_ZLIB 0x02 /* zlib compression. (introduced in warcraft 3) */
+#define LIBMPQ_COMPRESSION_PKZIP 0x08 /* pkware dcl compression. (first used compression algorithm) */
+#define LIBMPQ_COMPRESSION_BZIP2 0x10 /* bzip compression. (introduced in warcraft 3 - the frozen throne) */
+#define LIBMPQ_COMPRESSION_WAVE_MONO 0x40 /* adpcm 4:1 compression. (introduced in starcraft) */
+#define LIBMPQ_COMPRESSION_WAVE_STEREO 0x80 /* adpcm 4:1 compression. (introduced in starcraft) */
+
+/*
+ * table for decompression functions, return value for all functions
+ * is the transferred data size or one of the following error constants:
+ *
+ * LIBMPQ_ERROR_MALLOC
+ * LIBMPQ_ERROR_DECOMPRESS
+ */
+typedef int32_t (*DECOMPRESS)(uint8_t *, uint32_t, uint8_t *, uint32_t);
+typedef struct {
+ uint32_t mask; /* decompression bit. */
+ DECOMPRESS decompress; /* decompression function. */
+} decompress_table_s;
+
+/*
+ * huffman decompression routine, the in_size parameter is not used,
+ * but needs to be specified due to compatibility reasons.
+ *
+ * 1500F5F0
+ */
+extern int32_t libmpq__decompress_huffman(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size
+);
+
+/* decompression using zlib. */
+extern int32_t libmpq__decompress_zlib(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size
+);
+
+/* decompression using pkzip. */
+extern int32_t libmpq__decompress_pkzip(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size
+);
+
+/* decompression using bzip2. */
+extern int32_t libmpq__decompress_bzip2(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size
+);
+
+/* decompression using wave. (1 channel) */
+extern int32_t libmpq__decompress_wave_mono(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size
+);
+
+/* decompression using wave. (2 channels) */
+extern int32_t libmpq__decompress_wave_stereo(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size
+);
+
+/* decompression using multiple of the above algorithm. */
+extern int32_t libmpq__decompress_multi(
+ uint8_t *in_buf,
+ uint32_t in_size,
+ uint8_t *out_buf,
+ uint32_t out_size
+);
+
+#endif /* _EXTRACT_H */
diff --git a/contrib/libmpq/libmpq/huffman.c b/contrib/libmpq/libmpq/huffman.c
new file mode 100644
index 00000000000..8fc87be2f60
--- /dev/null
+++ b/contrib/libmpq/libmpq/huffman.c
@@ -0,0 +1,1101 @@
+/*
+ * huffman.c -- functions do decompress files in mpq files which
+ * uses a modified huffman version.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+ *
+ * Differences between C++ and C version:
+ *
+ * - Removed the object oriented stuff.
+ * - Replaced the goto things with some better C code.
+ *
+ * This source was adepted from the C++ version of huffman.cpp included
+ * in stormlib. The C++ version belongs to the following authors:
+ *
+ * Ladislav Zezula <ladik@zezula.net>
+ * ShadowFlare <BlakFlare@hotmail.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.
+ */
+
+/* generic includes. */
+#include <stdlib.h>
+#include <string.h>
+
+/* libmpq main includes. */
+#include "mpq.h"
+#include "mpq-internal.h"
+
+/* libmpq generic includes. */
+#include "huffman.h"
+
+/* tables for huffman tree. */
+static const uint8_t table_1502A630[] = {
+
+ /* data for compression type 0x00. */
+ 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00,
+
+ /* data for compression type 0x01. */
+ 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
+ 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
+ 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
+ 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04,
+ 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
+ 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02,
+ 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03,
+ 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03,
+ 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+ 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
+ 0x00, 0x00,
+
+ /* data for compression type 0x02. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
+ 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01,
+ 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02,
+ 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
+ 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
+ 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ /* data for compression type 0x03. */
+ 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
+ 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+ 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01,
+ 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03,
+ 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03,
+ 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01,
+ 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
+ 0x00, 0x00,
+
+ /* data for compression type 0x04. */
+ 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ /* data for compression type 0x05. */
+ 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
+ 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
+ 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
+ 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ /* data for compression type 0x06. */
+ 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ /* data for compression type 0x07. */
+ 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ /* data for compression type 0x08. */
+ 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10,
+ 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11,
+ 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+};
+
+/* this function insert an item to a huffman tree. */
+void libmpq__huffman_insert_item(struct huffman_tree_item_s **p_item, struct huffman_tree_item_s *item, uint32_t where, struct huffman_tree_item_s *item2) {
+
+ /* EDI - next to the first item. */
+ struct huffman_tree_item_s *next = item->next;
+
+ /* ESI - prev to the first item. */
+ struct huffman_tree_item_s *prev = item->prev;
+
+ /* pointer to previous item. */
+ struct huffman_tree_item_s *prev2;
+
+ /* pointer to next item. */
+ long next2;
+
+ /* check the first item already has next one. */
+ if (next != 0) {
+
+ /* check if previous item exist. */
+ if (PTR_INT(prev) < 0) {
+
+ /* return previous item. */
+ prev = PTR_NOT(prev);
+ } else {
+
+ /* add item. */
+ prev += (item - next->prev);
+ }
+
+ /* 150083C1 - remove the item from the tree. */
+ prev->next = next;
+ next->prev = prev;
+
+ /* invalidate prev and next pointer. */
+ item->next = 0;
+ item->prev = 0;
+ }
+
+ /* EDX - check if the second item is not entered. */
+ if (item2 == NULL) {
+
+ /* take the first tree item. */
+ item2 = PTR_PTR(&p_item[1]);
+ }
+
+ /* check if items should be switched or new one inserted. */
+ switch (where) {
+ case SWITCH_ITEMS:
+
+ /* item2->next (pointer to pointer to first). */
+ item->next = item2->next;
+ item->prev = item2->next->prev;
+ item2->next->prev = item;
+
+ /* set the first item. */
+ item2->next = item;
+
+ /* return from function. */
+ return;
+ case INSERT_ITEM:
+
+ /* set next item (or pointer to pointer to first item) - insert as last item. */
+ item->next = item2;
+
+ /* set previous item (or last item in the tree). */
+ item->prev = item2->prev;
+
+ /* usually NULL. */
+ next2 = PTR_INT(p_item[0]);
+
+ /* previous item to the second (or last tree item). */
+ prev2 = item2->prev;
+
+ /* check if previous item is a valid pointer. */
+ if (PTR_INT(prev2) < 0) {
+
+ /* set values. */
+ prev2 = PTR_NOT(prev);
+ prev2->next = item;
+
+ /* next after last item. */
+ item2->prev = item;
+
+ /* return from function. */
+ return;
+ }
+
+ /* check if next item is empty. */
+ if (next2 < 0) {
+
+ /* set next item. */
+ next2 = item2 - item2->next->prev;
+ }
+
+ /* add next item to previous one. */
+ prev2 += next2;
+ prev2->next = item;
+
+ /* set the next and last item. */
+ item2->prev = item;
+
+ /* return from function. */
+ return;
+ default:
+
+ /* nothing to do, so return from function. */
+ return;
+ }
+}
+
+/* 1500BC90 - remove item from huffman tree.*/
+void libmpq__huffman_remove_item(struct huffman_tree_item_s *hi) {
+
+ /* EDX - some common variables. */
+ struct huffman_tree_item_s *temp;
+
+ /* check if next item is not empty. */
+ if (hi->next != NULL) {
+
+ /* fetch previous item. */
+ temp = hi->prev;
+
+ /* check if previous item is a pointer. */
+ if (PTR_INT(temp) <= 0) {
+ temp = PTR_NOT(temp);
+ } else {
+ temp += (hi - hi->next->prev);
+ }
+
+ /* reorganize tree. */
+ temp->next = hi->next;
+ hi->next->prev = hi->prev;
+ hi->next = hi->prev = NULL;
+ }
+}
+
+/* get previous huffman tree item. */
+struct huffman_tree_item_s *libmpq__huffman_previous_item(struct huffman_tree_item_s *hi, long value) {
+
+ /* check if previous item exist. */
+ if (PTR_INT(hi->prev) < 0) {
+
+ /* return previous item. */
+ return PTR_NOT(hi->prev);
+ }
+
+ /* check if something else should returned. */
+ if (value < 0) {
+
+ /* fetch previous item of next item. */
+ value = hi - hi->next->prev;
+ }
+
+ /* return previous item with value. */
+ return hi->prev + value;
+}
+
+/* get one bit from input stream. */
+uint32_t libmpq__huffman_get_1bit(struct huffman_input_stream_s *is) {
+
+ /* some common variables. */
+ uint32_t bit = (is->bit_buf & 1);
+
+ /* shift bit right by one. */
+ is->bit_buf >>= 1;
+
+ /* check if we should extract bits. */
+ if (--is->bits == 0) {
+ is->bit_buf = *(uint32_t *)is->in_buf;
+ is->in_buf += sizeof(int32_t);
+ is->bits = 32;
+ }
+
+ /* return the bit. */
+ return bit;
+}
+
+/* get 7 bits from the input stream. */
+uint32_t libmpq__huffman_get_7bit(struct huffman_input_stream_s *is) {
+
+ /* check if we should extract bits. */
+ if (is->bits <= 7) {
+ is->bit_buf |= *(uint16_t *)is->in_buf << is->bits;
+ is->in_buf += sizeof(int16_t);
+ is->bits += 16;
+ }
+
+ /* get 7 bits from input stream. */
+ return (is->bit_buf & 0x7F);
+}
+
+/* get the whole byte from the input stream. */
+uint32_t libmpq__huffman_get_8bit(struct huffman_input_stream_s *is) {
+
+ /* some common variables. */
+ uint32_t one_byte;
+
+ /* check if we should extract bits. */
+ if (is->bits <= 8) {
+ is->bit_buf |= *(uint16_t *)is->in_buf << is->bits;
+ is->in_buf += sizeof(int16_t);
+ is->bits += 16;
+ }
+
+ /* fill values. */
+ one_byte = (is->bit_buf & 0xFF);
+ is->bit_buf >>= 8;
+ is->bits -= 8;
+
+ /* return the 8 bits. */
+ return one_byte;
+}
+
+/* return struct for 1500E740. */
+struct huffman_tree_item_s *libmpq__huffman_call_1500E740(struct huffman_tree_s *ht) {
+
+ /* EDX */
+ struct huffman_tree_item_s *p_item1 = ht->item3058;
+
+ /* EAX */
+ struct huffman_tree_item_s *p_item2;
+
+ /* some common variables. */
+ struct huffman_tree_item_s *p_next;
+ struct huffman_tree_item_s *p_prev;
+ struct huffman_tree_item_s **pp_item;
+
+ /* check if item is empty. */
+ if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) {
+
+ /* check if item is not empty. */
+ if ((p_item2 = &ht->items0008[ht->items++]) != NULL) {
+ p_item1 = p_item2;
+ } else {
+ p_item1 = ht->first;
+ }
+ } else {
+ p_item1 = p_item2;
+ }
+
+ /* set next item. */
+ p_next = p_item1->next;
+
+ /* check if next item is not empty. */
+ if (p_next != NULL) {
+
+ /* set previous item. */
+ p_prev = p_item1->prev;
+
+ /* check if previous item is a valid pointer. */
+ if (PTR_INT(p_prev) <= 0) {
+ p_prev = PTR_NOT(p_prev);
+ } else {
+ p_prev += (p_item1 - p_item1->next->prev);
+ }
+
+ /* fill values. */
+ p_prev->next = p_next;
+ p_next->prev = p_prev;
+ p_item1->next = NULL;
+ p_item1->prev = NULL;
+ }
+
+ /* ESI */
+ pp_item = &ht->first;
+ p_item1->next = (struct huffman_tree_item_s *)pp_item;
+ p_item1->prev = pp_item[1];
+
+ /* EDI = ht->item305C - ECX */
+ p_prev = pp_item[1];
+
+ /* check if previous pointer is valid. */
+ if (p_prev <= 0) {
+
+ /* fill values. */
+ p_prev = PTR_NOT(p_prev);
+ p_prev->next = p_item1;
+ p_prev->prev = p_item2;
+ p_item2->parent = NULL;
+ p_item2->child = NULL;
+ } else {
+
+ /* check if pointer is valid. */
+ if (PTR_INT(ht->item305C) < 0) {
+ p_prev += (struct huffman_tree_item_s *)pp_item - (*pp_item)->prev;
+ } else {
+ p_prev += PTR_INT(ht->item305C);
+ }
+
+ /* fill values. */
+ p_prev->next = p_item1;
+ pp_item[1] = p_item2;
+ p_item2->parent = NULL;
+ p_item2->child = NULL;
+ }
+
+ /* return item. */
+ return p_item2;
+}
+
+/* return struct for 1500E820. */
+void libmpq__huffman_call_1500E820(struct huffman_tree_s *ht, struct huffman_tree_item_s *p_item) {
+
+ /* EDI */
+ struct huffman_tree_item_s *p_item1;
+
+ /* EAX */
+ struct huffman_tree_item_s *p_item2 = NULL;
+
+ /* EDX */
+ struct huffman_tree_item_s *p_item3;
+
+ /* EBX */
+ struct huffman_tree_item_s *p_prev;
+
+ /* loop through parent items. */
+ for (; p_item != NULL; p_item = p_item->parent) {
+
+ /* increase byte counter. */
+ p_item->byte_value++;
+
+ /* loop through previous items. */
+ for (p_item1 = p_item; ; p_item1 = p_prev) {
+
+ /* set previous item. */
+ p_prev = p_item1->prev;
+
+ /* check if pointer is valid. */
+ if (PTR_INT(p_prev) <= 0) {
+ p_prev = NULL;
+ break;
+ }
+
+ /* check if byte value of previous item is higher than actual item. */
+ if (p_prev->byte_value >= p_item->byte_value) {
+ break;
+ }
+ }
+
+ /* check if previous item is same like actual item. */
+ if (p_item1 == p_item) {
+ continue;
+ }
+
+ /* check if next item is not empty, */
+ if (p_item1->next != NULL) {
+
+ /* fill values. */
+ p_item2 = libmpq__huffman_previous_item(p_item1, -1);
+ p_item2->next = p_item1->next;
+ p_item1->next->prev = p_item1->prev;
+ p_item1->next = NULL;
+ p_item1->prev = NULL;
+ }
+
+ /* fill values. */
+ p_item2 = p_item->next;
+ p_item1->next = p_item2;
+ p_item1->prev = p_item2->prev;
+ p_item2->prev = p_item1;
+ p_item->next = p_item1;
+
+ /* check if both items are not empty. */
+ if ((p_item2 = p_item1) != NULL) {
+
+ /* fill values. */
+ p_item2 = libmpq__huffman_previous_item(p_item, -1);
+ p_item2->next = p_item->next;
+ p_item->next->prev = p_item->prev;
+ p_item->next = NULL;
+ p_item->prev = NULL;
+ }
+
+ /* check if previous item is empty. */
+ if (p_prev == NULL) {
+ p_prev = PTR_PTR(&ht->first);
+ }
+
+ /* fill values. */
+ p_item2 = p_prev->next;
+ p_item->next = p_item2;
+ p_item->prev = p_item2->prev;
+ p_item2->prev = p_item;
+ p_prev->next = p_item;
+ p_item3 = p_item1->parent->child;
+ p_item2 = p_item->parent;
+
+ /* check if child item and parent item match. */
+ if (p_item2->child == p_item) {
+ p_item2->child = p_item1;
+ }
+
+ /* check if items match. */
+ if (p_item3 == p_item1) {
+ p_item1->parent->child = p_item;
+ }
+
+ /* fill values. */
+ p_item2 = p_item->parent;
+ p_item->parent = p_item1->parent;
+ p_item1->parent = p_item2;
+
+ /* increase counter. */
+ ht->offs0004++;
+ }
+}
+
+/* this function initialize a huffman tree. */
+void libmpq__huffman_tree_init(struct huffman_tree_s *ht, uint32_t cmp) {
+
+ /* some common variables. */
+ uint32_t count;
+ struct huffman_tree_item_s *hi;
+
+ /* clear links for all the items in the tree. */
+ for (hi = ht->items0008, count = 0x203; count != 0; hi++, count--) {
+ hi->next = hi->prev = NULL;
+ }
+
+ /* fill values. */
+ ht->item3050 = NULL;
+ ht->item3054 = PTR_PTR(&ht->item3054);
+ ht->item3058 = PTR_NOT(ht->item3054);
+ ht->item305C = NULL;
+ ht->first = PTR_PTR(&ht->first);
+ ht->last = PTR_NOT(ht->first);
+ ht->offs0004 = 1;
+ ht->items = 0;
+
+ /* clear all huffman decompress items, do this only if preparing for decompression. */
+ if (cmp == LIBMPQ_HUFF_DECOMPRESS) {
+ for (count = 0; count < sizeof(ht->qd3474) / sizeof(struct huffman_decompress_s); count++) {
+ ht->qd3474[count].offs00 = 0;
+ }
+ }
+}
+
+/* this function build a huffman tree, called with the first 8 bits loaded from input stream. */
+void libmpq__huffman_tree_build(struct huffman_tree_s *ht, uint32_t cmp_type) {
+
+ /* [ESP+10] - the greatest character found in table. */
+ uint32_t max_byte;
+
+ /* [ESP+1C] - pointer to uint8_t in table_1502A630. */
+ const uint8_t *byte_array;
+
+ /* thats needed to replace the goto stuff from original source. :) */
+ uint32_t found;
+
+ /* [ESP+14] - Pointer to Huffman tree item pointer array. */
+ struct huffman_tree_item_s **p_item;
+ struct huffman_tree_item_s *child1;
+
+ /* some common variables. */
+ uint32_t i;
+
+ /* ESI - loop while pointer has a negative value (last entry). */
+ while (PTR_INT(ht->last) > 0) {
+
+ /* EAX */
+ struct huffman_tree_item_s *temp;
+
+ /* ESI->next */
+ if (ht->last->next != NULL) {
+ libmpq__huffman_remove_item(ht->last);
+ }
+
+ /* [EDI+4] */
+ ht->item3058 = PTR_PTR(&ht->item3054);
+
+ /* EAX */
+ ht->last->prev = ht->item3058;
+ temp = libmpq__huffman_previous_item(PTR_PTR(&ht->item3054), PTR_INT(&ht->item3050));
+ temp->next = ht->last;
+ ht->item3054 = ht->last;
+ }
+
+ /* clear all pointers in huffman tree item array. */
+ memset(ht->items306C, 0, sizeof(ht->items306C));
+
+ /* greatest character found init to zero. */
+ max_byte = 0;
+
+ /* pointer to current entry in huffman tree item pointer array. */
+ p_item = (struct huffman_tree_item_s **)&ht->items306C;
+
+ /* ensure we have low 8 bits only. */
+ cmp_type &= 0xFF;
+
+ /* EDI also. */
+ byte_array = table_1502A630 + cmp_type * 258;
+
+ /* loop to build huffman tree. */
+ for (i = 0; i < 0x100; i++, p_item++) {
+
+ /* item to be created. */
+ struct huffman_tree_item_s *item = ht->item3058;
+ struct huffman_tree_item_s *p_item3 = ht->item3058;
+ uint8_t one_byte = byte_array[i];
+
+ /* skip all the bytes which are zero. */
+ if (byte_array[i] == 0) {
+ continue;
+ }
+
+ /* if not valid pointer, take the first available item in the array. */
+ if (PTR_INT(item) <= 0) {
+ item = &ht->items0008[ht->items++];
+ }
+
+ /* insert this item as the top of the tree. */
+ libmpq__huffman_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL);
+
+ /* invalidate child and parent. */
+ item->parent = NULL;
+ item->child = NULL;
+
+ /* store pointer into pointer array. */
+ *p_item = item;
+
+ /* store counter. */
+ item->dcmp_byte = i;
+
+ /* store byte value. */
+ item->byte_value = one_byte;
+
+ /* check if byte is to big. */
+ if (one_byte >= max_byte) {
+
+ /* set max byte to highest value. */
+ max_byte = one_byte;
+
+ /* continue loop. */
+ continue;
+ }
+
+ /* find the first item which has byte value greater than current one byte. */
+ found = 0;
+
+ /* EDI - Pointer to the last item. */
+ if (PTR_INT((p_item3 = ht->last)) > 0) {
+
+ /* 15006AF7 */
+ if (p_item3 != NULL) {
+
+ /* 15006AFB */
+ do {
+
+ /* check if we found item. */
+ if (p_item3->byte_value >= one_byte) {
+ found = 1;
+ break;
+ }
+
+ /* switch to previous item. */
+ p_item3 = p_item3->prev;
+ } while (PTR_INT(p_item3) > 0);
+ }
+ }
+
+ /* check if item was not found. */
+ if (found == 0) {
+ p_item3 = NULL;
+ }
+
+ /* 15006B09 */
+ if (item->next != NULL) {
+ libmpq__huffman_remove_item(item);
+ }
+
+ /* 15006B15 */
+ if (p_item3 == NULL) {
+ p_item3 = PTR_PTR(&ht->first);
+ }
+
+ /* 15006B1F */
+ item->next = p_item3->next;
+ item->prev = p_item3->next->prev;
+ p_item3->next->prev = item;
+ p_item3->next = item;
+ }
+
+ /* 15006B4A */
+ for (; i < 0x102; i++) {
+
+ /* EDI */
+ struct huffman_tree_item_s **p_item2 = &ht->items306C[i];
+
+ /* 15006B59 - ESI */
+ struct huffman_tree_item_s *item2 = ht->item3058;
+
+ /* check if item is a valid pointer. */
+ if (PTR_INT(item2) <= 0) {
+ item2 = &ht->items0008[ht->items++];
+ }
+
+ /* insert the item into tree. */
+ libmpq__huffman_insert_item(&ht->item305C, item2, INSERT_ITEM, NULL);
+
+ /* 15006B89 */
+ item2->dcmp_byte = i;
+ item2->byte_value = 1;
+ item2->parent = NULL;
+ item2->child = NULL;
+ *p_item2++ = item2;
+ }
+
+ /* 15006BAA - EDI - last item (first child to item). */
+ if (PTR_INT((child1 = ht->last)) > 0) {
+
+ /* EBP */
+ struct huffman_tree_item_s *child2;
+
+ /* ESI */
+ struct huffman_tree_item_s *item;
+
+ /* 15006BB8 */
+ while (PTR_INT((child2 = child1->prev)) > 0) {
+ if (PTR_INT((item = ht->item3058)) <= 0) {
+ item = &ht->items0008[ht->items++];
+ }
+
+ /* 15006BE3 */
+ libmpq__huffman_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL);
+
+ /* 15006BF3 */
+ item->parent = NULL;
+ item->child = NULL;
+
+ /*
+ * EDX = child2->byte_value + child1->byte_value;
+ * EAX = child1->byte_value;
+ * ECX = max_byte; (the greatest character (0xFF usually))
+ * item->byte_value (0x02 usually)
+ */
+ item->byte_value = child1->byte_value + child2->byte_value;
+
+ /* previous item in the tree. */
+ item->child = child1;
+ child1->parent = item;
+ child2->parent = item;
+
+ /* EAX = item->byte_value */
+ if (item->byte_value >= max_byte) {
+ max_byte = item->byte_value;
+ } else {
+
+ /* EDI */
+ struct huffman_tree_item_s *p_item2 = child2->prev;
+ found = 0;
+
+ /* check if item is a valid pointer. */
+ if (PTR_INT(p_item2) > 0) {
+
+ /* 15006C2D */
+ do {
+
+ /* check if we found item. */
+ if (p_item2->byte_value >= item->byte_value) {
+ found = 1;
+ break;
+ }
+
+ /* switch to previous item. */
+ p_item2 = p_item2->prev;
+ } while (PTR_INT(p_item2) > 0);
+ }
+
+ /* check if item was not found. */
+ if (found == 0) {
+ p_item2 = NULL;
+ }
+
+ /* check if next item exist. */
+ if (item->next != 0) {
+
+ /* some common variables. */
+ struct huffman_tree_item_s *temp4 = libmpq__huffman_previous_item(item, -1);
+
+ /* zhe first item changed. */
+ temp4->next = item->next;
+
+ /* first->prev changed to negative value. */
+ item->next->prev = item->prev;
+ item->next = NULL;
+ item->prev = NULL;
+ }
+
+ /* 15006C62 */
+ if (p_item2 == NULL) {
+ p_item2 = PTR_PTR(&ht->first);
+ }
+
+ /* set item with 0x100 byte value. */
+ item->next = p_item2->next;
+
+ /* set item with 0x17 byte value. */
+ item->prev = p_item2->next->prev;
+
+ /* changed prev of item with. */
+ p_item2->next->prev = item;
+ p_item2->next = item;
+ }
+
+ /* 15006C7B */
+ if (PTR_INT((child1 = child2->prev)) <= 0) {
+ break;
+ }
+ }
+ }
+
+ /* 15006C88 */
+ ht->offs0004 = 1;
+}
+
+/* this function did the real decompression. */
+int32_t libmpq__do_decompress_huffman(struct huffman_tree_s *ht, struct huffman_input_stream_s *is, uint8_t *out_buf, uint32_t out_length) {
+
+ /* some common variables. */
+ uint32_t dcmp_byte = 0;
+ uint8_t *out_pos = out_buf;
+ uint32_t bit_count;
+ struct huffman_decompress_s *qd;
+ struct huffman_tree_item_s *p_item1;
+ struct huffman_tree_item_s *p_item2;
+
+ /* 8 bits loaded from input stream. */
+ uint32_t n8bits;
+
+ /* 7 bits loaded from input stream. */
+ uint32_t n7bits;
+
+ /* thats needed to replace the goto stuff from original source. :) */
+ uint32_t found;
+
+ /* can we use quick decompression */
+ uint32_t has_qd;
+
+ /* test the output length, must not be non zero. */
+ if (out_length == 0) {
+ return 0;
+ }
+
+ /* get the compression type from the input stream. */
+ n8bits = libmpq__huffman_get_8bit(is);
+
+ /* build the Huffman tree. */
+ libmpq__huffman_tree_build(ht, n8bits);
+
+ /* compression 8 bit or not? */
+ ht->cmp0 = (n8bits == 0) ? TRUE : FALSE;
+
+ /* loop until break. */
+ for(;;) {
+
+ /* get 7 bits from input stream. */
+ n7bits = libmpq__huffman_get_7bit(is);
+
+ /* try to use quick decompression, check huffman decompress struct for corresponding item. */
+ qd = &ht->qd3474[n7bits];
+
+ /* if there is a quick-pass possible (ebx). */
+ has_qd = (qd->offs00 >= ht->offs0004) ? TRUE : FALSE;
+
+ /* if we can use quick decompress, use it. */
+ if (has_qd) {
+ found = 0;
+ if (qd->bits > 7) {
+ is->bit_buf >>= 7;
+ is->bits -= 7;
+ p_item1 = qd->p_item;
+ found = 1;
+ }
+ if (found == 0) {
+ is->bit_buf >>= qd->bits;
+ is->bits -= qd->bits;
+ dcmp_byte = qd->dcmp_byte;
+ }
+ } else {
+ found = 1;
+ p_item1 = ht->first->next->prev;
+ if (PTR_INT(p_item1) <= 0) {
+ p_item1 = NULL;
+ }
+ }
+
+ /* check if item was found. */
+ if (found == 1) {
+ bit_count = 0;
+ p_item2 = NULL;
+
+ /* loop until tree has no deeper level. */
+ do {
+
+ /* move down by one level. */
+ p_item1 = p_item1->child;
+
+ /* check if current bit is set, move to previous. */
+ if (libmpq__huffman_get_1bit(is)) {
+ p_item1 = p_item1->prev;
+ }
+
+ /* check if we are at 7th bit, save current huffman tree item. */
+ if (++bit_count == 7) {
+ p_item2 = p_item1;
+ }
+ } while (p_item1->child != NULL);
+
+ /* no quick decompression. :( */
+ if (has_qd == FALSE) {
+
+ /* check bit counter. */
+ if (bit_count > 7) {
+ qd->offs00 = ht->offs0004;
+ qd->bits = bit_count;
+ qd->p_item = p_item2;
+ } else {
+ uint32_t index = n7bits & (0xFFFFFFFF >> (32 - bit_count));
+ uint32_t add = (1 << bit_count);
+
+ /* loop through compression. */
+ for (qd = &ht->qd3474[index]; index <= 0x7F; index += add, qd += add) {
+ qd->offs00 = ht->offs0004;
+ qd->bits = bit_count;
+ qd->dcmp_byte = p_item1->dcmp_byte;
+ }
+ }
+ }
+
+ /* set compression byte. */
+ dcmp_byte = p_item1->dcmp_byte;
+ }
+
+ /* check if huffman tree needs to be modified. */
+ if (dcmp_byte == 0x101) {
+
+ /* fill values. */
+ n8bits = libmpq__huffman_get_8bit(is);
+ p_item1 = (ht->last <= 0) ? NULL : ht->last;
+ p_item2 = libmpq__huffman_call_1500E740(ht);
+ p_item2->parent = p_item1;
+ p_item2->dcmp_byte = p_item1->dcmp_byte;
+ p_item2->byte_value = p_item1->byte_value;
+ ht->items306C[p_item2->dcmp_byte] = p_item2;
+ p_item2 = libmpq__huffman_call_1500E740(ht);
+ p_item2->parent = p_item1;
+ p_item2->dcmp_byte = n8bits;
+ p_item2->byte_value = 0;
+ ht->items306C[p_item2->dcmp_byte] = p_item2;
+ p_item1->child = p_item2;
+
+ /* call 1500E820. */
+ libmpq__huffman_call_1500E820(ht, p_item2);
+
+ /* check if compression is not set. */
+ if (ht->cmp0 == 0) {
+ libmpq__huffman_call_1500E820(ht, ht->items306C[n8bits]);
+ }
+
+ /* set compression byte. */
+ dcmp_byte = n8bits;
+ }
+
+ /* check for compression. */
+ if (dcmp_byte == 0x100) {
+ break;
+ }
+
+ /* increase position by compression byte. */
+ *out_pos++ = (uint8_t)dcmp_byte;
+ if (--out_length == 0) {
+ break;
+ }
+
+ /* check if compression is not set. */
+ if (ht->cmp0) {
+ libmpq__huffman_call_1500E820(ht, ht->items306C[dcmp_byte]);
+ }
+ }
+
+ /* return copied bytes. */
+ return (out_pos - out_buf);
+}
diff --git a/contrib/libmpq/libmpq/huffman.h b/contrib/libmpq/libmpq/huffman.h
new file mode 100644
index 00000000000..6f691088fa0
--- /dev/null
+++ b/contrib/libmpq/libmpq/huffman.h
@@ -0,0 +1,151 @@
+/*
+ * huffman.h -- structures used for huffman compression.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+ *
+ * This source was adepted from the C++ version of huffman.h included
+ * in stormlib. The C++ version belongs to the following authors:
+ *
+ * Ladislav Zezula <ladik@zezula.net>
+ * ShadowFlare <BlakFlare@hotmail.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.
+ */
+
+#ifndef _HUFFMAN_H
+#define _HUFFMAN_H
+
+/* define huffman compression and decompression values. */
+#define LIBMPQ_HUFF_DECOMPRESS 0 /* we want to decompress using huffman trees. */
+
+/* define pointer conversions. */
+#define PTR_NOT(ptr) (struct huffman_tree_item_s *)(~(unsigned long)(ptr))
+#define PTR_PTR(ptr) ((struct huffman_tree_item_s *)(ptr))
+#define PTR_INT(ptr) (long)(ptr)
+
+/* define item handling. */
+#define INSERT_ITEM 1 /* insert item into huffman tree. */
+#define SWITCH_ITEMS 2 /* switch items isnide huffman tree. */
+
+/* input stream for huffman decompression. */
+struct huffman_input_stream_s {
+ uint8_t *in_buf; /* 00 - input data. */
+ uint32_t bit_buf; /* 04 - input bit buffer. */
+ uint32_t bits; /* 08 - number of bits remaining in byte. */
+};
+
+/* huffman tree item. */
+struct huffman_tree_item_s {
+ struct huffman_tree_item_s *next; /* 00 - pointer to next huffman tree item. */
+ struct huffman_tree_item_s *prev; /* 04 - pointer to prev huffman tree item (< 0 if none). */
+ uint32_t dcmp_byte; /* 08 - index of this item in item pointer array, decompressed byte value. */
+ uint32_t byte_value; /* 0C - some byte value. */
+ struct huffman_tree_item_s *parent; /* 10 - pointer to parent huffman tree item (NULL if none). */
+ struct huffman_tree_item_s *child; /* 14 - pointer to child huffman tree item. */
+};
+
+/* structure used for quick decompression. */
+struct huffman_decompress_s {
+ uint32_t offs00; /* 00 - 1 if resolved. */
+ uint32_t bits; /* 04 - bit count. */
+ union {
+ uint32_t dcmp_byte; /* 08 - byte value for decompress (if bitCount <= 7). */
+ struct huffman_tree_item_s *p_item; /* 08 - huffman tree item (if number of bits is greater than 7). */
+ };
+};
+
+/* structure for huffman tree. */
+struct huffman_tree_s {
+ uint32_t cmp0; /* 0000 - 1 if compression type 0. */
+ uint32_t offs0004; /* 0004 - some flag. */
+ struct huffman_tree_item_s items0008[0x203]; /* 0008 - huffman tree items. */
+ struct huffman_tree_item_s *item3050; /* 3050 - always NULL? */
+ struct huffman_tree_item_s *item3054; /* 3054 - pointer to huffman tree item. */
+ struct huffman_tree_item_s *item3058; /* 3058 - pointer to huffman tree item (< 0 if invalid). */
+ struct huffman_tree_item_s *item305C; /* 305C - usually NULL. */
+ struct huffman_tree_item_s *first; /* 3060 - pointer to top (first) huffman tree item. */
+ struct huffman_tree_item_s *last; /* 3064 - pointer to bottom (last) huffman tree item (< 0 if invalid). */
+ uint32_t items; /* 3068 - number of used huffman tree items. */
+ struct huffman_tree_item_s *items306C[0x102]; /* 306C - huffman tree item pointer array. */
+ struct huffman_decompress_s qd3474[0x80]; /* 3474 - array for quick decompression. */
+ uint8_t table_1502A630[]; /* some table to make struct size flexible. */
+};
+
+/* insert a new item into huffman tree. */
+void libmpq__huffman_insert_item(
+ struct huffman_tree_item_s **p_item,
+ struct huffman_tree_item_s *item,
+ uint32_t where,
+ struct huffman_tree_item_s *item2
+);
+
+/* remove item from huffman tree. */
+void libmpq__huffman_remove_item(
+ struct huffman_tree_item_s *hi
+);
+
+/* get previous item from huffman tree. */
+struct huffman_tree_item_s *libmpq__huffman_previous_item(
+ struct huffman_tree_item_s *hi,
+ long value
+);
+
+/* get one bit from stream. */
+uint32_t libmpq__huffman_get_1bit(
+ struct huffman_input_stream_s *is
+);
+
+/* get seven bit from stream. */
+uint32_t libmpq__huffman_get_7bit(
+ struct huffman_input_stream_s *is
+);
+
+/* get eight bit from stream. */
+uint32_t libmpq__huffman_get_8bit(
+ struct huffman_input_stream_s *is
+);
+
+/* call 1500E740. */
+struct huffman_tree_item_s *libmpq__huffman_call_1500E740(
+ struct huffman_tree_s *ht
+);
+
+/* call 1500E820- */
+void libmpq__huffman_call_1500E820(
+ struct huffman_tree_s *ht,
+ struct huffman_tree_item_s *p_item
+);
+
+/* initialize the huffman tree. */
+void libmpq__huffman_tree_init(
+ struct huffman_tree_s *ht,
+ uint32_t cmp
+);
+
+/* build the huffman tree. */
+void libmpq__huffman_tree_build(
+ struct huffman_tree_s *ht,
+ uint32_t cmp_type
+);
+
+/* decompress the stream using huffman compression. */
+int32_t libmpq__do_decompress_huffman(
+ struct huffman_tree_s *ht,
+ struct huffman_input_stream_s *is,
+ uint8_t *out_buf,
+ uint32_t out_length
+);
+
+#endif /* _HUFFMAN_H */
diff --git a/contrib/libmpq/libmpq/mpq-internal.h b/contrib/libmpq/libmpq/mpq-internal.h
new file mode 100644
index 00000000000..eddcb7e89ae
--- /dev/null
+++ b/contrib/libmpq/libmpq/mpq-internal.h
@@ -0,0 +1,155 @@
+/*
+ * mpq-internal.h -- some default types and defines, but only required for
+ * compilation of the library.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.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 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 _MPQ_INTERNAL_H
+#define _MPQ_INTERNAL_H
+
+/* generic includes. */
+#include <stdint.h>
+#include <stdio.h>
+
+/* define return value if nothing failed. */
+#define LIBMPQ_SUCCESS 0 /* return value for all functions which success. */
+
+/* define generic mpq archive information. */
+#define LIBMPQ_HEADER 0x1A51504D /* mpq archive header ('MPQ\x1A') */
+
+/* define the known archive versions. */
+#define LIBMPQ_ARCHIVE_VERSION_ONE 0 /* version one used until world of warcraft. */
+#define LIBMPQ_ARCHIVE_VERSION_TWO 1 /* version two used from world of warcraft - the burning crusade. */
+
+/* define values used by blizzard as flags. */
+#define LIBMPQ_FLAG_EXISTS 0x80000000 /* set if file exists, reset when the file was deleted. */
+#define LIBMPQ_FLAG_ENCRYPTED 0x00010000 /* indicates whether file is encrypted. */
+#define LIBMPQ_FLAG_COMPRESSED 0x0000FF00 /* file is compressed. */
+#define LIBMPQ_FLAG_COMPRESS_PKZIP 0x00000100 /* compression made by pkware data compression library. */
+#define LIBMPQ_FLAG_COMPRESS_MULTI 0x00000200 /* multiple compressions. */
+#define LIBMPQ_FLAG_COMPRESS_NONE 0x00000300 /* no compression (no blizzard flag used by myself). */
+#define LIBMPQ_FLAG_SINGLE 0x01000000 /* file is stored in one single sector, first seen in world of warcraft. */
+#define LIBMPQ_FLAG_EXTRA 0x04000000 /* compressed block offset table has one extra entry. */
+
+/* define generic hash values. */
+#define LIBMPQ_HASH_FREE 0xFFFFFFFF /* hash table entry is empty and has always been empty. */
+
+/* define special files. */
+#define LIBMPQ_LISTFILE_NAME "(listfile)" /* internal listfile. */
+#define LIBMPQ_SIGNATURE_NAME "(signature)" /* internal signature file. */
+#define LIBMPQ_ATTRIBUTES_NAME "(attributes)" /* internal attributes file. */
+
+/* define true and false, because not all systems have them. */
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifdef _MSC_VER
+ #pragma pack(push,1)
+ #define PACK_STRUCT
+#else
+ #define PACK_STRUCT __attribute__((packed))
+#endif
+
+/* mpq archive header. */
+typedef struct {
+ uint32_t mpq_magic; /* the 0x1A51504D ('MPQ\x1A') signature. */
+ uint32_t header_size; /* mpq archive header size. */
+ uint32_t archive_size; /* size of mpq archive. */
+ uint16_t version; /* 0000 for starcraft and broodwar. */
+ uint16_t block_size; /* size of file block is (512 * 2 ^ block size). */
+ uint32_t hash_table_offset; /* file position of mpq_hash. */
+ uint32_t block_table_offset; /* file position of mpq_block, each entry has 16 bytes. */
+ uint32_t hash_table_count; /* number of entries in hash table. */
+ uint32_t block_table_count; /* number of entries in the block table. */
+} PACK_STRUCT mpq_header_s;
+
+/* mpq extended archive header, used since world of warcraft - the burning crusade. */
+typedef struct {
+ uint64_t extended_offset; /* offset to the beginning of the extended block table, relative to the beginning of the archive. */
+ uint16_t hash_table_offset_high; /* upper 16 bits of the hash table offset for large archives. */
+ uint16_t block_table_offset_high;/* upper 16 bits of the block table offset for large archives.*/
+} PACK_STRUCT mpq_header_ex_s;
+
+/* hash entry, all files in the archive are searched by their hashes. */
+typedef struct {
+ uint32_t hash_a; /* the first two uint32_ts are the encrypted file. */
+ uint32_t hash_b; /* the first two uint32_ts are the encrypted file. */
+ uint16_t locale; /* locale information. */
+ uint16_t platform; /* platform information and zero is default. */
+ uint32_t block_table_index; /* index to file description block. */
+} PACK_STRUCT mpq_hash_s;
+
+/* file description block contains informations about the file. */
+typedef struct {
+ uint32_t offset; /* block file starting position in the archive. */
+ uint32_t packed_size; /* packed file size. */
+ uint32_t unpacked_size; /* unpacked file size. */
+ uint32_t flags; /* flags. */
+} PACK_STRUCT mpq_block_s;
+
+/* extended file description block contains information about the offset beyond 2^32 (4GB). */
+typedef struct {
+ uint16_t offset_high; /* upper 16 bit of the file offset in archive. */
+} PACK_STRUCT mpq_block_ex_s;
+
+/* file structure used since diablo 1.00 (0x38 bytes). */
+typedef struct {
+ uint32_t seed; /* seed used for file decrypt. */
+ uint32_t *packed_offset; /* position of each file block (only for packed files). */
+ uint32_t open_count; /* number of times it has been opened - used for freeing */
+} PACK_STRUCT mpq_file_s;
+
+/* map structure for valid blocks and hashes (first seen in warcraft 3 archives). */
+typedef struct {
+ uint32_t block_table_indices; /* real mapping for file number to block entry. */
+ uint32_t block_table_diff; /* block table difference between valid blocks and invalid blocks before. */
+} PACK_STRUCT mpq_map_s;
+
+#ifdef _MSC_VER
+ #pragma pack(pop)
+#endif
+#undef PACK_STRUCT
+
+/* archive structure used since diablo 1.00 by blizzard. */
+struct mpq_archive {
+
+ /* generic file information. */
+ FILE *fp; /* file handle. */
+
+ /* generic size information. */
+ uint32_t block_size; /* size of the mpq block. */
+ off_t archive_offset; /* absolute start position of archive. */
+
+ /* archive related buffers and tables. */
+ mpq_header_s mpq_header; /* mpq file header. */
+ mpq_header_ex_s mpq_header_ex; /* mpq extended file header. */
+ mpq_hash_s *mpq_hash; /* hash table. */
+ mpq_block_s *mpq_block; /* block table. */
+ mpq_block_ex_s *mpq_block_ex; /* extended block table. */
+ mpq_file_s **mpq_file; /* pointer to the file pointers which are opened. */
+
+ /* non archive structure related members. */
+ mpq_map_s *mpq_map; /* map table between valid blocks and hashes. */
+ uint32_t files; /* number of files in archive, which could be extracted. */
+};
+
+#endif /* _MPQ_INTERNAL_H */
diff --git a/contrib/libmpq/libmpq/mpq.c b/contrib/libmpq/libmpq/mpq.c
new file mode 100644
index 00000000000..4e3d7db0b4d
--- /dev/null
+++ b/contrib/libmpq/libmpq/mpq.c
@@ -0,0 +1,1033 @@
+/*
+ * mpq.c -- functions for developers using libmpq.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.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 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.
+ */
+
+/* mpq-tools configuration includes. */
+#include "config.h"
+
+/* libmpq main includes. */
+#include "mpq.h"
+#include "mpq-internal.h"
+
+/* libmpq generic includes. */
+#include "common.h"
+
+/* generic includes. */
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#if HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+
+#ifdef _MSC_VER
+ #define fseeko _fseeki64
+#endif
+
+/* this function returns the library version information. */
+const char *libmpq__version(void) {
+
+ /* return version information. */
+ return VERSION;
+}
+
+/* this function read a file and verify if it is a valid mpq archive, then it read and decrypt the hash table. */
+int32_t libmpq__archive_open(mpq_archive_s **mpq_archive, const char *mpq_filename, libmpq__off_t archive_offset) {
+
+ /* some common variables. */
+ uint32_t rb = 0;
+ uint32_t i = 0;
+ uint32_t count = 0;
+ int32_t result = 0;
+ uint32_t header_search = FALSE;
+
+ if (archive_offset == -1) {
+ archive_offset = 0;
+ header_search = TRUE;
+ }
+
+ if ((*mpq_archive = calloc(1, sizeof(mpq_archive_s))) == NULL) {
+
+ /* archive struct could not be allocated */
+ return LIBMPQ_ERROR_MALLOC;
+ }
+
+ /* check if file exists and is readable */
+ if (((*mpq_archive)->fp = fopen(mpq_filename, "rb")) == NULL) {
+
+ /* file could not be opened. */
+ result = LIBMPQ_ERROR_OPEN;
+ goto error;
+ }
+
+ /* assign some default values. */
+ (*mpq_archive)->mpq_header.mpq_magic = 0;
+ (*mpq_archive)->files = 0;
+
+ /* loop through file and search for mpq signature. */
+ while (TRUE) {
+
+ /* reset header values. */
+ (*mpq_archive)->mpq_header.mpq_magic = 0;
+
+ /* seek in file. */
+ if (fseeko((*mpq_archive)->fp, archive_offset, SEEK_SET) < 0) {
+
+ /* seek in file failed. */
+ result = LIBMPQ_ERROR_SEEK;
+ goto error;
+ }
+
+ /* read header from file. */
+ if ((rb = fread(&(*mpq_archive)->mpq_header, 1, sizeof(mpq_header_s), (*mpq_archive)->fp)) != sizeof(mpq_header_s)) {
+
+ /* no valid mpq archive. */
+ result = LIBMPQ_ERROR_FORMAT;
+ goto error;
+ }
+
+ /* check if we found a valid mpq header. */
+ if ((*mpq_archive)->mpq_header.mpq_magic == LIBMPQ_HEADER) {
+
+ /* check if we process old mpq archive version. */
+ if ((*mpq_archive)->mpq_header.version == LIBMPQ_ARCHIVE_VERSION_ONE) {
+
+ /* check if the archive is protected. */
+ if ((*mpq_archive)->mpq_header.header_size != sizeof(mpq_header_s)) {
+
+ /* correct header size. */
+ (*mpq_archive)->mpq_header.header_size = sizeof(mpq_header_s);
+ }
+ }
+
+ /* check if we process new mpq archive version. */
+ if ((*mpq_archive)->mpq_header.version == LIBMPQ_ARCHIVE_VERSION_TWO) {
+
+ /* check if the archive is protected. */
+ if ((*mpq_archive)->mpq_header.header_size != sizeof(mpq_header_s) + sizeof(mpq_header_ex_s)) {
+
+ /* correct header size. */
+ (*mpq_archive)->mpq_header.header_size = sizeof(mpq_header_s) + sizeof(mpq_header_ex_s);
+ }
+ }
+
+ /* break the loop, because header was found. */
+ break;
+ }
+
+ /* move to the next possible offset. */
+ if (!header_search) {
+
+ /* no valid mpq archive. */
+ result = LIBMPQ_ERROR_FORMAT;
+ goto error;
+ }
+ archive_offset += 512;
+ }
+
+ /* store block size for later use. */
+ (*mpq_archive)->block_size = 512 << (*mpq_archive)->mpq_header.block_size;
+
+ /* store archive offset and size for later use. */
+ (*mpq_archive)->archive_offset = archive_offset;
+
+ /* check if we process new mpq archive version. */
+ if ((*mpq_archive)->mpq_header.version == LIBMPQ_ARCHIVE_VERSION_TWO) {
+
+ /* seek in file. */
+ if (fseeko((*mpq_archive)->fp, sizeof(mpq_header_s) + archive_offset, SEEK_SET) < 0) {
+
+ /* seek in file failed. */
+ result = LIBMPQ_ERROR_SEEK;
+ goto error;
+ }
+
+ /* read header from file. */
+ if ((rb = fread(&(*mpq_archive)->mpq_header_ex, 1, sizeof(mpq_header_ex_s), (*mpq_archive)->fp)) != sizeof(mpq_header_ex_s)) {
+
+ /* no valid mpq archive. */
+ result = LIBMPQ_ERROR_FORMAT;
+ goto error;
+ }
+ }
+
+ /* allocate memory for the block table, hash table, file and block table to file mapping. */
+ if (((*mpq_archive)->mpq_block = calloc((*mpq_archive)->mpq_header.block_table_count, sizeof(mpq_block_s))) == NULL ||
+ ((*mpq_archive)->mpq_block_ex = calloc((*mpq_archive)->mpq_header.block_table_count, sizeof(mpq_block_ex_s))) == NULL ||
+ ((*mpq_archive)->mpq_hash = calloc((*mpq_archive)->mpq_header.hash_table_count, sizeof(mpq_hash_s))) == NULL ||
+ ((*mpq_archive)->mpq_file = calloc((*mpq_archive)->mpq_header.block_table_count, sizeof(mpq_file_s))) == NULL ||
+ ((*mpq_archive)->mpq_map = calloc((*mpq_archive)->mpq_header.block_table_count, sizeof(mpq_map_s))) == NULL) {
+
+ /* memory allocation problem. */
+ result = LIBMPQ_ERROR_MALLOC;
+ goto error;
+ }
+
+ /* seek in file. */
+ if (fseeko((*mpq_archive)->fp, (*mpq_archive)->mpq_header.hash_table_offset + (((long long)((*mpq_archive)->mpq_header_ex.hash_table_offset_high)) << 32) + (*mpq_archive)->archive_offset, SEEK_SET) < 0) {
+
+ /* seek in file failed. */
+ result = LIBMPQ_ERROR_SEEK;
+ goto error;
+ }
+
+ /* read the hash table into the buffer. */
+ if ((rb = fread((*mpq_archive)->mpq_hash, 1, (*mpq_archive)->mpq_header.hash_table_count * sizeof(mpq_hash_s), (*mpq_archive)->fp)) < 0) {
+
+ /* something on read failed. */
+ result = LIBMPQ_ERROR_READ;
+ goto error;
+ }
+
+ /* decrypt the hashtable. */
+ libmpq__decrypt_block((uint32_t *)((*mpq_archive)->mpq_hash), (*mpq_archive)->mpq_header.hash_table_count * sizeof(mpq_hash_s), libmpq__hash_string("(hash table)", 0x300));
+
+ /* seek in file. */
+ if (fseeko((*mpq_archive)->fp, (*mpq_archive)->mpq_header.block_table_offset + (((long long)((*mpq_archive)->mpq_header_ex.block_table_offset_high)) << 32) + (*mpq_archive)->archive_offset, SEEK_SET) < 0) {
+
+ /* seek in file failed. */
+ result = LIBMPQ_ERROR_SEEK;
+ goto error;
+ }
+
+ /* read the block table into the buffer. */
+ if ((rb = fread((*mpq_archive)->mpq_block, 1, (*mpq_archive)->mpq_header.block_table_count * sizeof(mpq_block_s), (*mpq_archive)->fp)) < 0) {
+
+ /* something on read failed. */
+ result = LIBMPQ_ERROR_READ;
+ goto error;
+ }
+
+ /* decrypt block table. */
+ libmpq__decrypt_block((uint32_t *)((*mpq_archive)->mpq_block), (*mpq_archive)->mpq_header.block_table_count * sizeof(mpq_block_s), libmpq__hash_string("(block table)", 0x300));
+
+ /* check if extended block table is present, regardless of version 2 it is only present in archives > 4GB. */
+ if ((*mpq_archive)->mpq_header_ex.extended_offset > 0) {
+
+ /* seek in file. */
+ if (fseeko((*mpq_archive)->fp, (*mpq_archive)->mpq_header_ex.extended_offset + archive_offset, SEEK_SET) < 0) {
+
+ /* seek in file failed. */
+ result = LIBMPQ_ERROR_SEEK;
+ goto error;
+ }
+
+ /* read header from file. */
+ if ((rb = fread((*mpq_archive)->mpq_block_ex, 1, (*mpq_archive)->mpq_header.block_table_count * sizeof(mpq_block_ex_s), (*mpq_archive)->fp)) < 0) {
+
+ /* no valid mpq archive. */
+ result = LIBMPQ_ERROR_FORMAT;
+ goto error;
+ }
+ }
+
+ /* loop through all files in mpq archive and check if they are valid. */
+ for (i = 0; i < (*mpq_archive)->mpq_header.block_table_count; i++) {
+
+ /* save block difference between valid and invalid blocks. */
+ (*mpq_archive)->mpq_map[i].block_table_diff = i - count;
+
+ /* check if file exists, sizes and offsets are correct. */
+ if (((*mpq_archive)->mpq_block[i].flags & LIBMPQ_FLAG_EXISTS) == 0) {
+
+ /* file does not exist, so nothing to do with that block. */
+ continue;
+ }
+
+ /* create final indices tables. */
+ (*mpq_archive)->mpq_map[count].block_table_indices = i;
+
+ /* increase file counter. */
+ count++;
+ }
+
+ /* save the number of files. */
+ (*mpq_archive)->files = count;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+
+error:
+ if ((*mpq_archive)->fp)
+ fclose((*mpq_archive)->fp);
+
+ free((*mpq_archive)->mpq_map);
+ free((*mpq_archive)->mpq_file);
+ free((*mpq_archive)->mpq_hash);
+ free((*mpq_archive)->mpq_block);
+ free((*mpq_archive)->mpq_block_ex);
+ free(*mpq_archive);
+
+ *mpq_archive = NULL;
+
+ return result;
+}
+
+/* this function close the file descriptor, free the decryption buffer and the file list. */
+int32_t libmpq__archive_close(mpq_archive_s *mpq_archive) {
+
+ /* try to close the file */
+ if ((fclose(mpq_archive->fp)) < 0) {
+
+ /* don't free anything here, so the caller can try calling us
+ * again.
+ */
+ return LIBMPQ_ERROR_CLOSE;
+ }
+
+ /* free header, tables and list. */
+ free(mpq_archive->mpq_map);
+ free(mpq_archive->mpq_file);
+ free(mpq_archive->mpq_hash);
+ free(mpq_archive->mpq_block);
+ free(mpq_archive->mpq_block_ex);
+ free(mpq_archive);
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the packed size of all files in the archive. */
+int32_t libmpq__archive_packed_size(mpq_archive_s *mpq_archive, libmpq__off_t *packed_size) {
+
+ /* some common variables. */
+ uint32_t i;
+
+ /* loop through all files in archive and count packed size. */
+ for (i = 0; i < mpq_archive->files; i++) {
+ *packed_size += mpq_archive->mpq_block[mpq_archive->mpq_map[i].block_table_indices].packed_size;
+ }
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the unpacked size of all files in the archive. */
+int32_t libmpq__archive_unpacked_size(mpq_archive_s *mpq_archive, libmpq__off_t *unpacked_size) {
+
+ /* some common variables. */
+ uint32_t i;
+
+ /* loop through all files in archive and count unpacked size. */
+ for (i = 0; i < mpq_archive->files; i++) {
+ *unpacked_size += mpq_archive->mpq_block[mpq_archive->mpq_map[i].block_table_indices].unpacked_size;
+ }
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the archive offset (beginning of archive in file). */
+int32_t libmpq__archive_offset(mpq_archive_s *mpq_archive, libmpq__off_t *offset) {
+
+ /* return archive offset. */
+ *offset = mpq_archive->archive_offset;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the archive offset. */
+int32_t libmpq__archive_version(mpq_archive_s *mpq_archive, uint32_t *version) {
+
+ /* return archive version. */
+ *version = mpq_archive->mpq_header.version + 1;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the number of valid files in archive. */
+int32_t libmpq__archive_files(mpq_archive_s *mpq_archive, uint32_t *files) {
+
+ /* return archive version. */
+ *files = mpq_archive->files;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the packed size of the given files in the archive. */
+int32_t libmpq__file_packed_size(mpq_archive_s *mpq_archive, uint32_t file_number, libmpq__off_t *packed_size) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* get the packed size of file. */
+ *packed_size = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].packed_size;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the unpacked size of the given file in the archive. */
+int32_t libmpq__file_unpacked_size(mpq_archive_s *mpq_archive, uint32_t file_number, libmpq__off_t *unpacked_size) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* get the unpacked size of file. */
+ *unpacked_size = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the file offset (beginning of file in archive). */
+int32_t libmpq__file_offset(mpq_archive_s *mpq_archive, uint32_t file_number, libmpq__off_t *offset) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* return file offset relative to archive start. */
+ *offset = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].offset + (((long long)mpq_archive->mpq_block_ex[mpq_archive->mpq_map[file_number].block_table_indices].offset_high) << 32);
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the number of blocks for the given file in the archive. */
+int32_t libmpq__file_blocks(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *blocks) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* return the number of blocks for the given file. */
+ *blocks = (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) != 0 ? 1 : (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return if the file is encrypted or not. */
+int32_t libmpq__file_encrypted(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *encrypted) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* return the encryption status of file. */
+ *encrypted = (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_ENCRYPTED) != 0 ? TRUE : FALSE;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return if the file is compressed or not. */
+int32_t libmpq__file_compressed(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *compressed) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* return the compression status of file. */
+ *compressed = (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_COMPRESS_MULTI) != 0 ? TRUE : FALSE;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return if the file is imploded or not. */
+int32_t libmpq__file_imploded(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *imploded) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* return the implosion status of file. */
+ *imploded = (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_COMPRESS_PKZIP) != 0 ? TRUE : FALSE;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return filenumber by the given name. */
+int32_t libmpq__file_number(mpq_archive_s *mpq_archive, const char *filename, uint32_t *number) {
+
+ /* some common variables. */
+ uint32_t i, hash1, hash2, hash3, ht_count;
+
+ /* if the list of file names doesn't include this one, we'll have
+ * to figure out the file number the "hard" way.
+ */
+ ht_count = mpq_archive->mpq_header.hash_table_count;
+
+ hash1 = libmpq__hash_string (filename, 0x0) & (ht_count - 1);
+ hash2 = libmpq__hash_string (filename, 0x100);
+ hash3 = libmpq__hash_string (filename, 0x200);
+
+ /* loop through all files in mpq archive.
+ * hash1 gives us a clue about the starting position of this
+ * search.
+ */
+ for (i = hash1; mpq_archive->mpq_hash[i].block_table_index != LIBMPQ_HASH_FREE; i = (i + 1) & (ht_count - 1)) {
+
+ /* if the other two hashes match, we found our file number. */
+ if (mpq_archive->mpq_hash[i].hash_a == hash2 &&
+ mpq_archive->mpq_hash[i].hash_b == hash3) {
+
+ /* return the file number. */
+ *number = mpq_archive->mpq_hash[i].block_table_index - mpq_archive->mpq_map[mpq_archive->mpq_hash[i].block_table_index].block_table_diff;
+
+ /* we found our file, return zero. */
+ return LIBMPQ_SUCCESS;
+ }
+
+ /* check if we have cycled through the whole hash table */
+ if (((i + 1) & (ht_count - 1)) == hash1) {
+ break;
+ }
+ }
+
+ /* if no matching entry found, so return error. */
+ return LIBMPQ_ERROR_EXIST;
+}
+
+/* this function read the given file from archive into a buffer. */
+int32_t libmpq__file_read(mpq_archive_s *mpq_archive, uint32_t file_number, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred) {
+
+ /* some common variables. */
+ uint32_t i;
+ uint32_t blocks = 0;
+ int32_t result = 0;
+ libmpq__off_t file_offset = 0;
+ libmpq__off_t unpacked_size = 0;
+ libmpq__off_t transferred_block = 0;
+ libmpq__off_t transferred_total = 0;
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* get target size of block. */
+ libmpq__file_unpacked_size(mpq_archive, file_number, &unpacked_size);
+
+ /* check if target buffer is to small. */
+ if (unpacked_size > out_size) {
+
+ /* output buffer size is to small or block size is unknown. */
+ return LIBMPQ_ERROR_SIZE;
+ }
+
+ /* fetch file offset. */
+ libmpq__file_offset(mpq_archive, file_number, &file_offset);
+
+ /* get block count for file. */
+ libmpq__file_blocks(mpq_archive, file_number, &blocks);
+
+ /* open the packed block offset table. */
+ if ((result = libmpq__block_open_offset(mpq_archive, file_number)) < 0) {
+
+ /* something on opening packed block offset table failed. */
+ return result;
+ }
+
+ /* loop through all blocks. */
+ for (i = 0; i < blocks; i++) {
+
+ /* cleanup size variable. */
+ unpacked_size = 0;
+
+ /* get unpacked block size. */
+ libmpq__block_unpacked_size(mpq_archive, file_number, i, &unpacked_size);
+
+ /* read block. */
+ if ((result = libmpq__block_read(mpq_archive, file_number, i, out_buf + transferred_total, unpacked_size, &transferred_block)) < 0) {
+
+ /* close the packed block offset table. */
+ libmpq__block_close_offset(mpq_archive, file_number);
+
+ /* something on reading block failed. */
+ return result;
+ }
+
+ transferred_total += transferred_block;
+
+ }
+
+ /* close the packed block offset table. */
+ libmpq__block_close_offset(mpq_archive, file_number);
+
+ /* check for null pointer. */
+ if (transferred != NULL) {
+
+ /* store transferred bytes. */
+ *transferred = transferred_total;
+ }
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function open a file in the given archive and caches the block offset information. */
+int32_t libmpq__block_open_offset(mpq_archive_s *mpq_archive, uint32_t file_number) {
+
+ /* some common variables. */
+ uint32_t i;
+ uint32_t packed_size;
+ int32_t rb = 0;
+ int32_t result = 0;
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ if (mpq_archive->mpq_file[file_number]) {
+
+ /* file already opened, so increment counter */
+ mpq_archive->mpq_file[file_number]->open_count++;
+ return LIBMPQ_SUCCESS;
+ }
+
+ /* check if file is not stored in a single sector. */
+ if ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) == 0) {
+
+ /* get packed size based on block size and block count. */
+ packed_size = sizeof(uint32_t) * (((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size) + 1);
+ } else {
+
+ /* file is stored in single sector and we need only two entries for the packed block offset table. */
+ packed_size = sizeof(uint32_t) * 2;
+ }
+
+ /* check if data has one extra entry. */
+ if ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_EXTRA) != 0) {
+
+ /* add one uint32_t. */
+ packed_size += sizeof(uint32_t);
+ }
+
+ /* allocate memory for the file. */
+ if ((mpq_archive->mpq_file[file_number] = calloc(1, sizeof(mpq_file_s))) == NULL) {
+
+ /* memory allocation problem. */
+ result = LIBMPQ_ERROR_MALLOC;
+ goto error;
+ }
+
+ /* allocate memory for the packed block offset table. */
+ if ((mpq_archive->mpq_file[file_number]->packed_offset = calloc(1, packed_size)) == NULL) {
+
+ /* memory allocation problem. */
+ result = LIBMPQ_ERROR_MALLOC;
+ goto error;
+ }
+
+ /* initialize counter to one opening */
+ mpq_archive->mpq_file[file_number]->open_count = 1;
+
+ /* check if we need to load the packed block offset table, we will maintain this table for unpacked files too. */
+ if ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_COMPRESSED) != 0 &&
+ (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) == 0) {
+
+ /* seek to block position. */
+ if (fseeko(mpq_archive->fp, mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].offset + (((long long)mpq_archive->mpq_block_ex[mpq_archive->mpq_map[file_number].block_table_indices].offset_high) << 32) + mpq_archive->archive_offset, SEEK_SET) < 0) {
+
+ /* seek in file failed. */
+ result = LIBMPQ_ERROR_SEEK;
+ goto error;
+ }
+
+ /* read block positions from begin of file. */
+ if ((rb = fread(mpq_archive->mpq_file[file_number]->packed_offset, 1, packed_size, mpq_archive->fp)) < 0) {
+
+ /* something on read from archive failed. */
+ result = LIBMPQ_ERROR_READ;
+ goto error;
+ }
+
+ /* check if the archive is protected some way, sometimes the file appears not to be encrypted, but it is. */
+ if (mpq_archive->mpq_file[file_number]->packed_offset[0] != rb) {
+
+ /* file is encrypted. */
+ mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags |= LIBMPQ_FLAG_ENCRYPTED;
+ }
+
+ /* check if packed offset block is encrypted, we have to decrypt it. */
+ if (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_ENCRYPTED) {
+
+ /* check if we don't know the file seed, try to find it. */
+ if ((mpq_archive->mpq_file[file_number]->seed = libmpq__decrypt_key((uint8_t *)mpq_archive->mpq_file[file_number]->packed_offset, packed_size, mpq_archive->block_size)) < 0) {
+
+ /* sorry without seed, we cannot extract file. */
+ result = LIBMPQ_ERROR_DECRYPT;
+ goto error;
+ }
+
+ /* decrypt block in input buffer. */
+ if (libmpq__decrypt_block(mpq_archive->mpq_file[file_number]->packed_offset, packed_size, mpq_archive->mpq_file[file_number]->seed - 1) < 0 ) {
+
+ /* something on decrypt failed. */
+ result = LIBMPQ_ERROR_DECRYPT;
+ goto error;
+ }
+
+ /* check if the block positions are correctly decrypted. */
+ if (mpq_archive->mpq_file[file_number]->packed_offset[0] != packed_size) {
+
+ /* sorry without seed, we cannot extract file. */
+ result = LIBMPQ_ERROR_DECRYPT;
+ goto error;
+ }
+ }
+ } else {
+
+ /* check if file is not stored in a single sector. */
+ if ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) == 0) {
+
+ /* loop through all blocks and create packed block offset table based on block size. */
+ for (i = 0; i < ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size + 1); i++) {
+
+ /* check if we process the last block. */
+ if (i == ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size)) {
+
+ /* store size of last block. */
+ mpq_archive->mpq_file[file_number]->packed_offset[i] = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size;
+ } else {
+
+ /* store default block size. */
+ mpq_archive->mpq_file[file_number]->packed_offset[i] = i * mpq_archive->block_size;
+ }
+ }
+ } else {
+
+ /* store offsets. */
+ mpq_archive->mpq_file[file_number]->packed_offset[0] = 0;
+ mpq_archive->mpq_file[file_number]->packed_offset[1] = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].packed_size;
+ }
+ }
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+
+error:
+
+ /* free packed block offset table and file pointer. */
+ free(mpq_archive->mpq_file[file_number]->packed_offset);
+ free(mpq_archive->mpq_file[file_number]);
+
+ /* return error constant. */
+ return result;
+}
+
+/* this function free the file pointer to the opened file in archive. */
+int32_t libmpq__block_close_offset(mpq_archive_s *mpq_archive, uint32_t file_number) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ if (mpq_archive->mpq_file[file_number] == NULL) {
+
+ /* packed block offset table is not opened. */
+ return LIBMPQ_ERROR_OPEN;
+ }
+
+ mpq_archive->mpq_file[file_number]->open_count--;
+
+ if (mpq_archive->mpq_file[file_number]->open_count != 0) {
+
+ /* still in use */
+ return LIBMPQ_SUCCESS;
+ }
+
+ /* free packed block offset table and file pointer. */
+ free(mpq_archive->mpq_file[file_number]->packed_offset);
+ free(mpq_archive->mpq_file[file_number]);
+
+ /* mark it as unopened - libmpq__block_open_offset checks for this to decide whether to increment the counter */
+ mpq_archive->mpq_file[file_number] = NULL;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the unpacked size of the given file and block in the archive. */
+int32_t libmpq__block_unpacked_size(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t block_number, libmpq__off_t *unpacked_size) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* check if given block number is not out of range. */
+ if (block_number < 0 || block_number >= ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) != 0 ? 1 : (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size)) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* check if packed block offset table is opened. */
+ if (mpq_archive->mpq_file[file_number] == NULL ||
+ mpq_archive->mpq_file[file_number]->packed_offset == NULL) {
+
+ /* packed block offset table is not opened. */
+ return LIBMPQ_ERROR_OPEN;
+ }
+
+ /* check if block is stored as single sector. */
+ if ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) != 0) {
+
+ /* return the unpacked size of the block in the mpq archive. */
+ *unpacked_size = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size;
+ }
+
+ /* check if block is not stored as single sector. */
+ if ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) == 0) {
+
+ /* check if we not process the last block. */
+ if (block_number < ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size) - 1) {
+
+ /* return the block size as unpacked size. */
+ *unpacked_size = mpq_archive->block_size;
+ } else {
+
+ /* return the unpacked size of the last block in the mpq archive. */
+ *unpacked_size = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size - mpq_archive->block_size * block_number;
+ }
+ }
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function return the decryption seed for the given file and block. */
+int32_t libmpq__block_seed(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t block_number, uint32_t *seed) {
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* check if given block number is not out of range. */
+ if (block_number < 0 || block_number >= ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) != 0 ? 1 : (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size)) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* check if packed block offset table is opened. */
+ if (mpq_archive->mpq_file[file_number] == NULL ||
+ mpq_archive->mpq_file[file_number]->packed_offset == NULL) {
+
+ /* packed block offset table is not opened. */
+ return LIBMPQ_ERROR_OPEN;
+ }
+
+ /* return the decryption key. */
+ *seed = mpq_archive->mpq_file[file_number]->seed + block_number;
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
+
+/* this function read the given block from archive into a buffer. */
+int32_t libmpq__block_read(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t block_number, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred) {
+
+ /* some common variables. */
+ uint8_t *in_buf;
+ uint32_t seed = 0;
+ uint32_t encrypted = 0;
+ uint32_t compressed = 0;
+ uint32_t imploded = 0;
+ int32_t tb = 0;
+ libmpq__off_t block_offset = 0;
+ off_t in_size = 0;
+ libmpq__off_t unpacked_size = 0;
+
+ /* check if given file number is not out of range. */
+ if (file_number < 0 || file_number > mpq_archive->files - 1) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* check if given block number is not out of range. */
+ if (block_number < 0 || block_number >= ((mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].flags & LIBMPQ_FLAG_SINGLE) != 0 ? 1 : (mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].unpacked_size + mpq_archive->block_size - 1) / mpq_archive->block_size)) {
+
+ /* file number is out of range. */
+ return LIBMPQ_ERROR_EXIST;
+ }
+
+ /* check if packed block offset table is opened. */
+ if (mpq_archive->mpq_file[file_number] == NULL ||
+ mpq_archive->mpq_file[file_number]->packed_offset == NULL) {
+
+ /* packed block offset table is not opened. */
+ return LIBMPQ_ERROR_OPEN;
+ }
+
+ /* get target size of block. */
+ libmpq__block_unpacked_size(mpq_archive, file_number, block_number, &unpacked_size);
+
+ /* check if target buffer is to small. */
+ if (unpacked_size > out_size) {
+
+ /* output buffer size is to small or block size is unknown. */
+ return LIBMPQ_ERROR_SIZE;
+ }
+
+ /* fetch some required values like input buffer size and block offset. */
+ block_offset = mpq_archive->mpq_block[mpq_archive->mpq_map[file_number].block_table_indices].offset + (((long long)mpq_archive->mpq_block_ex[mpq_archive->mpq_map[file_number].block_table_indices].offset_high) << 32) + mpq_archive->mpq_file[file_number]->packed_offset[block_number];
+ in_size = mpq_archive->mpq_file[file_number]->packed_offset[block_number + 1] - mpq_archive->mpq_file[file_number]->packed_offset[block_number];
+
+ /* seek in file. */
+ if (fseeko(mpq_archive->fp, block_offset + mpq_archive->archive_offset, SEEK_SET) < 0) {
+
+ /* something with seek in file failed. */
+ return LIBMPQ_ERROR_SEEK;
+ }
+
+ /* allocate memory for the read buffer. */
+ if ((in_buf = calloc(1, in_size)) == NULL) {
+
+ /* memory allocation problem. */
+ return LIBMPQ_ERROR_MALLOC;
+ }
+
+ /* read block from file. */
+ if (fread(in_buf, 1, in_size, mpq_archive->fp) < 0) {
+
+ /* free buffers. */
+ free(in_buf);
+
+ /* something on reading block failed. */
+ return LIBMPQ_ERROR_READ;
+ }
+
+ /* get encryption status. */
+ libmpq__file_encrypted(mpq_archive, file_number, &encrypted);
+
+ /* check if file is encrypted. */
+ if (encrypted == 1) {
+
+ /* get decryption key. */
+ libmpq__block_seed(mpq_archive, file_number, block_number, &seed);
+
+ /* decrypt block. */
+ if (libmpq__decrypt_block((uint32_t *)in_buf, in_size, seed) < 0) {
+
+ /* free buffers. */
+ free(in_buf);
+
+ /* something on decrypting block failed. */
+ return LIBMPQ_ERROR_DECRYPT;
+ }
+ }
+
+ /* get compression status. */
+ libmpq__file_compressed(mpq_archive, file_number, &compressed);
+
+ /* check if file is compressed. */
+ if (compressed == 1) {
+
+ /* decompress block. */
+ if ((tb = libmpq__decompress_block(in_buf, in_size, out_buf, out_size, LIBMPQ_FLAG_COMPRESS_MULTI)) < 0) {
+
+ /* free temporary buffer. */
+ free(in_buf);
+
+ /* something on decompressing block failed. */
+ return LIBMPQ_ERROR_UNPACK;
+ }
+ }
+
+ /* get implosion status. */
+ libmpq__file_imploded(mpq_archive, file_number, &imploded);
+
+ /* check if file is imploded. */
+ if (imploded == 1) {
+
+ /* explode block. */
+ if ((tb = libmpq__decompress_block(in_buf, in_size, out_buf, out_size, LIBMPQ_FLAG_COMPRESS_PKZIP)) < 0) {
+
+ /* free temporary buffer. */
+ free(in_buf);
+
+ /* something on decompressing block failed. */
+ return LIBMPQ_ERROR_UNPACK;
+ }
+ }
+
+ /* check if file is neither compressed nor imploded. */
+ if (compressed == 0 && imploded == 0) {
+
+ /* copy block. */
+ if ((tb = libmpq__decompress_block(in_buf, in_size, out_buf, out_size, LIBMPQ_FLAG_COMPRESS_NONE)) < 0) {
+
+ /* free temporary buffer. */
+ free(in_buf);
+
+ /* something on decompressing block failed. */
+ return LIBMPQ_ERROR_UNPACK;
+ }
+ }
+
+ /* free read buffer. */
+ free(in_buf);
+
+ /* check for null pointer. */
+ if (transferred != NULL) {
+
+ /* store transferred bytes. */
+ *transferred = tb;
+ }
+
+ /* if no error was found, return zero. */
+ return LIBMPQ_SUCCESS;
+}
diff --git a/contrib/libmpq/libmpq/mpq.h b/contrib/libmpq/libmpq/mpq.h
new file mode 100644
index 00000000000..3d53e06477c
--- /dev/null
+++ b/contrib/libmpq/libmpq/mpq.h
@@ -0,0 +1,98 @@
+/*
+ * mpq.h -- some default types and defines.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+ *
+ * Some parts (the encryption and decryption stuff) were adapted from
+ * the C++ version of StormLib.h and StormPort.h included in stormlib.
+ * The C++ version belongs to the following authors:
+ *
+ * Ladislav Zezula <ladik@zezula.net>
+ * Marko Friedemann <marko.friedemann@bmx-chemnitz.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 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 _MPQ_H
+#define _MPQ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* generic includes. */
+#include <stdint.h>
+#include <sys/types.h>
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+# define LIBMPQ_API __attribute__((visibility("default")))
+#else
+# define LIBMPQ_API
+#endif
+
+/* define errors. */
+#define LIBMPQ_ERROR_OPEN -1 /* open error on file. */
+#define LIBMPQ_ERROR_CLOSE -2 /* close error on file. */
+#define LIBMPQ_ERROR_SEEK -3 /* lseek error on file. */
+#define LIBMPQ_ERROR_READ -4 /* read error on file. */
+#define LIBMPQ_ERROR_WRITE -5 /* write error on file. */
+#define LIBMPQ_ERROR_MALLOC -6 /* memory allocation error. */
+#define LIBMPQ_ERROR_FORMAT -7 /* format errror. */
+#define LIBMPQ_ERROR_NOT_INITIALIZED -8 /* libmpq__init() wasn't called. */
+#define LIBMPQ_ERROR_SIZE -9 /* buffer size is to small. */
+#define LIBMPQ_ERROR_EXIST -10 /* file or block does not exist in archive. */
+#define LIBMPQ_ERROR_DECRYPT -11 /* we don't know the decryption seed. */
+#define LIBMPQ_ERROR_UNPACK -12 /* error on unpacking file. */
+
+/* internal data structure. */
+typedef struct mpq_archive mpq_archive_s;
+
+/* file offset data type for API*/
+typedef int64_t libmpq__off_t;
+
+/* generic information about library. */
+extern LIBMPQ_API const char *libmpq__version(void);
+
+/* generic mpq archive information. */
+extern LIBMPQ_API int32_t libmpq__archive_open(mpq_archive_s **mpq_archive, const char *mpq_filename, libmpq__off_t archive_offset);
+extern LIBMPQ_API int32_t libmpq__archive_close(mpq_archive_s *mpq_archive);
+extern LIBMPQ_API int32_t libmpq__archive_packed_size(mpq_archive_s *mpq_archive, libmpq__off_t *packed_size);
+extern LIBMPQ_API int32_t libmpq__archive_unpacked_size(mpq_archive_s *mpq_archive, libmpq__off_t *unpacked_size);
+extern LIBMPQ_API int32_t libmpq__archive_offset(mpq_archive_s *mpq_archive, libmpq__off_t *offset);
+extern LIBMPQ_API int32_t libmpq__archive_version(mpq_archive_s *mpq_archive, uint32_t *version);
+extern LIBMPQ_API int32_t libmpq__archive_files(mpq_archive_s *mpq_archive, uint32_t *files);
+
+/* generic file processing functions. */
+extern LIBMPQ_API int32_t libmpq__file_packed_size(mpq_archive_s *mpq_archive, uint32_t file_number, libmpq__off_t *packed_size);
+extern LIBMPQ_API int32_t libmpq__file_unpacked_size(mpq_archive_s *mpq_archive, uint32_t file_number, libmpq__off_t *unpacked_size);
+extern LIBMPQ_API int32_t libmpq__file_offset(mpq_archive_s *mpq_archive, uint32_t file_number, libmpq__off_t *offset);
+extern LIBMPQ_API int32_t libmpq__file_blocks(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *blocks);
+extern LIBMPQ_API int32_t libmpq__file_encrypted(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *encrypted);
+extern LIBMPQ_API int32_t libmpq__file_compressed(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *compressed);
+extern LIBMPQ_API int32_t libmpq__file_imploded(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *imploded);
+extern LIBMPQ_API int32_t libmpq__file_number(mpq_archive_s *mpq_archive, const char *filename, uint32_t *number);
+extern LIBMPQ_API int32_t libmpq__file_read(mpq_archive_s *mpq_archive, uint32_t file_number, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred);
+
+/* generic block processing functions. */
+extern LIBMPQ_API int32_t libmpq__block_open_offset(mpq_archive_s *mpq_archive, uint32_t file_number);
+extern LIBMPQ_API int32_t libmpq__block_close_offset(mpq_archive_s *mpq_archive, uint32_t file_number);
+extern LIBMPQ_API int32_t libmpq__block_unpacked_size(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t block_number, libmpq__off_t *unpacked_size);
+extern LIBMPQ_API int32_t libmpq__block_read(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t block_number, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MPQ_H */
diff --git a/contrib/libmpq/libmpq/wave.c b/contrib/libmpq/libmpq/wave.c
new file mode 100644
index 00000000000..4f2b73ba27e
--- /dev/null
+++ b/contrib/libmpq/libmpq/wave.c
@@ -0,0 +1,250 @@
+/*
+ * wave.c -- this file contains decompression methods used by mpq-tools
+ * to decompress wave files.
+ *
+ * Copyright (c) 2003-2007 Maik Broemme <mbroemme@plusserver.de>
+ *
+ * This source was adepted from the C++ version of wave.cpp included
+ * in stormlib. The C++ version belongs to the following authors:
+ *
+ * Ladislav Zezula <ladik@zezula.net>
+ * Tom Amigo <tomamigo@apexmail.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.
+ */
+
+/* generic includes. */
+#include <stdint.h>
+
+/* libmpq generic includes. */
+#include "wave.h"
+
+/* table necessary dor decompression. */
+static const uint32_t wave_table_1503f120[] = {
+ 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
+ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
+ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
+ 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008
+};
+
+/* table necessary dor decompression. */
+static const uint32_t wave_table_1503f1a0[] = {
+ 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
+ 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
+ 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
+ 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
+ 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
+ 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
+ 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
+ 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
+ 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
+ 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
+ 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
+ 0x00007FFF
+};
+
+/* this function decompress a wave file, mono or stereo, 1500F230 offset. */
+int32_t libmpq__do_decompress_wave(uint8_t *out_buf, int32_t out_length, uint8_t *in_buf, int32_t in_length, int32_t channels) {
+
+ /* some common variables. */
+ byte_and_int16_t out;
+ byte_and_int16_t in;
+ uint32_t index;
+ int32_t nr_array1[2];
+ int32_t nr_array2[2];
+ uint32_t count = 0;
+
+ /* end on input buffer. */
+ uint8_t *in_end = in_buf + in_length;
+
+ /* assign default values. */
+ out.pb = out_buf;
+ in.pb = in_buf;
+ nr_array1[0] = 0x2C;
+ nr_array1[1] = 0x2C;
+
+ /* increase. */
+ in.pw++;
+
+ /* 15007AD7 */
+ for (count = 0; count < channels; count++) {
+
+ /* some common variables. */
+ int32_t temp;
+
+ /* save pointer. */
+ temp = *(int16_t *)in.pw++;
+ nr_array2[count] = temp;
+
+ /* check if should break. */
+ if (out_length < 2) {
+ return out.pb - out_buf;
+ }
+
+ /* return values. */
+ *out.pw++ = (uint16_t)temp;
+ out_length -= 2;
+ }
+
+ /* decrease channels. */
+ index = channels - 1;
+
+ /* loop through input buffer until end reached. */
+ while (in.pb < in_end) {
+
+ /* save the byte. */
+ uint8_t one_byte = *in.pb++;
+
+ /* check how many channels and set index. */
+ if (channels == 2) {
+ index = (index == 0) ? 1 : 0;
+ }
+
+ /* 15007B25 - get one byte from input buffer. */
+ if (one_byte & 0x80) {
+
+ /* 15007B32 */
+ switch (one_byte & 0x7F) {
+ case 0:
+
+ /* 15007B8E */
+ if (nr_array1[index] != 0) {
+ nr_array1[index]--;
+ }
+
+ /* check if should break. */
+ if (out_length < 2) {
+ break;
+ }
+
+ /* return values. */
+ *out.pw++ = (uint16_t)nr_array2[index];
+ out_length -= 2;
+
+ /* continue loop. */
+ continue;
+ case 1:
+ /* 15007B72 and EBX. */
+ nr_array1[index] += 8;
+
+ /* check index. */
+ if (nr_array1[index] > 0x58) {
+ nr_array1[index] = 0x58;
+ }
+
+ /* check how many channels and set index. */
+ if (channels == 2) {
+ index = (index == 0) ? 1 : 0;
+ }
+
+ /* continue loop. */
+ continue;
+ case 2:
+
+ /* nothing todo, so continue. */
+ continue;
+ default:
+
+ /* decrease index. */
+ nr_array1[index] -= 8;
+
+ /* check index. */
+ if (nr_array1[index] < 0) {
+ nr_array1[index] = 0;
+ }
+
+ /* check if two channels left. */
+ if (channels != 2) {
+ continue;
+ }
+ index = (index == 0) ? 1 : 0;
+
+ /* continue loop. */
+ continue;
+ }
+ } else {
+
+ /* EDI */
+ uint32_t temp1 = wave_table_1503f1a0[nr_array1[index]];
+
+ /* ESI */
+ uint32_t temp2 = temp1 >> in_buf[1];
+
+ /* ECX */
+ int32_t temp3 = nr_array2[index];
+
+ /* EBX = one byte. */
+ if (one_byte & 0x01) {
+ temp2 += (temp1 >> 0);
+ }
+ if (one_byte & 0x02) {
+ temp2 += (temp1 >> 1);
+ }
+ if (one_byte & 0x04) {
+ temp2 += (temp1 >> 2);
+ }
+ if (one_byte & 0x08) {
+ temp2 += (temp1 >> 3);
+ }
+ if (one_byte & 0x10) {
+ temp2 += (temp1 >> 4);
+ }
+ if (one_byte & 0x20) {
+ temp2 += (temp1 >> 5);
+ }
+ if (one_byte & 0x40) {
+ temp3 -= temp2;
+ if (temp3 <= (int32_t)0xFFFF8000) {
+ temp3 = (int32_t)0xFFFF8000;
+ }
+ } else {
+ temp3 += temp2;
+ if (temp3 >= 0x7FFF) {
+ temp3 = 0x7FFF;
+ }
+ }
+
+ /* restore index. */
+ nr_array2[index] = temp3;
+
+ /* check if should break. */
+ if (out_length < 2) {
+ break;
+ }
+
+ /* assign values. */
+ temp2 = nr_array1[index];
+ one_byte &= 0x1F;
+ *out.pw++ = (uint16_t)temp3;
+ out_length -= 2;
+ temp2 += wave_table_1503f120[one_byte];
+ nr_array1[index] = temp2;
+
+ /* check index. */
+ if (nr_array1[index] < 0) {
+ nr_array1[index] = 0;
+ } else {
+
+ /* check index. */
+ if (nr_array1[index] > 0x58) {
+ nr_array1[index] = 0x58;
+ }
+ }
+ }
+ }
+
+ /* return copied bytes. */
+ return (out.pb - out_buf);
+}
diff --git a/contrib/libmpq/libmpq/wave.h b/contrib/libmpq/libmpq/wave.h
new file mode 100644
index 00000000000..1b9491bd70a
--- /dev/null
+++ b/contrib/libmpq/libmpq/wave.h
@@ -0,0 +1,45 @@
+/*
+ * wave.h -- header file for wav unplode functions used by mpq-tools.
+ *
+ * Copyright (c) 2003-2007 Maik Broemme <mbroemme@plusserver.de>
+ *
+ * This source was adepted from the C++ version of wave.h included
+ * in stormlib. The C++ version belongs to the following authors:
+ *
+ * Ladislav Zezula <ladik.zezula.net>
+ * Tom Amigo <tomamigo@apexmail.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.
+ */
+
+#ifndef _WAVE_H
+#define _WAVE_H
+
+/* buffer. */
+typedef union {
+ uint16_t *pw;
+ uint8_t *pb;
+} byte_and_int16_t;
+
+/* decompress a wave file, mono or stereo, 1500F230 offset. */
+int32_t libmpq__do_decompress_wave(
+ uint8_t *out_buf,
+ int32_t out_length,
+ uint8_t *in_buf,
+ int32_t in_length,
+ int32_t channels
+);
+
+#endif /* _WAVE_H */
diff --git a/contrib/libmpq/tools/Makefile.am b/contrib/libmpq/tools/Makefile.am
new file mode 100644
index 00000000000..607205379a4
--- /dev/null
+++ b/contrib/libmpq/tools/Makefile.am
@@ -0,0 +1,8 @@
+# minimum required automake 1.6
+AUTOMAKE_OPTIONS = 1.6
+
+# the main programs.
+bin_PROGRAMS = crypt_buf_gen
+
+# sources for crypt_buf_gen program.
+crypt_buf_gen_SOURCES = crypt_buf_gen.c
diff --git a/contrib/libmpq/tools/crypt_buf_gen.c b/contrib/libmpq/tools/crypt_buf_gen.c
new file mode 100644
index 00000000000..3d150fc661f
--- /dev/null
+++ b/contrib/libmpq/tools/crypt_buf_gen.c
@@ -0,0 +1,85 @@
+/*
+ * crypt_buf_gen.c -- tool to re-create the static decryption buffer.
+ *
+ * Copyright (c) 2003-2008 Maik Broemme <mbroemme@plusserver.de>
+ * Copyright (c) 2008 Georg Lukas <georg@op-co.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 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.
+ *
+ *
+ * Usage:
+ * $ make crypt_buf_gen
+ * $ ./crypt_buf_gen > crypt_buf.h
+ *
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static uint32_t *buffer;
+
+int32_t libmpq__buffer_init() {
+ buffer = malloc(sizeof(uint32_t) * 0x500);
+
+ if (!buffer)
+ return -1;
+
+ /* some common variables. */
+ uint32_t seed = 0x00100001;
+ uint32_t index1 = 0;
+ uint32_t index2 = 0;
+ uint32_t i;
+
+ /* initialize the decryption buffer. */
+ for (index1 = 0; index1 < 0x100; index1++) {
+ for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100) {
+
+ /* some common variables. */
+ uint32_t temp1, temp2;
+
+ /* temporary copy. */
+ seed = (seed * 125 + 3) % 0x2AAAAB;
+ temp1 = (seed & 0xFFFF) << 0x10;
+
+ /* temporary copy. */
+ seed = (seed * 125 + 3) % 0x2AAAAB;
+ temp2 = (seed & 0xFFFF);
+
+ /* assign buffer. */
+ buffer[index2] = (temp1 | temp2);
+ }
+ }
+
+ /* if no error was found, return zero. */
+ return 0;
+}
+
+int main() {
+ if (libmpq__buffer_init() != 0)
+ perror("libmpq__buffer_init()");
+ int x;
+ printf("/* DO NOT CHANGE! this file is auto-generated by crypt_buf_gen.c */\n");
+ printf("static const uint32_t crypt_buf[0x500] = {\n\t");
+ for (x = 0; x < 0x500; x++) {
+ printf("0x%08x", buffer[x]);
+ if (x < 0x500 - 1) {
+ if (x % 6 == 5)
+ printf(",\n\t");
+ else
+ printf(", ");
+ }
+ }
+ printf("\n};\n");
+}
diff --git a/contrib/libmpq/win/VS100/libmpq.vcxproj b/contrib/libmpq/win/VS100/libmpq.vcxproj
new file mode 100644
index 00000000000..e68a67ccd57
--- /dev/null
+++ b/contrib/libmpq/win/VS100/libmpq.vcxproj
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>libmpq</ProjectName>
+ <ProjectGuid>{03AB0F44-628E-4855-99A0-C98A1EB52C50}</ProjectGuid>
+ <RootNamespace>libmpq</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\; ..\..\..\..\dep\include\zlib; ..\..\..\..\dep\include\bzip2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ </ClCompile>
+ <ProjectReference>
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>
+ </ProjectReference>
+ <Lib>
+ <AdditionalLibraryDirectories>..\dep\lib\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <AdditionalIncludeDirectories>..\; ..\..\..\..\dep\include\zlib; ..\..\..\..\dep\include\bzip2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ </ClCompile>
+ <ProjectReference>
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>
+ </ProjectReference>
+ <Lib>
+ <AdditionalLibraryDirectories>..\dep\lib\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\libmpq\common.c" />
+ <ClCompile Include="..\..\libmpq\explode.c" />
+ <ClCompile Include="..\..\libmpq\extract.c" />
+ <ClCompile Include="..\..\libmpq\huffman.c" />
+ <ClCompile Include="..\..\libmpq\mpq.c" />
+ <ClCompile Include="..\..\libmpq\wave.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\libmpq\common.h" />
+ <ClInclude Include="..\..\libmpq\crypt_buf.h" />
+ <ClInclude Include="..\..\libmpq\explode.h" />
+ <ClInclude Include="..\..\libmpq\extract.h" />
+ <ClInclude Include="..\..\libmpq\huffman.h" />
+ <ClInclude Include="..\..\libmpq\mpq-internal.h" />
+ <ClInclude Include="..\..\libmpq\mpq.h" />
+ <ClInclude Include="..\..\libmpq\wave.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\..\win\VC100\bzip2.vcxproj">
+ <Project>{b96f612a-c91d-43b3-a4c3-d4294817ec6c}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\win\VC100\zlib.vcxproj">
+ <Project>{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/contrib/libmpq/win/config.h b/contrib/libmpq/win/config.h
new file mode 100644
index 00000000000..6833494624d
--- /dev/null
+++ b/contrib/libmpq/win/config.h
@@ -0,0 +1,81 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#define HAVE_FSEEKO 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `bz2' library (-lbz2). */
+#define HAVE_LIBBZ2 1
+
+/* Define to 1 if you have the `z' library (-lz). */
+#define HAVE_LIBZ 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 0
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "libmpq"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "mbroemme@plusserver.de"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libmpq"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libmpq 0.4.2"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libmpq"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.4.2"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.4.2"
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+/* #undef _LARGEFILE_SOURCE */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
diff --git a/contrib/libmpq/win/libmpq_VC100.sln b/contrib/libmpq/win/libmpq_VC100.sln
new file mode 100644
index 00000000000..5c88e2e4957
--- /dev/null
+++ b/contrib/libmpq/win/libmpq_VC100.sln
@@ -0,0 +1,31 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmpq", "VS100\libmpq.vcxproj", "{03AB0F44-628E-4855-99A0-C98A1EB52C50}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\win\VC100\zlib.vcxproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "..\..\..\win\VC100\bzip2.vcxproj", "{B96F612A-C91D-43B3-A4C3-D4294817EC6C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Debug|Win32.ActiveCfg = Debug|Win32
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Debug|Win32.Build.0 = Debug|Win32
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Release|Win32.ActiveCfg = Release|Win32
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Release|Win32.Build.0 = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.Build.0 = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.ActiveCfg = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.Build.0 = Release|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Debug|Win32.Build.0 = Debug|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Release|Win32.ActiveCfg = Release|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/libmpq/win/libmpq_VC90.sln b/contrib/libmpq/win/libmpq_VC90.sln
new file mode 100644
index 00000000000..7c4a8e47a56
--- /dev/null
+++ b/contrib/libmpq/win/libmpq_VC90.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmpq", "VC90\libmpq.vcproj", "{03AB0F44-628E-4855-99A0-C98A1EB52C50}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C} = {B96F612A-C91D-43B3-A4C3-D4294817EC6C}
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\win\VC90\zlib.vcproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "..\..\..\win\VC90\bzip2.vcproj", "{B96F612A-C91D-43B3-A4C3-D4294817EC6C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Debug|Win32.ActiveCfg = Debug|Win32
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Debug|Win32.Build.0 = Debug|Win32
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Release|Win32.ActiveCfg = Release|Win32
+ {03AB0F44-628E-4855-99A0-C98A1EB52C50}.Release|Win32.Build.0 = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.Build.0 = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.ActiveCfg = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.Build.0 = Release|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Debug|Win32.Build.0 = Debug|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Release|Win32.ActiveCfg = Release|Win32
+ {B96F612A-C91D-43B3-A4C3-D4294817EC6C}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/libmpq/win/stdint.h b/contrib/libmpq/win/stdint.h
new file mode 100644
index 00000000000..d02608a5972
--- /dev/null
+++ b/contrib/libmpq/win/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// 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.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/contrib/vmap_assembler/CMakeLists.txt b/contrib/vmap_assembler/CMakeLists.txt
new file mode 100644
index 00000000000..42c7817699f
--- /dev/null
+++ b/contrib/vmap_assembler/CMakeLists.txt
@@ -0,0 +1,85 @@
+# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+cmake_minimum_required (VERSION 2.6)
+project (MANGOS_VMAP_ASSEMB_IO)
+
+set(CMAKE_VERBOSE_MAKEFILE true)
+
+# uncomment next line to disable debug mode
+ADD_DEFINITIONS("-DIOMAP_DEBUG")
+
+ADD_DEFINITIONS("-Wall")
+ADD_DEFINITIONS("-ggdb")
+ADD_DEFINITIONS("-O3")
+
+include_directories(../../src/shared/vmap/)
+include_directories(../../dep/include/g3dlite/)
+include_directories(../../dep/ACE_wrappers/)
+include_directories(../../objdir/dep/ACE_wrappers)
+include_directories(../../src/framework/)
+
+add_library(g3dlite ../../dep/src/g3dlite/AABox.cpp
+ ../../dep/src/g3dlite/Box.cpp
+ ../../dep/src/g3dlite/Crypto.cpp
+ ../../dep/src/g3dlite/format.cpp
+ ../../dep/src/g3dlite/Matrix3.cpp
+ ../../dep/src/g3dlite/Plane.cpp
+ ../../dep/src/g3dlite/System.cpp
+ ../../dep/src/g3dlite/Triangle.cpp
+ ../../dep/src/g3dlite/Vector3.cpp
+ ../../dep/src/g3dlite/Vector4.cpp
+ ../../dep/src/g3dlite/debugAssert.cpp
+ ../../dep/src/g3dlite/fileutils.cpp
+ ../../dep/src/g3dlite/g3dmath.cpp
+ ../../dep/src/g3dlite/g3dfnmatch.cpp
+ ../../dep/src/g3dlite/prompt.cpp
+ ../../dep/src/g3dlite/stringutils.cpp
+ ../../dep/src/g3dlite/Any.cpp
+ ../../dep/src/g3dlite/BinaryFormat.cpp
+ ../../dep/src/g3dlite/BinaryInput.cpp
+ ../../dep/src/g3dlite/BinaryOutput.cpp
+ ../../dep/src/g3dlite/Capsule.cpp
+ ../../dep/src/g3dlite/CollisionDetection.cpp
+ ../../dep/src/g3dlite/CoordinateFrame.cpp
+ ../../dep/src/g3dlite/Cylinder.cpp
+ ../../dep/src/g3dlite/Line.cpp
+ ../../dep/src/g3dlite/LineSegment.cpp
+ ../../dep/src/g3dlite/Log.cpp
+ ../../dep/src/g3dlite/Matrix4.cpp
+ ../../dep/src/g3dlite/MemoryManager.cpp
+ ../../dep/src/g3dlite/Quat.cpp
+ ../../dep/src/g3dlite/Random.cpp
+ ../../dep/src/g3dlite/Ray.cpp
+ ../../dep/src/g3dlite/ReferenceCount.cpp
+ ../../dep/src/g3dlite/Sphere.cpp
+ ../../dep/src/g3dlite/TextInput.cpp
+ ../../dep/src/g3dlite/TextOutput.cpp
+ ../../dep/src/g3dlite/UprightFrame.cpp
+ ../../dep/src/g3dlite/Vector2.cpp
+ )
+
+add_library(vmap
+ ../../src/shared/vmap/BIH.cpp
+ ../../src/shared/vmap/VMapManager2.cpp
+ ../../src/shared/vmap/MapTree.cpp
+ ../../src/shared/vmap/TileAssembler.cpp
+ ../../src/shared/vmap/WorldModel.cpp
+ ../../src/shared/vmap/ModelInstance.cpp
+ )
+
+target_link_libraries(vmap g3dlite z)
+
+add_executable(vmap_assembler vmap_assembler.cpp)
+target_link_libraries(vmap_assembler vmap)
+
+# add_executable(vmap_test coordinate_test.cpp)
+# target_link_libraries(vmap_test vmap)
+
diff --git a/contrib/vmap_assembler/VC100/vmap_assembler.vcxproj b/contrib/vmap_assembler/VC100/vmap_assembler.vcxproj
new file mode 100644
index 00000000000..e16f40b8e98
--- /dev/null
+++ b/contrib/vmap_assembler/VC100/vmap_assembler.vcxproj
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{572FFF74-480C-4472-8ABF-81733BB4049D}</ProjectGuid>
+ <RootNamespace>vmap_assembler</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;..\..\..\src\framework;..\..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)vmap_assembler.exe</OutputFile>
+ <IgnoreSpecificDefaultLibraries>
+ </IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <AdditionalLibraryDirectories>
+ </AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;..\..\..\src\framework;..\..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)vmap_assembler.exe</OutputFile>
+ <IgnoreSpecificDefaultLibraries>
+ </IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;..\..\..\src\framework;..\..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)vmap_assembler.exe</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;..\..\..\src\framework;..\..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)vmap_assembler.exe</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\vmap_assembler.cpp" />
+ <ClCompile Include="..\..\..\src\shared\vmap\BIH.cpp" />
+ <ClCompile Include="..\..\..\src\shared\vmap\MapTree.cpp" />
+ <ClCompile Include="..\..\..\src\shared\vmap\ModelInstance.cpp" />
+ <ClCompile Include="..\..\..\src\shared\vmap\TileAssembler.cpp" />
+ <ClCompile Include="..\..\..\src\shared\vmap\VMapManager2.cpp" />
+ <ClCompile Include="..\..\..\src\shared\vmap\WorldModel.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\src\shared\vmap\BIH.h" />
+ <ClInclude Include="..\..\..\src\shared\vmap\MapTree.h" />
+ <ClInclude Include="..\..\..\src\shared\vmap\ModelInstance.h" />
+ <ClInclude Include="..\..\..\src\shared\vmap\TileAssembler.h" />
+ <ClInclude Include="..\..\..\src\shared\vmap\VMapManager2.h" />
+ <ClInclude Include="..\..\..\src\shared\vmap\VMapTools.h" />
+ <ClInclude Include="..\..\..\src\shared\vmap\WorldModel.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\win\VC100\g3dlite.vcxproj">
+ <Project>{8072769e-cf10-48bf-b9e1-12752a5dac6e}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\win\VC100\zlib.vcxproj">
+ <Project>{8f1dea42-6a5b-4b62-839d-c141a7bfacf2}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/contrib/vmap_assembler/VC71/vmap_assembler.vcproj b/contrib/vmap_assembler/VC71/vmap_assembler.vcproj
index aaaeb4dfc3c..1c6d932bddf 100644
--- a/contrib/vmap_assembler/VC71/vmap_assembler.vcproj
+++ b/contrib/vmap_assembler/VC71/vmap_assembler.vcproj
@@ -12,8 +12,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="..\Debug\obj"
+ OutputDirectory="..\bin\$(PlatformName)_$(ConfigurationName)\"
+ IntermediateDirectory="bin\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -61,8 +61,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="..\Release\obj"
+ OutputDirectory="..\bin\$(PlatformName)_$(ConfigurationName)\"
+ IntermediateDirectory="bin\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
ConfigurationType="1"
CharacterSet="2">
<Tool
diff --git a/contrib/vmap_assembler/VC80/vmap_assembler.vcproj b/contrib/vmap_assembler/VC80/vmap_assembler.vcproj
index 3b3a58a05aa..f8f14285974 100644
--- a/contrib/vmap_assembler/VC80/vmap_assembler.vcproj
+++ b/contrib/vmap_assembler/VC80/vmap_assembler.vcproj
@@ -16,8 +16,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="..\Debug\obj"
+ OutputDirectory="..\bin\$(PlatformName)_$(ConfigurationName)\"
+ IntermediateDirectory="bin\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
@@ -96,8 +96,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="..\Release\obj"
+ OutputDirectory="..\bin\$(PlatformName)_$(ConfigurationName)\"
+ IntermediateDirectory="bin\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
@@ -190,167 +190,187 @@
Name="vmaplib"
>
<File
- RelativePath="..\..\..\src\shared\vmap\AABSPTree.h"
+ RelativePath="..\..\..\src\shared\vmap\BIH.cpp"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\BaseModel.cpp"
+ RelativePath="..\..\..\src\shared\vmap\BIH.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\BaseModel.h"
+ RelativePath="..\..\..\src\shared\vmap\MapTree.cpp"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\CoordModelMapping.cpp"
+ RelativePath="..\..\..\src\shared\vmap\MapTree.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\CoordModelMapping.h"
+ RelativePath="..\..\..\src\shared\vmap\ModelInstance.cpp"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\DebugCmdLogger.cpp"
+ RelativePath="..\..\..\src\shared\vmap\ModelInstance.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\DebugCmdLogger.h"
+ RelativePath="..\..\..\src\shared\vmap\TileAssembler.cpp"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\ManagedModelContainer.cpp"
+ RelativePath="..\..\..\src\shared\vmap\TileAssembler.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\ManagedModelContainer.h"
+ RelativePath="..\..\..\src\shared\vmap\VMapManager2.cpp"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\ModelContainer.cpp"
+ RelativePath="..\..\..\src\shared\vmap\VMapManager2.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\ModelContainer.h"
+ RelativePath="..\..\..\src\shared\vmap\VMapTools.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\NodeValueAccess.h"
+ RelativePath="..\..\..\src\shared\vmap\WorldModel.cpp"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\ShortBox.h"
+ RelativePath="..\..\..\src\shared\vmap\WorldModel.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="g3dlite"
+ >
<File
- RelativePath="..\..\..\src\shared\vmap\ShortVector.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\AABox.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\SubModel.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Array.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\SubModel.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Box.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\TileAssembler.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\CollisionDetection.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\TileAssembler.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\CoordinateFrame.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\TreeNode.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Crypto.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\TreeNode.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\debug.h"
>
</File>
<File
- RelativePath="..\..\..\src\shared\vmap\VMapTools.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\format.h"
>
</File>
- </Filter>
- <Filter
- Name="g3dlite"
- >
<File
- RelativePath="..\..\..\dep\src\g3dlite\AABox.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\g3dmath.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\AABox.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\GCamera.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\AABSPTree.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Line.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Array.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Matrix3.h"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\Box.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Plane.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Box.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\platform.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\CollisionDetection.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Quat.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\CoordinateFrame.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Ray.h"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\Crypto.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\RegistryUtil.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Crypto.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Sphere.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\debug.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\stringutils.h"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\format.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\System.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\format.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Table.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\g3dmath.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Triangle.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\g3dmath.inl"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\GCamera.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2int16.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Line.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3.h"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\Matrix3.cpp"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3int16.h"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Matrix3.h"
+ RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector4.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\AABox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\Box.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\Crypto.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\format.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\Matrix3.cpp"
>
</File>
<File
@@ -358,95 +378,131 @@
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Plane.h"
+ RelativePath="..\..\..\dep\src\g3dlite\System.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\platform.h"
+ RelativePath="..\..\..\dep\src\g3dlite\Triangle.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Quat.h"
+ RelativePath="..\..\..\dep\src\g3dlite\Vector3.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Quat.inl"
+ RelativePath="..\..\..\dep\src\g3dlite\Vector4.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Ray.h"
+ RelativePath="..\..\..\dep\src\g3dlite\debugAssert.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\RegistryUtil.h"
+ RelativePath="..\..\..\dep\src\g3dlite\fileutils.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Sphere.h"
+ RelativePath="..\..\..\dep\src\g3dlite\g3dmath.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\stringutils.h"
+ RelativePath="..\..\..\dep\src\g3dlite\g3dfnmatch.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\System.cpp"
+ RelativePath="..\..\..\dep\src\g3dlite\prompt.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\System.h"
+ RelativePath="..\..\..\dep\src\g3dlite\stringutils.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Table.h"
+ RelativePath="..\..\..\dep\src\g3dlite\Any.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\Triangle.cpp"
+ RelativePath="..\..\..\dep\src\g3dlite\BinaryFormat.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Triangle.h"
+ RelativePath="..\..\..\dep\src\g3dlite\BinaryInput.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2.h"
+ RelativePath="..\..\..\dep\src\g3dlite\BinaryOutput.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2.inl"
+ RelativePath="..\..\..\dep\src\g3dlite\Capsule.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector2int16.h"
+ RelativePath="..\..\..\dep\src\g3dlite\CollisionDetection.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\Vector3.cpp"
+ RelativePath="..\..\..\dep\src\g3dlite\CoordinateFrame.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3.h"
+ RelativePath="..\..\..\dep\src\g3dlite\Cylinder.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3.inl"
+ RelativePath="..\..\..\dep\src\g3dlite\Line.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector3int16.h"
+ RelativePath="..\..\..\dep\src\g3dlite\LineSegment.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\src\g3dlite\Vector4.cpp"
+ RelativePath="..\..\..\dep\src\g3dlite\Log.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector4.h"
+ RelativePath="..\..\..\dep\src\g3dlite\Matrix4.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\MemoryManager.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\Quat.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\Random.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\Ray.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\ReferenceCount.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\Sphere.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\TextInput.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\TextOutput.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\dep\src\g3dlite\UprightFrame.cpp"
>
</File>
<File
- RelativePath="..\..\..\dep\include\g3dlite\G3D\Vector4.inl"
+ RelativePath="..\..\..\dep\src\g3dlite\Vector2.cpp"
>
</File>
</Filter>
diff --git a/contrib/vmap_assembler/VC90/vmap_assembler.vcproj b/contrib/vmap_assembler/VC90/vmap_assembler.vcproj
new file mode 100644
index 00000000000..aff990d01cc
--- /dev/null
+++ b/contrib/vmap_assembler/VC90/vmap_assembler.vcproj
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="vmap_assembler"
+ ProjectGUID="{572FFF74-480C-4472-8ABF-81733BB4049D}"
+ RootNamespace="vmap_assembler"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\bin\$(PlatformName)_$(ConfigurationName)\"
+ IntermediateDirectory="bin\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/vmap_assembler.exe"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/vmap_assembler.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\bin\$(PlatformName)_$(ConfigurationName)\"
+ IntermediateDirectory="bin\$(ProjectName)__$(PlatformName)_$(ConfigurationName)\"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\dep\include\g3dlite;..\..\..\src\shared\vmap;..\..\..\src\framework;..\..\..\dep\ACE_wrappers"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/vmap_assembler.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\..\vmap_assembler.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="vmaplib"
+ >
+ <File
+ RelativePath="..\..\..\src\shared\vmap\BIH.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\BIH.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\MapTree.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\MapTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\ModelInstance.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\ModelInstance.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\TileAssembler.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\TileAssembler.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\VMapManager2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\VMapManager2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\VMapTools.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\WorldModel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\src\shared\vmap\WorldModel.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/contrib/vmap_assembler/vmap_assembler.cpp b/contrib/vmap_assembler/vmap_assembler.cpp
index e6a3089f328..6666b54356c 100644
--- a/contrib/vmap_assembler/vmap_assembler.cpp
+++ b/contrib/vmap_assembler/vmap_assembler.cpp
@@ -54,7 +54,7 @@ File contains map names that should be split into tiles
A '#' at the beginning of a line defines a comment
*/
-bool readConfigFile(char *pConffile, VMAP::TileAssembler* pTa)
+/* bool readConfigFile(char *pConffile, VMAP::TileAssembler* pTa)
{
bool result = false;
char buffer[501];
@@ -74,7 +74,7 @@ bool readConfigFile(char *pConffile, VMAP::TileAssembler* pTa)
result = true;
}
return(result);
-}
+} */
//=======================================================
int main(int argc, char* argv[])
{
@@ -97,7 +97,7 @@ int main(int argc, char* argv[])
All the names in the list are considered to be world maps or huge instances.
These maps will be spilt into tiles in the vmap assemble process
*/
- if(conffile != NULL)
+ /* if(conffile != NULL)
{
if(!readConfigFile(conffile, ta))
{
@@ -105,9 +105,9 @@ int main(int argc, char* argv[])
delete ta;
return 1;
}
- }
+ } */
- if(!ta->convertWorld())
+ if(!ta->convertWorld2())
{
printf("exit with errors\n");
delete ta;
@@ -118,4 +118,3 @@ int main(int argc, char* argv[])
printf("Ok, all done\n");
return 0;
}
-
diff --git a/contrib/vmap_assembler/vmap_assemblerVC100.sln b/contrib/vmap_assembler/vmap_assemblerVC100.sln
new file mode 100644
index 00000000000..368858561f9
--- /dev/null
+++ b/contrib/vmap_assembler/vmap_assemblerVC100.sln
@@ -0,0 +1,59 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmap_assembler", "VC100\vmap_assembler.vcxproj", "{572FFF74-480C-4472-8ABF-81733BB4049D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\win\VC100\zlib.vcxproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "g3dlite", "..\..\win\VC100\g3dlite.vcxproj", "{8072769E-CF10-48BF-B9E1-12752A5DAC6E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_NoPCH|Win32 = Debug_NoPCH|Win32
+ Debug_NoPCH|x64 = Debug_NoPCH|x64
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug_NoPCH|Win32.ActiveCfg = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug_NoPCH|Win32.Build.0 = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug_NoPCH|x64.ActiveCfg = Debug|x64
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug_NoPCH|x64.Build.0 = Debug|x64
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.Build.0 = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|x64.ActiveCfg = Debug|x64
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|x64.Build.0 = Debug|x64
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.ActiveCfg = Release|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.Build.0 = Release|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|x64.ActiveCfg = Release|x64
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|x64.Build.0 = Release|x64
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|x64.ActiveCfg = Debug_NoPCH|x64
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|x64.Build.0 = Debug_NoPCH|x64
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.Build.0 = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|x64.ActiveCfg = Debug|x64
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|x64.Build.0 = Debug|x64
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.ActiveCfg = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.Build.0 = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|x64.ActiveCfg = Release|x64
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|x64.Build.0 = Release|x64
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|x64.ActiveCfg = Debug_NoPCH|x64
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|x64.Build.0 = Debug_NoPCH|x64
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.Build.0 = Debug|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.ActiveCfg = Debug|x64
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.Build.0 = Debug|x64
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.ActiveCfg = Release|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.Build.0 = Release|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.ActiveCfg = Release|x64
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/vmap_assembler/vmap_assemblerVC90.sln b/contrib/vmap_assembler/vmap_assemblerVC90.sln
new file mode 100644
index 00000000000..9e94e750661
--- /dev/null
+++ b/contrib/vmap_assembler/vmap_assemblerVC90.sln
@@ -0,0 +1,42 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmap_assembler", "VC90\vmap_assembler.vcproj", "{572FFF74-480C-4472-8ABF-81733BB4049D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E} = {8072769E-CF10-48BF-B9E1-12752A5DAC6E}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\win\VC90\zlib.vcproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "g3dlite", "..\..\win\VC90\g3dlite.vcproj", "{8072769E-CF10-48BF-B9E1-12752A5DAC6E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_NoPCH|Win32 = Debug_NoPCH|Win32
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug_NoPCH|Win32.ActiveCfg = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug_NoPCH|Win32.Build.0 = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Debug|Win32.Build.0 = Debug|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.ActiveCfg = Release|Win32
+ {572FFF74-480C-4472-8ABF-81733BB4049D}.Release|Win32.Build.0 = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug|Win32.Build.0 = Debug|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.ActiveCfg = Release|Win32
+ {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release|Win32.Build.0 = Release|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.ActiveCfg = Debug_NoPCH|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug_NoPCH|Win32.Build.0 = Debug_NoPCH|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.Build.0 = Debug|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.ActiveCfg = Release|Win32
+ {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/vmap_extractor_v2/CMakeLists.txt b/contrib/vmap_extractor_v2/CMakeLists.txt
new file mode 100644
index 00000000000..20e4f7c64ce
--- /dev/null
+++ b/contrib/vmap_extractor_v2/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+cmake_minimum_required (VERSION 2.6)
+project (MANGOS_VMAP_EXTRACT_IO)
+
+
+# uncomment next line to disable debug mode
+ADD_DEFINITIONS("-DIOMAP_DEBUG")
+# build setup currently only supports libmpq 0.4.x
+ADD_DEFINITIONS("-DUSE_LIBMPQ04")
+ADD_DEFINITIONS("-Wall")
+ADD_DEFINITIONS("-ggdb")
+ADD_DEFINITIONS("-O3")
+
+include_directories(../libmpq)
+#add_subdirectory(stormlib)
+
+add_subdirectory(vmapextract)
diff --git a/contrib/vmap_extractor_v2/stormdll/StormDll.cpp b/contrib/vmap_extractor_v2/stormdll/StormDll.cpp
deleted file mode 100644
index 2031180c7e3..00000000000
--- a/contrib/vmap_extractor_v2/stormdll/StormDll.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*****************************************************************************/
-/* Storm.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* This is just a dummy module for building import library for Storm.dll */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.04.03 1.00 Lad The first version of Storm.cpp */
-/*****************************************************************************/
-
-#include <windows.h>
-
-#define BUILDING_STORM_CPP
-#define STORM_ALTERNATE_NAMES
-#include "StormDll.h"
-
-BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(CloseFile)(HANDLE hFile)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-LCID WINAPI SFILE(SetLocale)(LCID nNewLocale)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SFILE(Destroy)()
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SCOMP(Compress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
diff --git a/contrib/vmap_extractor_v2/stormdll/StormDll.def b/contrib/vmap_extractor_v2/stormdll/StormDll.def
deleted file mode 100644
index 8de88f5db3d..00000000000
--- a/contrib/vmap_extractor_v2/stormdll/StormDll.def
+++ /dev/null
@@ -1,25 +0,0 @@
-; Storm definition file with alternate Storm.dll names
-LIBRARY "Storm"
-
-EXPORTS
- StormCloseArchive @252 ; 0x0FC
- StormCloseFile @253 ; 0x0FD
- StormDestroy @262 ; 0x106
- StormGetFileArchive @264 ; 0x108
- StormGetFileSize @265 ; 0x109
- StormOpenArchive @266 ; 0x10A
- StormOpenFile @267 ; 0x10B
- StormOpenFileEx @268 ; 0x10C
- StormReadFile @269 ; 0x10D
- StormSetBasePath @270 ; 0x10E
- StormSetFilePointer @271 ; 0x10F
- StormSetLocale @272 ; 0x110
- StormGetBasePath @273 ; 0x111
- StormGetArchiveName @275 ; 0x113
- StormGetFileName @276 ; 0x114
-
-; StormSetLastError @465 ; 0x
-
- StormCompress @551 ; 0x227
- StormDecompress @552 ; 0x228
- \ No newline at end of file
diff --git a/contrib/vmap_extractor_v2/stormdll/StormDll.h b/contrib/vmap_extractor_v2/stormdll/StormDll.h
deleted file mode 100644
index 6d67820a22f..00000000000
--- a/contrib/vmap_extractor_v2/stormdll/StormDll.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*****************************************************************************/
-/* Storm.h Copyright Justin Olbrantz(Quantam) 2000 */
-/*---------------------------------------------------------------------------*/
-/* Storm Interface Library v1.0 for Windows */
-/* */
-/* Author : Justin Olbrantz(Quantam) */
-/* E-mail : omega@dragonfire.net */
-/* WWW : www.campaigncreations.com/starcraft/mpq2k/inside_mopaq/ */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.00 1.00 Qua The first version of Storm.h */
-/* 11.04.03 1.00 Lad Added some functions */
-/*****************************************************************************/
-
-// We need the Windows data types for the Storm prototypes
-#include <windows.h>
-
-#ifndef __STORM_H__
-#define __STORM_H__
-
-// Somethimes is necessary to change the function names so they
-// will not conflict with other MPQ tools.
-#ifdef STORM_ALTERNATE_NAMES
- #define SFILE(Name) Storm##Name
- #define SCOMP(Name) Storm##Name
-#else
- #define SFILE(Name) SFile##Name
- #define SCOMP(Name) SComp##Name
-#endif
-
-
-// Just in case anyone is still using C out there
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Storm file function prototypes
-BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ);
-BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ);
-BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength);
-BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile);
-BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile);
-BOOL WINAPI SFILE(CloseFile)(HANDLE hFile);
-DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh);
-BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ);
-BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength);
-DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod);
-BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped);
-LCID WINAPI SFILE(SetLocale)(LCID nNewLocale);
-BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength);
-BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath);
-
-// Storm (de)compression functions
-BOOL WINAPI SCOMP(Compress) (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel);
-BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength);
-
-
-#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP)
-#pragma comment(lib, "Storm.lib") // Force linking Storm.lib and thus Storm.dll
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __STORM_H__
diff --git a/contrib/vmap_extractor_v2/stormlib/GfxDecode.cpp b/contrib/vmap_extractor_v2/stormlib/GfxDecode.cpp
deleted file mode 100644
index 665e5d38e49..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/GfxDecode.cpp
+++ /dev/null
@@ -1,697 +0,0 @@
-/***********************************************************************
-*
-* Description: GfxDecode -- functions for reading Diablo's GFX files
-* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de>
-* Created at: Son Jan 27 15:20:43 CET 2002
-* Computer: hangloose.flachland-chemnitz.de
-* System: Linux 2.4.16 on i686
-*
-* Copyright (c) 2002 BMX-Chemnitz.DE All rights reserved.
-*
-* ---------------------------------------------------------------------
-* included are functions for getting:
-* - the framecount of .CEL-files -> celGetFrameCount()
-* - single frames of .CEL-files -> celGetFrameData()
-* - the framecount of .CL2-files -> cl2GetFrameCount()
-* - single directions of .CL2-files (all frames) -> cl2GetDirData()
-* - single .PCX-files (256 color; v2, v5) -> pcxGetData()
-***********************************************************************/
-
-#include <vector>
-#include <cmath>
-#include <iostream>
-
-#include "StormLib.h"
-
-#define TRANS_COL 256
-
-using std::cerr;
-using std::vector;
-
-/****** RAMP stuff *****************************************************
- * for a more detailed description/explanation see below
- ***********************************************************************/
-// two variations: one/two ramp(s)
-static const uint16_t c_2RampSize = 544; // the frame size
-static const uint16_t c_1RampSize = 800; // the frame size
-
-// ramps (both variations) can be either left or right
-static const uint16_t c_RampOffsetLeft[17] = {
- 0, // __
- 8, // + 8 note that this __--
- 24, // + 16 "drawing" is __--
- 48, // + 24 upside down! __-- this area
- 80, // + 32 __-- is always
- 120, // + 40 __-- colored
- 168, // + 48 __--
- 224, // + 56 __-- lower ramp ends here (+30 == 254)
- 288, // + 64 --__ upper ramp might be missing
- 348, // + 60 | --__
- 400, // + 52 | --__ this area
- 444, // + 44 | --__ is always
- 480, // + 36 | --__ colored
- 508, // + 28 | either trans- --__
- 528, // + 20 | parent or colored --__
- 540, // + 12 | --__ +2 Pixels = 544
- 542 // + 2 | this last one doesn't exist, it's those^ 2 pixels
-};
-
-static const uint16_t c_RampOffsetRight[17] = {
- 2, // __ before this, there are 2 Pixels
- 14, // + 12 --__ 4^2 - 2
- 34, // + 20 --__ 6^2 - 2
- 62, // + 28 this area --__ 8^2 - 2
- 98, // + 36 is always --__ 10^2 - 2 pattern anyone? ;)
- 142, // + 44 colored --__
- 194, // + 52 --__
- 254, // + 60 lower ramp ends here --__ (-30 == 224)
- 318, // + 64 upper ramp might be missing __--
- 374, // + 56 __-- |
- 422, // + 48 this area __-- | note that this
- 462, // + 40 is always __-- | "drawing"
- 494, // + 32 colored __-- eiter trans- | is upside down!
- 518, // + 24 __-- parent or colored |
- 534, // + 16 __-- |
- 542, // + 8 __-- +2 Startpixels = 544 |
- 542 // + 0 this last one doesn't exist, it | would be EOF
-};
-
-/****** FrameBuffer class **********************************************
- * holds buffers and size information of the actual target image
- * purpose: buffer management and avoidance of ugly globals
- **********************************************************************/
-class FrameBuf
-{
- protected:
- vector <uint8_t *> vecData;
- uint8_t *pCurrRow;
- uint8_t *pPalette;
- uint16_t uRows;
- uint16_t *upYSize;
- uint16_t *upMaxX;
- public:
- uint16_t uCols;
- uint16_t uXSize;
- uint16_t uMaxBlock;
- uint16_t uFrameNum;
- bool bHasBlocks;
- bool bHasRamps;
- FrameBuf(
- uint8_t *pPal=NULL, uint16_t frame=0, uint16_t xsize=0,
- uint16_t *pysize=NULL, uint16_t *pmaxx=NULL, uint16_t maxblock=0)
- {
- pCurrRow = new uint8_t[4*xsize];
- pPalette = pPal;
- uCols = 0;
- uRows = 0;
- uXSize = xsize;
- uFrameNum = frame;
- uMaxBlock = maxblock;
- upYSize = pysize;
- upMaxX = pmaxx;
- bHasBlocks= false;
- bHasRamps = false;
- }
- ~FrameBuf()
- {
- delete[] pCurrRow;
- for (vector <uint8_t *>::iterator vi=vecData.begin(); vi!=vecData.end(); vi++)
- delete[] *vi;
- vecData.clear();
- }
- void addLine()
- {
- ++uRows;
- uCols = 0;
- vecData.push_back(pCurrRow);
- pCurrRow = new uint8_t[4*uXSize];
- }
- void addPixel(uint16_t uColorNum)
- {
- if (uColorNum > TRANS_COL) {
- cerr << "\n*** there seemed to be an error, illegal color index " << uColorNum;
- cerr << "\n +++ at (" << uCols << "," << uRows << "), see for yourself *** \n\n";
- uColorNum = TRANS_COL; // sane setting to avoid segfaults
- }
-
- memcpy(pCurrRow + 4*uCols, pPalette + 4*uColorNum, 4*sizeof(uint8_t));
- if (++uCols == uXSize)
- addLine();
- else if ((uColorNum != TRANS_COL) && (upMaxX != NULL) && (uCols > *upMaxX))
- *upMaxX = uCols;
- }
- // used to return the actual image data
- uint8_t *getData()
- {
- uint16_t i;
- vector <uint8_t *>::reverse_iterator vri;
- // allocate a buffer to hold the actual image size
- uint8_t *tmp = new uint8_t[4*uXSize*uRows];
-
- // the lines are upside down inside the vector, use reverse iterator
- for (i=0, vri=vecData.rbegin(); vri!=vecData.rend(); vri++, i++)
- memcpy(tmp+4*uXSize*i, *vri, 4*uXSize*sizeof(uint8_t));
-
- *upYSize = uRows; // set height
-
- if (uCols > 0) {
- cerr << "\n*** there seemed to be an error (last line does not match boundary, " << uCols << " pixels left)";
- cerr << "\n +++ this is often caused by specifying an invalid width, see for yourself *** \n\n";
- }
-
- return tmp;
- }
-};
-
-uint16_t WINAPI celGetFrameCount(uint8_t *pFileBuf)
-{
- uint32_t tmp;
- memcpy(&tmp, pFileBuf, sizeof(uint32_t));
- return (uint16_t)tmp;
-}
-
-/***** Block Decoder ***************************************************
- * one of three possible decoding techniques necessary for .cel
- * possible block contents are either colored (in that case the
- * appropriate number of pixels are read) or transparent pixels
- * there are neither ramps nor plain pixels allowed here
- ***********************************************************************/
-uint8_t *celDecodeBlocks(uint8_t *pFileBuf, FrameBuf *pFrame, uint32_t *framestart)
-{
- uint32_t uFilePos=framestart[pFrame->uFrameNum];
- uint8_t cRead=0, i=0;
-
- if (!pFrame->bHasBlocks) // sanity check
- return NULL;
-
- while (uFilePos < framestart[pFrame->uFrameNum+1]) {
- cRead = pFileBuf[uFilePos++];
-
- if ((uFilePos == framestart[pFrame->uFrameNum]+1))
- // TODO: what is this 0x0A 0x00 stuff all about?
- if ((cRead == 0x0A) && (pFileBuf[uFilePos] == 0x00)) {
- uFilePos += 9;
- cRead = pFileBuf[uFilePos++];
- }
-
- if (cRead > 0x7F)
- // transparent block (complement, 256-val)
- for (i=0; i<256-cRead; i++)
- pFrame->addPixel(TRANS_COL);
- else if (cRead < pFrame->uMaxBlock + 1)
- // pixel block (block size pixels to be read!)
- for (i=0; i<cRead; i++)
- pFrame->addPixel(pFileBuf[uFilePos++]);
- else
- cerr << "\n*** block mode: illegal block (> max_size) ***\n\n";
- }
- return pFrame->getData();
-}
-
-/***** Ramp Decoder ****************************************************
- * the second of three possible decoding techniques necessary for .cel
- * each block save the first/last is enclosed by two 0x00 pairs
- * those blocks affect _TWO_ rows with one being 2 colored pixels shorter
- * the first/last "block" affects only one row
- ***********************************************************************/
-uint8_t *celDecodeRamps(uint8_t *pFileBuf, FrameBuf *pFrame, uint32_t *framestart, bool bLeft)
-{
- uint32_t uFrameLen = framestart[pFrame->uFrameNum+1]-framestart[pFrame->uFrameNum];
- uint32_t uFilePos=0;
- uint16_t uBlockLen=0, i=0, j=0;
- bool bFirstLonger=false;
-
- if (!pFrame->bHasRamps) // sanity check
- return NULL;
-
- if (pFrame->uXSize != 32) // only used in that case
- return NULL;
-
- if (!bLeft) { // get first two pixels for right side ramps
- pFrame->addPixel(pFileBuf[framestart[pFrame->uFrameNum]]);
- pFrame->addPixel(pFileBuf[framestart[pFrame->uFrameNum]+1]);
- }
-
- // do all the ramp blocks
- for (i=0; i<(uFrameLen == c_2RampSize ? 15 : 7); i++) {
- uBlockLen = (bLeft ? (c_RampOffsetLeft[i+1] - c_RampOffsetLeft[i]) : (c_RampOffsetRight[i+1] - c_RampOffsetRight[i]));
- uFilePos = framestart[pFrame->uFrameNum] + (bLeft ? c_RampOffsetLeft[i] : c_RampOffsetRight[i]) + 2;
- bFirstLonger = (i>(bLeft ? 7 : 6));
- if (bLeft) {
- // OK, first line, starting with transparency
- for (j=0; j<pFrame->uXSize - uBlockLen/2 + (bFirstLonger ? 0 : 2); j++)
- pFrame->addPixel(TRANS_COL);
- // fill it up with the pixel block
- for (j=0; j<uBlockLen/2 - (bFirstLonger ? 0 : 2); j++)
- pFrame->addPixel(pFileBuf[uFilePos++]);
- // second line, starting again with transparency
- for (j=0; j<pFrame->uXSize - uBlockLen/2 + (bFirstLonger ? 2 : 0); j++)
- pFrame->addPixel(TRANS_COL);
- // fill the second line with the remaining pixels
- for (j=0; j<uBlockLen/2 - (bFirstLonger ? 2 : 0); j++)
- pFrame->addPixel(pFileBuf[uFilePos++]);
- } else {
- if (pFrame->uCols != 0) // fill current line with trans (if not empty)
- for (j=pFrame->uXSize - pFrame->uCols; j>0; j--)
- pFrame->addPixel(TRANS_COL);
- // OK, insert the first pixels into a new line
- for (j=0; j<uBlockLen/2 - (bFirstLonger ? 0 : 2); j++)
- pFrame->addPixel(pFileBuf[uFilePos++]);
- // fill the line with transparency
- for (j=0; j<pFrame->uXSize - uBlockLen/2 + (bFirstLonger ? 0 : 2); j++)
- pFrame->addPixel(TRANS_COL);
- // start a second line with the remaining pixels
- for (j=0; j<uBlockLen/2 - (bFirstLonger ? 2 : 0); j++)
- pFrame->addPixel(pFileBuf[uFilePos++]);
- }
- }
-
- // now read the last 0x00 pair and fill up
- uBlockLen = (uFrameLen == c_2RampSize ? 30 : 2); // one or two ramps?
- uFilePos = framestart[pFrame->uFrameNum] + (bLeft ? c_RampOffsetLeft[i] : c_RampOffsetRight[i]) + 2;
- // the transparency for the last (single) 0x00 pair
- for (j=0; j<uBlockLen; j++)
- pFrame->addPixel(TRANS_COL);
- if (bLeft) { // left side only: the remaining line
- for (j=0; j<pFrame->uXSize - uBlockLen; j++)
- pFrame->addPixel(pFileBuf[uFilePos++]);
- }
-
- // now the rest of the file (plain)
- while (uFilePos < framestart[pFrame->uFrameNum+1])
- pFrame->addPixel(pFileBuf[uFilePos++]);
-
- // the uppermost line is emtpy when 2 ramps are used
- if (uFrameLen == c_2RampSize)
- for (j=0; j<pFrame->uXSize; j++)
- pFrame->addPixel(TRANS_COL);
-
- return pFrame->getData();
-}
-
-/***** celGetFrameData *************************************************
- * decode .cel data for given frame and xsize
- * Args:
- * *vpFileBuf the buffer containing the filecontent
- * *palette the palette (4 bytes for each of the 257 entries)
- * 256 colors are needed + 1 for alpha
- * uXSize this information must be given
- * uFrameNume the frame to get
- * *uYSize the actual value is returned therein
- * *uMaxX this can be used (if != NULL) to get the column
- * of the rightmost nontransparent pixel (useable
- * eg for fonts)
- *
- * Returns: an array containing 4 Bytes (RGBA) for each pixel
- *
- * ---------------------------------------------------------------
- * Comments: dirty hack, started from scratch @ 2000-10-11
- * cleanly rewritten during incorporation into ladiks StormLib
- * status: structured hack ;)
- *
- * It took me approx. 6 days to understand the format basics (hex viewer)
- * For this I had a little help from a dos tool ("ddecode", from
- * www.cowlevel.com, binary only, no sources) which, however, gave
- * me the general idea what the pictures are actually supposed to look like.
- *
- * The fine adjustments, however, took quite some time and a little luck.
- * After I had written to various people (mickyk and ladik), which could
- * not help me, but wished best luck (thanks, btw, it helped ;)), I tried
- * some reverse engineering which was not succesful in the end.
- *
- * I then had incidentally a new idea of what could be going on @ 2002-01-23.
- * It just came to my mind that I could retry some actual painting in
- * reverse order (had done that before to no avail) and when looking closer
- * at it I realized the "ramp" stuff. This really is the trickiest part and
- * it took me some eight days to implement it without breaking the other
- * parts of the code. Very odd format indeed.
- *
- * TODO: learn what 0x0A 0x00 means
- **********************************************************************/
-uint8_t * WINAPI celGetFrameData(uint8_t *pFileBuf, uint8_t *palette, uint16_t uXSize, uint16_t uFrameNum, uint16_t *uYSize, uint16_t *uMaxX)
-{
- FrameBuf *pFrame;
- uint32_t *framestart=NULL, frames=0, uFilePos=0;
- uint16_t i, tmpWord=0;
- uint8_t cRead=0, *data;
-
- memcpy(&frames, pFileBuf, sizeof(uint32_t));
- uFilePos += sizeof(uint32_t);
-
- if (pFileBuf == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (palette == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (uFrameNum > frames-1) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (uYSize == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- // in case we want to know the rightmost pixels column (usable eg. for fonts)
- if (uMaxX != NULL)
- *uMaxX = 0;
-
- // get the frame offsets
- framestart = new uint32_t[frames+1];
- for (i=0; i<frames+1; i++) {
- memcpy(&framestart[i], pFileBuf+uFilePos, sizeof(uint32_t));
- uFilePos += sizeof(uint32_t);
- }
-
- /****** block size *************************************************
- * depends on the image width
- ******************************/
-
- double erg = rint(sqrt(pow(2, rint(log((double)(framestart[uFrameNum+1] - framestart[uFrameNum])) / log(2.0)))));
- pFrame = new FrameBuf(palette, uFrameNum, uXSize, uYSize, uMaxX, max((uint16_t)min((int)erg, 0x7F), uXSize));
-
- /****** ramp detection -- AFAIK only needed for 32x32 tiles ********
- * here I use hard coded constants because this is the only simple
- * way to get the detection done; plus this stuff is only to be
- * found in such 32x32 (tile) files and so wont hurt anyone ;)
- ******************************************************************/
-
- uint32_t uFrameLen = framestart[uFrameNum+1] - framestart[uFrameNum];
- if ((uXSize == 32) && ((uFrameLen == c_2RampSize) || (uFrameLen == c_1RampSize))) {
-
- // use the static arrays for the check
- for (i=0; i<(uFrameLen == c_2RampSize ? 16 : 8); i++) {
- memcpy(&tmpWord, pFileBuf+framestart[uFrameNum]+c_RampOffsetLeft[i], sizeof(uint16_t));
- if (tmpWord != 0)
- break;
- }
- bool bRampsLeft = pFrame->bHasRamps = (i==(uFrameLen == c_2RampSize ? 16 : 8));
- if (!pFrame->bHasRamps) { // only one can apply
- for (i=0; i<(uFrameLen == c_2RampSize ? 16 : 8); i++) {
- memcpy(&tmpWord, pFileBuf+framestart[uFrameNum]+c_RampOffsetRight[i], sizeof(uint16_t));
- if (tmpWord != 0)
- break;
- }
- pFrame->bHasRamps = (i==(uFrameLen == c_2RampSize ? 16 : 8)); // bRampsLeft stays false in this case
- }
-
- if (pFrame->bHasRamps) { // decode ramps and be off (if appropriate)
- data = celDecodeRamps(pFileBuf, pFrame, framestart, bRampsLeft);
- delete pFrame;
- delete[] framestart;
- return data;
- }
- }
-
- /*********** block detection ***************************************
- * 0x0A as start byte seems to be sufficient (though I still dunno
- * what the trailing 10 bytes mean); in any other case we act as if
- * blocks were to be used and check afterwards if the image looks
- * OK (that is, the last line has no pixels in it)
- ******************************************************************/
-
- cRead = pFileBuf[framestart[uFrameNum]];
- if (cRead == 0x0A) // sufficient
- pFrame->bHasBlocks = true;
- // if width == 32 && framelen == 32*32, assume plain
- else if ((uXSize != 32) || (uFrameLen != 32*32)) { // check needed
- uFilePos=framestart[uFrameNum];
- i=0;
- // rush through the frame
- while (uFilePos < framestart[uFrameNum+1]) {
- cRead = pFileBuf[uFilePos++];
-
- // transparency blocks
- while (cRead > 0x7F) {
- i += 256-cRead;
- i %= uXSize;
- if (uFilePos < framestart[uFrameNum+1])
- cRead = pFileBuf[uFilePos++];
- else
- cRead = 0;
- }
-
- // colored pixel block
- if (uFilePos < framestart[uFrameNum+1]) {
- if (cRead < pFrame->uMaxBlock + 1) {
- i+=cRead;
- i%=uXSize;
- uFilePos+=cRead;
- } else {
- // when the value is out of valid blockrange
- i=1; // trigger error (1%uXSize != 0)
- break;
- }
- }
- }
- if (i%uXSize == 0) // looks as if we got it right
- pFrame->bHasBlocks=true;
- }
-
- if (pFrame->bHasBlocks) { // use block decoder if appropriate
- data = celDecodeBlocks(pFileBuf, pFrame, framestart);
- delete pFrame;
- delete[] framestart;
- return data;
- }
-
- // plain mode (#3), read each color index and write the pixel
- uFilePos=framestart[uFrameNum];
- while (uFilePos < framestart[uFrameNum+1])
- pFrame->addPixel(pFileBuf[uFilePos++]);
-
- // cleanup, return image data and height
- data = pFrame->getData();
- delete pFrame;
- delete[] framestart;
- return data;
-}
-
-uint16_t WINAPI cl2GetFrameCount(uint8_t *pFileBuf)
-{
- uint32_t tmp;
- memcpy(&tmp, pFileBuf, sizeof(uint32_t));
- memcpy(&tmp, pFileBuf+tmp, sizeof(uint32_t));
- return (uint16_t)tmp;
-}
-
-/***** cl2GetDirData ***************************************************
- * decodes all frames of a .cl2 for given direction and xsize
- * Args:
- * *pFileBuf the buffer containing the filecontent
- * *palette the palette (4 bytes for each of the 257 entries)
- * 256 colors are needed + 1 for alpha
- * uXSize this information must be given
- * uDirNum the direction to get the frames from
- * *uYSize the actual height is returned herein
- *
- * Returns: <frames> arrays containing 4 Bytes (RGBA) for each pixel
- * where <frames> is read at runtime and handed back via *uFrames
- *
- * ---------------------------------------------------------------
- * Comments: dirty hack, started from scratch @ 2000-10-12
- *
- * The format basics are similar to .cel, with the main difference
- * that the values read have reverse interpretation. In .cel a value
- * greater than 0x7F means transparency, while in .cl2 this means
- * color and vice-versa. .cl2 has the additional understanding
- * of blocks of the same color (0x80 .. 0xBF) where the one color is
- * written multiple times.
- *
- * .cl2 only uses the block scheme, so there is no detection
- * necessary in order to get it right. The only thing still unknown
- * is that 0x0A 0x00 stuff...
- *
- * TODO: learn what 0x0A 0x00 means
- ***********************************************************************/
-BYTE ** WINAPI cl2GetDirData(BYTE *pFileBuf, BYTE *palette, WORD uXSize, WORD uDirNum, WORD *uYSize)
-{
- FrameBuf *pFrame;
- uint32_t frames=0, *framestart=NULL, uFilePos=0;
- uint16_t i, fc;
- uint8_t cRead=0, **data=NULL;
-
- if (pFileBuf == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (palette == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (uDirNum > 7) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (uYSize == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- // get direction offsets
- uint32_t dirstart[8];
- for (i=0; i<8; i++) {
- memcpy(&dirstart[i], pFileBuf+uFilePos, sizeof(uint32_t));
- uFilePos += sizeof(uint32_t);
- }
-
- uFilePos = dirstart[uDirNum];
-
- memcpy(&frames, pFileBuf+uFilePos, sizeof(uint32_t));
- uFilePos += sizeof(uint32_t);
-
- data = new uint8_t*[frames];
-
- // get frame offsets
- framestart = new uint32_t[frames+1];
- for (i=0; i<frames+1; i++) {
- memcpy(&framestart[i], pFileBuf+uFilePos, sizeof(uint32_t));
- uFilePos += sizeof(uint32_t);
- }
-
- // get frame data
- for (fc=0; fc<frames; fc++) {
- pFrame = new FrameBuf(palette, 0, uXSize, uYSize, NULL, 0);
-
- uFilePos = dirstart[uDirNum] + framestart[fc];
- while (uFilePos < dirstart[uDirNum] + framestart[fc+1]) {
-
- cRead = pFileBuf[uFilePos++];
- if (cRead < 0x80) { // transparency
- // TODO: what is this 0x0A 0x00 stuff all about?
- if ((cRead == 0x0A) && (pFileBuf[uFilePos] == 0) && (uFilePos == dirstart[uDirNum] + framestart[fc] + 1))
- uFilePos += 9; // ignore the 9 bytes after 0x0A 0x00 at the framestart
- else
- for (i=0; i<cRead; i++)
- pFrame->addPixel(TRANS_COL);
- } else if (cRead < 0xC0) {
- // read the next byte and write it <0xBF - cRead> times
- for (i=0; i<0xBF - cRead; i++)
- pFrame->addPixel(pFileBuf[uFilePos]);
- ++uFilePos;
- } else // cRead > 0xBF
- // read a block of the given size and write it
- for (i=0; i < 256-cRead; i++)
- pFrame->addPixel(pFileBuf[uFilePos++]);
- }
-
- // got the frame data, save it
- data[fc] = pFrame->getData();
- delete pFrame;
- }
-
- delete[] framestart;
- return data;
-}
-
-/****** pcxGetData *****************************************************
- * decodes pcx files (256 color, as in diablo mpq)
- * Args:
- * *pFileBuf the buffer containing the filecontent
- * uFileSize the size of the file buffer
- * uTransColor the palette entry to be transparent
- * *uXSize the actual width is returned herein
- * *uYSize the actual height is returned herein
- *
- * Returns: an array containing 4 Bytes (RGBA) for each pixel
- *
- * ---------------------------------------------------------------
- * Comments: format info and pseudocode taken from:
- * Klaus Holtorf, "Das Handbuch der Grafikformate"
- * ISBN 3-7723-6393-8
- ***********************************************************************/
-BYTE * WINAPI pcxGetData(BYTE *pFileBuf, DWORD uFileSize, BYTE uTransColor, WORD *uXSize, WORD *uYSize)
-{
- uint32_t uFilePos=0;
- uint32_t uDataRead=0; // potentially big! (logo.pcx: 550 * 216 * 15 = 1,782,000)
- uint16_t i=0;
- uint8_t *data, *palette;
- uint8_t uColorNum=0, uCount=0;
-
- struct pcx_header_t {
- uint8_t id;
- uint8_t version;
- uint8_t compressed;
- uint8_t bpp;
- uint16_t x0;
- uint16_t y0;
- uint16_t x1;
- uint16_t y1;
- uint16_t xdpi;
- uint16_t ydpi;
- uint8_t pal[16][3];
- uint8_t reserved;
- uint8_t layers;
- uint16_t rowbytes;
- uint16_t colortype;
- uint8_t pad[58];
- } pcxHeader;
-
- if (pFileBuf == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (uXSize == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (uYSize == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- // get image information
- memcpy(&pcxHeader, pFileBuf, sizeof(struct pcx_header_t));
- *uXSize = (pcxHeader.x1 - pcxHeader.x0 + 1);
- *uYSize = (pcxHeader.y1 - pcxHeader.y0 + 1);
-
- if ((pcxHeader.version != 2) && (pcxHeader.version != 5)) {
- cerr << "cannot handle pcx v" << pcxHeader.version << "\n";
- return NULL;
- }
-
- // get palette
- palette = new uint8_t[256*4];
- if (pFileBuf[uFileSize - 768 - 1] != 0x0C) {
- cerr << "palette error at " << uFileSize - 768 - 1 << "\n";
- return NULL;
- }
- for (i=0; i<256; i++) {
- memcpy(palette+i*4, pFileBuf+uFileSize-768+i*3, 3*sizeof(uint8_t));
- palette[i*4+3] = 0xFF;
- }
- memset(palette+uTransColor*4, 0, 4*sizeof(uint8_t)); // transparent black
-
- // start right after the header
- uFilePos = sizeof(struct pcx_header_t);
- data = new uint8_t[*uXSize * *uYSize * 4];
- while (uDataRead < (uint32_t)(*uXSize * *uYSize)) {
- // decompress
- uColorNum = pFileBuf[uFilePos++];
- if ((pcxHeader.compressed) && (uColorNum > 0xBF)) {
- uCount = (uColorNum & 0x3F);
- uColorNum = pFileBuf[uFilePos++];
- } else
- uCount = 1;
-
- // draw count pixels with color val
- for (i=0; i<uCount; i++)
- memcpy(data+(uDataRead++)*4, palette+uColorNum*4, 4*sizeof(uint8_t));
- }
-
- // cleanup
- delete[] palette;
-
- return data;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/SCommon.cpp b/contrib/vmap_extractor_v2/stormlib/SCommon.cpp
deleted file mode 100644
index 393310f675d..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SCommon.cpp
+++ /dev/null
@@ -1,1074 +0,0 @@
-/*****************************************************************************/
-/* SCommon.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Common functions for StormLib, used by all SFile*** modules */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 24.03.03 1.00 Lad The first version of SFileCommon.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/* 12.06.04 1.01 Lad Renamed to SCommon.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-char StormLibCopyright[] = "StormLib v 4.50 Copyright Ladislav Zezula 1998-2003";
-
-//-----------------------------------------------------------------------------
-// The buffer for decryption engine.
-
-TMPQArchive * pFirstOpen = NULL; // The first member of MPQ archives chain
-LCID lcLocale = LANG_NEUTRAL; // File locale
-USHORT wPlatform = 0; // File platform
-
-//-----------------------------------------------------------------------------
-// Compression types
-
-//
-// Data compressions
-//
-// Can be combination of MPQ_COMPRESSION_PKWARE, MPQ_COMPRESSION_BZIP2
-// and MPQ_COMPRESSION_ZLIB. Some newer compressions are not supported
-// by older games. The table of supported compressions is here:
-//
-// MPQ_COMPRESSION_PKWARE - All games since Diablo I
-// MPQ_COMPRESSION_ZLIB - Games since Starcraft
-// MPQ_COMPRESSION_BZIP2 - Games since World of Warcraft
-//
-
-static int nDataCmp = MPQ_COMPRESSION_ZLIB;
-
-//
-// WAVE compressions by quality level
-//
-
-static int uWaveCmpLevel[] = {-1, 4, 2};
-static int uWaveCmpType[] = {MPQ_COMPRESSION_PKWARE, 0x81, 0x81};
-
-//-----------------------------------------------------------------------------
-// Storm buffer functions
-
-// Buffer for the decryption engine
-#define STORM_BUFFER_SIZE 0x500
-static DWORD StormBuffer[STORM_BUFFER_SIZE];
-static BOOL bStormBufferCreated = FALSE;
-
-int PrepareStormBuffer()
-{
- DWORD dwSeed = 0x00100001;
- DWORD index1 = 0;
- DWORD index2 = 0;
- int i;
-
- // Initialize the decryption buffer.
- // Do nothing if already done.
- if(bStormBufferCreated == FALSE)
- {
- for(index1 = 0; index1 < 0x100; index1++)
- {
- for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
- {
- DWORD temp1, temp2;
-
- dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB;
- temp1 = (dwSeed & 0xFFFF) << 0x10;
-
- dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB;
- temp2 = (dwSeed & 0xFFFF);
-
- StormBuffer[index2] = (temp1 | temp2);
- }
- }
- bStormBufferCreated = TRUE;
- }
- return ERROR_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// Encrypting and decrypting hash table
-
-void EncryptHashTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength)
-{
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch; // One key character
-
- // Prepare seeds
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-
- // Encrypt it
- dwSeed2 = 0xEEEEEEEE;
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *pdwTable;
- *pdwTable++ = ch ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-}
-
-void DecryptHashTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength)
-{
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch; // One key character
-
- // Prepare seeds
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-
- // Decrypt it
- dwSeed2 = 0xEEEEEEEE;
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *pdwTable ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- *pdwTable++ = ch;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Encrypting and decrypting block table
-
-void EncryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength)
-{
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch; // One key character
-
- // Prepare seeds
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-
- // Decrypt it
- dwSeed2 = 0xEEEEEEEE;
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *pdwTable;
- *pdwTable++ = ch ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-}
-
-void DecryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength)
-{
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch; // One key character
-
- // Prepare seeds
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-
- // Encrypt it
- dwSeed2 = 0xEEEEEEEE;
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *pdwTable ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- *pdwTable++ = ch;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Functions tries to get file decryption key. The trick comes from block
-// positions which are stored at the begin of each compressed file. We know the
-// file size, that means we know number of blocks that means we know the first
-// DWORD value in block position. And if we know encrypted and decrypted value,
-// we can find the decryption key !!!
-//
-// hf - MPQ file handle
-// block - DWORD array of block positions
-// ch - Decrypted value of the first block pos
-
-DWORD DetectFileSeed(DWORD * block, DWORD decrypted)
-{
- DWORD saveSeed1;
- DWORD temp = *block ^ decrypted; // temp = seed1 + seed2
- temp -= 0xEEEEEEEE; // temp = seed1 + StormBuffer[0x400 + (seed1 & 0xFF)]
-
- for(int i = 0; i < 0x100; i++) // Try all 255 possibilities
- {
- DWORD seed1;
- DWORD seed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Try the first DWORD (We exactly know the value)
- seed1 = temp - StormBuffer[0x400 + i];
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = block[0] ^ (seed1 + seed2);
-
- if(ch != decrypted)
- continue;
-
- // Add 1 because we are decrypting block positions
- saveSeed1 = seed1 + 1;
-
- // If OK, continue and test the second value. We don't know exactly the value,
- // but we know that the second one has lower 16 bits set to zero
- // (no compressed block is larger than 0xFFFF bytes)
- seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
- seed2 = ch + seed2 + (seed2 << 5) + 3;
-
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = block[1] ^ (seed1 + seed2);
-
- if((ch & 0xFFFF0000) == 0)
- return saveSeed1;
- }
- return 0;
-}
-
-// Function tries to detect file seed. It expectes at least two uncompressed bytes
-DWORD DetectFileSeed2(DWORD * pdwBlock, UINT nDwords, ...)
-{
- va_list argList;
- DWORD dwDecrypted[0x10];
- DWORD saveSeed1;
- DWORD dwTemp;
- DWORD i, j;
-
- // We need at least two DWORDS to detect the seed
- if(nDwords < 0x02 || nDwords > 0x10)
- return 0;
-
- va_start(argList, nDwords);
- for(i = 0; i < nDwords; i++)
- dwDecrypted[i] = va_arg(argList, DWORD);
- va_end(argList);
-
- dwTemp = (*pdwBlock ^ dwDecrypted[0]) - 0xEEEEEEEE;
- for(i = 0; i < 0x100; i++) // Try all 255 possibilities
- {
- DWORD seed1;
- DWORD seed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Try the first DWORD
- seed1 = dwTemp - StormBuffer[0x400 + i];
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = pdwBlock[0] ^ (seed1 + seed2);
-
- if(ch != dwDecrypted[0])
- continue;
-
- saveSeed1 = seed1;
-
- // If OK, continue and test all bytes.
- for(j = 1; j < nDwords; j++)
- {
- seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
- seed2 = ch + seed2 + (seed2 << 5) + 3;
-
- seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
- ch = pdwBlock[j] ^ (seed1 + seed2);
-
- if(ch == dwDecrypted[j] && j == nDwords - 1)
- return saveSeed1;
- }
- }
- return 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// Encrypting and decrypting MPQ blocks
-
-void EncryptMPQBlock(DWORD * block, DWORD dwLength, DWORD dwSeed1)
-{
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Round to DWORDs
- dwLength >>= 2;
-
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *block;
- *block++ = ch ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- }
-}
-
-void DecryptMPQBlock(DWORD * block, DWORD dwLength, DWORD dwSeed1)
-{
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Round to DWORDs
- dwLength >>= 2;
-
- while(dwLength-- > 0)
- {
- dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
- ch = *block ^ (dwSeed1 + dwSeed2);
-
- dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
- dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
- *block++ = ch;
- }
-}
-
-
-DWORD DecryptHashIndex(TMPQArchive * ha, const char * szFileName)
-{
- BYTE * pbKey = (BYTE *)szFileName;
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch;
-
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[0x000 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
- return (dwSeed1 & (ha->pHeader->dwHashTableSize - 1));
-}
-
-DWORD DecryptName1(const char * szFileName)
-{
- BYTE * pbKey = (BYTE *)szFileName;
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- DWORD ch;
-
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[0x100 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
- return dwSeed1;
-}
-
-DWORD DecryptName2(const char * szFileName)
-{
- BYTE * pbKey = (BYTE *)szFileName;
- DWORD dwSeed1 = 0x7FED7FED;
- DWORD dwSeed2 = 0xEEEEEEEE;
- int ch;
-
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++);
-
- dwSeed1 = StormBuffer[0x200 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
- return dwSeed1;
-}
-
-DWORD DecryptFileSeed(const char * szFileName)
-{
- BYTE * pbKey = (BYTE *)szFileName;
- DWORD dwSeed1 = 0x7FED7FED; // EBX
- DWORD dwSeed2 = 0xEEEEEEEE; // ESI
- DWORD ch;
-
- while(*pbKey != 0)
- {
- ch = toupper(*pbKey++); // ECX
-
- dwSeed1 = StormBuffer[0x300 + ch] ^ (dwSeed1 + dwSeed2);
- dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
- }
- return dwSeed1;
-}
-
-TMPQHash * GetHashEntry(TMPQArchive * ha, const char * szFileName)
-{
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash0; // File hash entry (start)
- TMPQHash * pHash; // File hash entry (current)
- DWORD dwIndex = (DWORD)(DWORD_PTR)szFileName;
- DWORD dwName1;
- DWORD dwName2;
-
- // If filename is given by index, we have to search all hash entries for the right index.
- if(dwIndex <= ha->pHeader->dwBlockTableSize)
- {
- // Pass all the hash entries and find the
- for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
- {
- if(pHash->dwBlockIndex == dwIndex)
- return pHash;
- }
- return NULL;
- }
-
- // Decrypt name and block index
- dwIndex = DecryptHashIndex(ha, szFileName);
- dwName1 = DecryptName1(szFileName);
- dwName2 = DecryptName2(szFileName);
- pHash = pHash0 = ha->pHashTable + dwIndex;
-
- // Look for hash index
- while(pHash->dwBlockIndex != HASH_ENTRY_FREE)
- {
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex != HASH_ENTRY_DELETED)
- return pHash;
-
- // Move to the next hash entry
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pHash0)
- break;
- }
-
- // File was not found
- return NULL;
-}
-
-// Retrieves the locale-specific hash entry
-TMPQHash * GetHashEntryEx(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
-{
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash0 = NULL; // Language-neutral hash entry
- TMPQHash * pHashX = NULL; // Language-speficic
- TMPQHash * pHash = GetHashEntry(ha, szFileName);
-
- if(pHash != NULL)
- {
- TMPQHash * pHashStart = pHash;
- DWORD dwName1 = pHash->dwName1;
- DWORD dwName2 = pHash->dwName2;
-
- while(pHash->dwBlockIndex != HASH_ENTRY_FREE)
- {
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2)
- {
- if(pHash->lcLocale == LANG_NEUTRAL)
- pHash0 = pHash;
- if(pHash->lcLocale == lcLocale)
- pHashX = pHash;
-
- // If both found, break the loop
- if(pHash0 != NULL && pHashX != NULL)
- break;
- }
-
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pHashStart)
- return NULL;
- }
-
- if(lcLocale != LANG_NEUTRAL && pHashX != NULL)
- return pHashX;
- if(pHash0 != NULL)
- return pHash0;
- return NULL;
- }
-
- return pHash;
-}
-
-// Encrypts file name and gets the hash entry
-// Returns the hash pointer, which is always within the allocated array
-TMPQHash * FindFreeHashEntry(TMPQArchive * ha, const char * szFileName)
-{
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash0; // File hash entry (search start)
- TMPQHash * pHash; // File hash entry
- DWORD dwIndex = DecryptHashIndex(ha, szFileName);
- DWORD dwName1 = DecryptName1(szFileName);
- DWORD dwName2 = DecryptName2(szFileName);
- DWORD dwBlockIndex = 0xFFFFFFFF;
-
- // Save the starting hash position
- pHash = pHash0 = ha->pHashTable + dwIndex;
-
- // Look for the first free hash entry. Can be also a deleted entry
- while(pHash->dwBlockIndex < HASH_ENTRY_DELETED)
- {
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pHash0)
- return NULL;
- }
-
- // Fill the hash entry with the informations about the file name
- pHash->dwName1 = dwName1;
- pHash->dwName2 = dwName2;
- pHash->lcLocale = (USHORT)lcLocale;
- pHash->wPlatform = wPlatform;
-
- // Now we have to find a free block entry
- for(dwIndex = 0; dwIndex < ha->pHeader->dwBlockTableSize; dwIndex++)
- {
- TMPQBlock * pBlock = ha->pBlockTable + dwIndex;
-
- if((pBlock->dwFlags & MPQ_FILE_EXISTS) == 0)
- {
- dwBlockIndex = dwIndex;
- break;
- }
- }
-
- // If no free block entry found, we have to use the index
- // at the end of the current block table
- if(dwBlockIndex == 0xFFFFFFFF)
- dwBlockIndex = ha->pHeader->dwBlockTableSize;
- pHash->dwBlockIndex = dwBlockIndex;
- return pHash;
-}
-
-//-----------------------------------------------------------------------------
-// Checking for valid archive handle and valid file handle
-
-BOOL IsValidMpqHandle(TMPQArchive * ha)
-{
- if(ha == NULL || IsBadReadPtr(ha, sizeof(TMPQArchive)))
- return FALSE;
- if(ha->pHeader == NULL || IsBadReadPtr(ha->pHeader, sizeof(TMPQHeader)))
- return FALSE;
-
- return (ha->pHeader->dwID == ID_MPQ);
-}
-
-BOOL IsValidFileHandle(TMPQFile * hf)
-{
- if(hf == NULL || IsBadReadPtr(hf, sizeof(TMPQFile)))
- return FALSE;
-
- if(hf->hFile != INVALID_HANDLE_VALUE)
- return TRUE;
-
- return IsValidMpqHandle(hf->ha);
-}
-
-// This function writes a local file into the MPQ archive.
-// Returns 0 if OK, otherwise error code.
-// TODO: Test for archives > 4GB
-int AddFileToArchive(
- TMPQArchive * ha,
- HANDLE hFile,
- const char * szArchivedName,
- DWORD dwFlags,
- DWORD dwQuality,
- int nFileType,
- BOOL * pbReplaced)
-{
- LARGE_INTEGER RelativePos = {0};
- LARGE_INTEGER FilePos = {0};
- LARGE_INTEGER TempPos;
- TMPQBlockEx * pBlockEx = NULL; // Entry in the extended block table
- TMPQBlock * pBlock = NULL; // Entry in the block table
- TMPQHash * pHash = NULL; // Entry in the hash table
- DWORD * pdwBlockPos = NULL; // Block position table (compressed files only)
- BYTE * pbFileData = NULL; // Uncompressed (source) data
- BYTE * pbCompressed = NULL; // Compressed (target) data
- BYTE * pbToWrite = NULL; // Data to write to the file
- DWORD dwBlockPosLen = 0; // Length of the block table positions
- DWORD dwTransferred = 0; // Number of bytes written into archive file
- DWORD dwFileSize = 0; // Size of the file to add
- DWORD dwSeed1 = 0; // Encryption seed
- DWORD nBlocks = 0; // Number of file blocks
- DWORD nBlock = 0; // Index of the currently written block
- BOOL bReplaced = FALSE; // TRUE if replaced, FALSE if added
- int nCmpFirst = nDataCmp; // Compression for the first data block
- int nCmpNext = nDataCmp; // Compression for the next data blocks
- int nCmp = nDataCmp; // Current compression
- int nCmpLevel = -1; // Compression level
- int nError = ERROR_SUCCESS;
-
- // Set the correct compression types
- if(dwFlags & MPQ_FILE_COMPRESS_PKWARE)
- nCmpFirst = nCmpNext = MPQ_COMPRESSION_PKWARE;
-
- if(dwFlags & MPQ_FILE_COMPRESS_MULTI)
- {
- if(nFileType == SFILE_TYPE_DATA)
- nCmpFirst = nCmpNext = nDataCmp;
-
- if(nFileType == SFILE_TYPE_WAVE)
- {
- nCmpNext = uWaveCmpType[dwQuality];
- nCmpLevel = uWaveCmpLevel[dwQuality];
- }
- }
-
- // Check if the file already exists in the archive
- if(nError == ERROR_SUCCESS)
- {
- if((pHash = GetHashEntryEx(ha, szArchivedName, lcLocale)) != NULL)
- {
- if(pHash->lcLocale == lcLocale)
- {
- if((dwFlags & MPQ_FILE_REPLACEEXISTING) == 0)
- {
- nError = ERROR_ALREADY_EXISTS;
- pHash = NULL;
- }
- else
- bReplaced = TRUE;
- }
- else
- pHash = NULL;
- }
-
- if(nError == ERROR_SUCCESS && pHash == NULL)
- {
- pHash = FindFreeHashEntry(ha, szArchivedName);
- if(pHash == NULL)
- nError = ERROR_HANDLE_DISK_FULL;
- }
- }
-
- // Get the block table entry for the file
- if(nError == ERROR_SUCCESS)
- {
- DWORD dwFileSizeHigh = 0;
-
- // Get the size of the added file
- dwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
- if(dwFileSizeHigh != 0)
- nError = ERROR_PARAMETER_QUOTA_EXCEEDED;
-
- // Fix the flags, if the file is too small
- if(dwFileSize < 0x04)
- dwFlags &= ~(MPQ_FILE_ENCRYPTED | MPQ_FILE_FIXSEED);
- if(dwFileSize < 0x20)
- dwFlags &= ~MPQ_FILE_COMPRESSED;
-
- if(pHash->dwBlockIndex == HASH_ENTRY_FREE)
- pHash->dwBlockIndex = ha->pHeader->dwBlockTableSize;
-
- // The block table index cannot be larger than hash table size
- if(pHash->dwBlockIndex >= ha->pHeader->dwHashTableSize)
- nError = ERROR_HANDLE_DISK_FULL;
- }
-
- // The file will be stored after the end of the last archived file
- // (i.e. at old position of archived file
- if(nError == ERROR_SUCCESS)
- {
- TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize;
- const char * szTemp = strrchr(szArchivedName, '\\');
-
- // Get the position of the first file
- RelativePos.QuadPart = ha->pHeader->dwHeaderSize;
-
- // Find the position of the last file. It has to be after the last archived file
- // (Do not use the dwArchiveSize here, because it may or may not
- // include the hash table at the end of the file
- pBlockEx = ha->pExtBlockTable;
- for(pBlock = ha->pBlockTable; pBlock < pBlockEnd; pBlock++, pBlockEx++)
- {
- if(pBlock->dwFlags & MPQ_FILE_EXISTS)
- {
- TempPos.HighPart = pBlockEx->wFilePosHigh;
- TempPos.LowPart = pBlock->dwFilePos;
- TempPos.QuadPart += pBlock->dwCSize;
-
- if(TempPos.QuadPart > RelativePos.QuadPart)
- RelativePos = TempPos;
- }
- }
-
- // When format V1, we cannot exceed 4 GB
- if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
- {
- TempPos.QuadPart = ha->MpqPos.QuadPart + RelativePos.QuadPart;
- TempPos.QuadPart += ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- TempPos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- TempPos.QuadPart += dwFileSize;
-
- if(TempPos.HighPart != 0)
- nError = ERROR_DISK_FULL;
- }
-
- // Get pointers to both block entries of the file
- pBlockEx = ha->pExtBlockTable + pHash->dwBlockIndex;
- pBlock = ha->pBlockTable + pHash->dwBlockIndex;
-
- // Save the file size info
- pBlockEx->wFilePosHigh = (USHORT)RelativePos.HighPart;
- pBlock->dwFilePos = RelativePos.LowPart;
- pBlock->dwFSize = GetFileSize(hFile, NULL);
- pBlock->dwFlags = dwFlags | MPQ_FILE_EXISTS;
-
- // Create seed1 for file encryption
- if(szTemp != NULL)
- szArchivedName = szTemp + 1;
-
- if(dwFlags & MPQ_FILE_ENCRYPTED)
- {
- dwSeed1 = DecryptFileSeed(szArchivedName);
-
- if(dwFlags & MPQ_FILE_FIXSEED)
- dwSeed1 = (dwSeed1 + pBlock->dwFilePos) ^ pBlock->dwFSize;
- }
- }
-
- // Allocate buffer for the input data
- if(nError == ERROR_SUCCESS)
- {
- nBlocks = (pBlock->dwFSize / ha->dwBlockSize) + 1;
- if(pBlock->dwFSize % ha->dwBlockSize)
- nBlocks++;
-
- pBlock->dwCSize = 0;
- if((pbFileData = ALLOCMEM(BYTE, ha->dwBlockSize)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- pbToWrite = pbFileData;
- }
-
- // Allocate buffers for the compressed data
- if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_COMPRESSED))
- {
- pdwBlockPos = ALLOCMEM(DWORD, nBlocks + 1);
- pbCompressed = ALLOCMEM(BYTE, ha->dwBlockSize * 2);
- if(pdwBlockPos == NULL || pbCompressed == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- pbToWrite = pbCompressed;
- }
-
- // Set the file position to the point where the file will be stored
- if(nError == ERROR_SUCCESS)
- {
- // Set the file pointer to file data position
- FilePos.QuadPart = ha->MpqPos.QuadPart + RelativePos.QuadPart;
- if(FilePos.QuadPart != ha->FilePointer.QuadPart)
- {
- SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN);
- ha->FilePointer = FilePos;
- }
- }
-
- // Write block positions (if the file will be compressed)
- if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_COMPRESSED))
- {
- dwBlockPosLen = nBlocks * sizeof(DWORD);
- if(dwFlags & MPQ_FILE_HAS_EXTRA)
- dwBlockPosLen += sizeof(DWORD);
-
- memset(pdwBlockPos, 0, dwBlockPosLen);
- pdwBlockPos[0] = dwBlockPosLen;
-
- // Write the block positions
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pdwBlockPos, nBlocks);
- WriteFile(ha->hFile, pdwBlockPos, dwBlockPosLen, &dwTransferred, NULL);
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pdwBlockPos, nBlocks);
-
- if(dwTransferred == dwBlockPosLen)
- pBlock->dwCSize += dwBlockPosLen;
- else
- nError = GetLastError();
-
- // Update the current position in the file
- ha->HashTablePos.QuadPart = FilePos.QuadPart + dwTransferred;
- }
-
- // Write all file blocks
- if(nError == ERROR_SUCCESS)
- {
- nCmp = nCmpFirst;
-
- SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
- for(nBlock = 0; nBlock < nBlocks-1; nBlock++)
- {
- DWORD dwInLength = ha->dwBlockSize;
- DWORD dwOutLength = ha->dwBlockSize;
-
- // Load the block from the file
- ReadFile(hFile, pbFileData, ha->dwBlockSize, &dwInLength, NULL);
- if(dwInLength == 0)
- break;
-
- // Compress the block, if necessary
- dwOutLength = dwInLength;
- if(pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- {
- // Should be enough for compression
- int nOutLength = ha->dwBlockSize * 2;
- int nCmpType = 0;
-
- if(pBlock->dwFlags & MPQ_FILE_COMPRESS_PKWARE)
- Compress_pklib((char *)pbCompressed, &nOutLength, (char *)pbFileData, dwInLength, &nCmpType, 0);
-
- if(pBlock->dwFlags & MPQ_FILE_COMPRESS_MULTI)
- SCompCompress((char *)pbCompressed, &nOutLength, (char *)pbFileData, dwInLength, nCmp, 0, nCmpLevel);
-
- // The compressed block size must NOT be the same or greater like
- // the original block size. If yes, do not compress the block
- // and store the data as-is.
- if(nOutLength >= (int)dwInLength)
- {
- memcpy(pbCompressed, pbFileData, dwInLength);
- nOutLength = dwInLength;
- }
-
- // Update block positions
- dwOutLength = nOutLength;
- pdwBlockPos[nBlock+1] = pdwBlockPos[nBlock] + dwOutLength;
- nCmp = nCmpNext;
- }
-
- // Encrypt the block, if necessary
- if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pbToWrite, dwOutLength / sizeof(DWORD));
- EncryptMPQBlock((DWORD *)pbToWrite, dwOutLength, dwSeed1 + nBlock);
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pbToWrite, dwOutLength / sizeof(DWORD));
- }
-
- // Write the block
- WriteFile(ha->hFile, pbToWrite, dwOutLength, &dwTransferred, NULL);
- if(dwTransferred != dwOutLength)
- {
- nError = ERROR_DISK_FULL;
- break;
- }
-
- // Update the hash table position and the compressed file size
- ha->HashTablePos.QuadPart += dwTransferred;
- pBlock->dwCSize += dwOutLength;
- }
- }
-
- // Now save the block positions
- if(nError == ERROR_SUCCESS && (pBlock->dwFlags & MPQ_FILE_COMPRESSED))
- {
- if(dwFlags & MPQ_FILE_HAS_EXTRA)
- pdwBlockPos[nBlocks] = pdwBlockPos[nBlocks-1];
-
- // If file is encrypted, block positions are also encrypted
- if(dwFlags & MPQ_FILE_ENCRYPTED)
- EncryptMPQBlock(pdwBlockPos, dwBlockPosLen, dwSeed1 - 1);
-
- // Set the position back to the block table
- SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN);
-
- // Write block positions to the archive
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pdwBlockPos, nBlocks);
- WriteFile(ha->hFile, pdwBlockPos, dwBlockPosLen, &dwTransferred, NULL);
- if(dwTransferred != dwBlockPosLen)
- nError = ERROR_DISK_FULL;
-
- ha->FilePointer.QuadPart = ha->FilePointer.QuadPart + dwTransferred;
- }
-
- // If success, we have to change the settings
- // in MPQ header. If failed, we have to clean hash entry
- if(nError == ERROR_SUCCESS)
- {
- ha->pLastFile = NULL;
- ha->dwBlockPos = 0;
- ha->dwBuffPos = 0;
- ha->dwFlags |= MPQ_FLAG_CHANGED;
-
- // Add new entry to the block table (if needed)
- if(pHash->dwBlockIndex >= ha->pHeader->dwBlockTableSize)
- ha->pHeader->dwBlockTableSize++;
-
- // Hash table size in the TMPQArchive is already set at this point
- RelativePos.QuadPart = ha->HashTablePos.QuadPart - ha->MpqPos.QuadPart;
- ha->pHeader->dwHashTablePos = RelativePos.LowPart;
- ha->pHeader->wHashTablePosHigh = (USHORT)RelativePos.HighPart;
-
- // Update block table pos
- RelativePos.QuadPart += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash));
- ha->pHeader->wBlockTablePosHigh = (USHORT)RelativePos.HighPart;
- ha->pHeader->dwBlockTablePos = RelativePos.LowPart;
- ha->BlockTablePos.QuadPart = RelativePos.QuadPart + ha->MpqPos.QuadPart;
-
- // If the archive size exceeded 4GB, we have to use extended block table pos
- RelativePos.QuadPart += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock));
- if(RelativePos.HighPart != 0)
- {
- ha->pHeader->ExtBlockTablePos = RelativePos;
- ha->ExtBlockTablePos.QuadPart = RelativePos.QuadPart + ha->MpqPos.QuadPart;
-
- RelativePos.QuadPart += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx));
- }
-
- // Update archive size (only valid for version V1)
- ha->MpqSize = RelativePos;
- ha->pHeader->dwArchiveSize = ha->MpqSize.LowPart;
- }
- else
- {
- // Clear the hash table entry
- if(pHash != NULL)
- memset(pHash, 0xFF, sizeof(TMPQHash));
- }
-
- // Cleanup
- if(pbCompressed != NULL)
- FREEMEM(pbCompressed);
- if(pdwBlockPos != NULL)
- FREEMEM(pdwBlockPos);
- if(pbFileData != NULL)
- FREEMEM(pbFileData);
- if(pbReplaced != NULL)
- *pbReplaced = bReplaced;
- return nError;
-}
-
-int SetDataCompression(int nDataCompression)
-{
- nDataCmp = nDataCompression;
- return 0;
-}
-
-// This method saves MPQ header, hash table and block table.
-// TODO: Test for archives > 4GB
-int SaveMPQTables(TMPQArchive * ha)
-{
- BYTE * pbBuffer = NULL;
- DWORD dwBytes;
- DWORD dwWritten;
- DWORD dwBuffSize = max(ha->pHeader->dwHashTableSize, ha->pHeader->dwBlockTableSize);
- int nError = ERROR_SUCCESS;
-
- // Allocate buffer for encrypted tables
- if(nError == ERROR_SUCCESS)
- {
- // Allocate temporary buffer for tables encryption
- pbBuffer = ALLOCMEM(BYTE, sizeof(TMPQHash) * dwBuffSize);
- if(pbBuffer == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Write the MPQ Header
- if(nError == ERROR_SUCCESS)
- {
- DWORD dwHeaderSize = ha->pHeader->dwHeaderSize;
-
- // Write the MPQ header
- SetFilePointer(ha->hFile, ha->MpqPos.LowPart, &ha->MpqPos.HighPart, FILE_BEGIN);
-
- // Convert to little endian for file save
- BSWAP_TMPQHEADER(ha->pHeader);
- WriteFile(ha->hFile, ha->pHeader, dwHeaderSize, &dwWritten, NULL);
- BSWAP_TMPQHEADER(ha->pHeader);
-
- if(dwWritten != ha->pHeader->dwHeaderSize)
- nError = ERROR_DISK_FULL;
- }
-
- // Write the hash table
- if(nError == ERROR_SUCCESS)
- {
- // Copy the hash table to temporary buffer
- dwBytes = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- memcpy(pbBuffer, ha->pHashTable, dwBytes);
-
- // Convert to little endian for file save
- EncryptHashTable((DWORD *)pbBuffer, (BYTE *)"(hash table)", dwBytes >> 2);
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBuffer, dwBytes / sizeof(DWORD));
-
- // Set the file pointer to the offset of the hash table and write it
- SetFilePointer(ha->hFile, ha->HashTablePos.LowPart, (PLONG)&ha->HashTablePos.HighPart, FILE_BEGIN);
- WriteFile(ha->hFile, pbBuffer, dwBytes, &dwWritten, NULL);
- if(dwWritten != dwBytes)
- nError = ERROR_DISK_FULL;
- }
-
- // Write the block table
- if(nError == ERROR_SUCCESS)
- {
- // Copy the block table to temporary buffer
- dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- memcpy(pbBuffer, ha->pBlockTable, dwBytes);
-
- // Encrypt the block table and write it to the file
- EncryptBlockTable((DWORD *)pbBuffer, (BYTE *)"(block table)", dwBytes >> 2);
-
- // Convert to little endian for file save
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBuffer, dwBytes / sizeof(DWORD));
- WriteFile(ha->hFile, pbBuffer, dwBytes, &dwWritten, NULL);
- if(dwWritten != dwBytes)
- nError = ERROR_DISK_FULL;
- }
-
- // Write the extended block table
- if(nError == ERROR_SUCCESS && ha->pHeader->ExtBlockTablePos.QuadPart != 0)
- {
- // We expect format V2 or newer in this case
- assert(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2);
-
- // Copy the block table to temporary buffer
- dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx);
- memcpy(pbBuffer, ha->pExtBlockTable, dwBytes);
-
- // Convert to little endian for file save
- BSWAP_ARRAY16_UNSIGNED((USHORT *)pbBuffer, dwBytes / sizeof(USHORT));
- WriteFile(ha->hFile, pbBuffer, dwBytes, &dwWritten, NULL);
- if(dwWritten != dwBytes)
- nError = ERROR_DISK_FULL;
- }
-
-
- // Set end of file here
- if(nError == ERROR_SUCCESS)
- {
- SetEndOfFile(ha->hFile);
- }
-
- // Cleanup and exit
- if(pbBuffer != NULL)
- FREEMEM(pbBuffer);
- return nError;
-}
-
-// Frees the MPQ archive
-// TODO: Test for archives > 4GB
-void FreeMPQArchive(TMPQArchive *& ha)
-{
- if(ha != NULL)
- {
- FREEMEM(ha->pbBlockBuffer);
- FREEMEM(ha->pBlockTable);
- FREEMEM(ha->pExtBlockTable);
- FREEMEM(ha->pHashTable);
- if(ha->pListFile != NULL)
- SListFileFreeListFile(ha);
-
- if(ha->hFile != INVALID_HANDLE_VALUE)
- CloseHandle(ha->hFile);
- FREEMEM(ha);
- ha = NULL;
- }
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/SCommon.h b/contrib/vmap_extractor_v2/stormlib/SCommon.h
deleted file mode 100644
index b53be0ae2a8..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SCommon.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*****************************************************************************/
-/* SCommon.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Common functions for encryption/decryption from Storm.dll. Included by */
-/* SFile*** functions, do not include and do not use this file directly */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 24.03.03 1.00 Lad The first version of SFileCommon.h */
-/* 12.06.04 1.00 Lad Renamed to SCommon.h */
-/*****************************************************************************/
-
-#ifndef __SCOMMON_H__
-#define __SCOMMON_H__
-
-//-----------------------------------------------------------------------------
-// StormLib private defines
-
-#define SFILE_TYPE_DATA 0 // Process the file as data file
-#define SFILE_TYPE_WAVE 1 // Process the file as WAVe file
-
-//-----------------------------------------------------------------------------
-// External variables
-
-extern TMPQArchive * pFirstOpen;
-extern LCID lcLocale;
-
-//-----------------------------------------------------------------------------
-// Encryption and decryption functions
-
-int PrepareStormBuffer();
-
-void EncryptHashTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength);
-void DecryptHashTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength);
-TMPQHash * FindFreeHashEntry(TMPQArchive * ha, const char * szFileName);
-
-void EncryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength);
-void DecryptBlockTable(DWORD * pdwTable, BYTE * pbKey, DWORD dwLength);
-
-DWORD DetectFileSeed(DWORD * block, DWORD decrypted);
-DWORD DetectFileSeed2(DWORD * block, UINT nDwords, ...);
-void EncryptMPQBlock(DWORD * pdwBlock, DWORD dwLength, DWORD dwSeed1);
-void DecryptMPQBlock(DWORD * pdwBlock, DWORD dwLength, DWORD dwSeed1);
-
-DWORD DecryptHashIndex(TMPQArchive * ha, const char * szFileName);
-DWORD DecryptName1 (const char * szFileName);
-DWORD DecryptName2 (const char * szFileName);
-DWORD DecryptFileSeed (const char * szFileName);
-
-TMPQHash * GetHashEntry (TMPQArchive * ha, const char * szFileName);
-TMPQHash * GetHashEntryEx(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
-
-//-----------------------------------------------------------------------------
-// Compression and decompression functions
-
-int Compress_pklib (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel);
-int Decompress_pklib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength);
-
-//-----------------------------------------------------------------------------
-// Checking functions
-
-BOOL IsValidMpqHandle(TMPQArchive * ha);
-BOOL IsValidFileHandle(TMPQFile * hf);
-
-//-----------------------------------------------------------------------------
-// Other functions
-
-BOOL SFileOpenArchiveEx(const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMPQ, DWORD dwAccessMode = GENERIC_READ);
-int AddFileToArchive(TMPQArchive * ha, HANDLE hFile, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality, int nFileType, BOOL * pbReplaced);
-int SetDataCompression(int nDataCompression);
-int SaveMPQTables(TMPQArchive * ha);
-void FreeMPQArchive(TMPQArchive *& ha);
-
-BOOL CheckWildCard(const char * szString, const char * szWildCard);
-
-//-----------------------------------------------------------------------------
-// Listfile functions
-
-int SListFileCreateListFile(TMPQArchive * ha);
-int SListFileAddNode(TMPQArchive * ha, const char * szAddedFile);
-int SListFileRemoveNode(TMPQArchive * ha, const char * szFileName);
-int SListFileRenameNode(TMPQArchive * ha, const char * szOldFileName, const char * szNewFileName);
-int SListFileFreeListFile(TMPQArchive * ha);
-
-int SListFileSaveToMpq(TMPQArchive * ha);
-
-#endif // __SCOMMON_H__
-
diff --git a/contrib/vmap_extractor_v2/stormlib/SCompression.cpp b/contrib/vmap_extractor_v2/stormlib/SCompression.cpp
deleted file mode 100644
index 612ef2cc262..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SCompression.cpp
+++ /dev/null
@@ -1,715 +0,0 @@
-/*****************************************************************************/
-/* SCompression.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* This module serves as a bridge between StormLib code and (de)compression */
-/* functions. All (de)compression calls go (and should only go) through this */
-/* module. No system headers should be included in this module to prevent */
-/* compile-time problems. */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 01.04.03 1.00 Lad The first version of SCompression.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-#include <string.h>
-
-// Include functions from Pkware Data Compression Library
-#include "pklib/pklib.h"
-
-// Include functions from zlib
-#ifndef __SYS_ZLIB
-#include "zlib/zlib.h" // Include functions from zlib
-#else
-#include <zlib.h> // If zlib is available on system, use this instead
-#endif
-
-// Include functions from Huffmann compression
-#include "huffman/huff.h"
-
-// Include functions from WAVe compression
-#include "wave/wave.h"
-
-// Include functions from BZip2 compression library
-#ifndef __SYS_BZLIB
-#include "bzip2/bzlib.h" // Include functions from bzlib
-#else
-#include <bzlib.h> // If bzlib is available on system, use this instead
-#endif
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-// Information about the input and output buffers for pklib
-typedef struct
-{
- char * pInBuff; // Pointer to input data buffer
- int nInPos; // Current offset in input data buffer
- int nInBytes; // Number of bytes in the input buffer
- char * pOutBuff; // Pointer to output data buffer
- int nOutPos; // Position in the output buffer
- int nMaxOut; // Maximum number of bytes in the output buffer
-} TDataInfo;
-
-// Table of compression functions
-typedef int (*COMPRESS)(char *, int *, char *, int, int *, int);
-typedef struct
-{
- unsigned long dwMask; // Compression mask
- COMPRESS Compress; // Compression function
-} TCompressTable;
-
-// Table of decompression functions
-typedef int (*DECOMPRESS)(char *, int *, char *, int);
-typedef struct
-{
- unsigned long dwMask; // Decompression bit
- DECOMPRESS Decompress; // Decompression function
-} TDecompressTable;
-
-
-/*****************************************************************************/
-/* */
-/* Support functions for Pkware Data Compression Library */
-/* */
-/*****************************************************************************/
-
-// Function loads data from the input buffer. Used by Pklib's "implode"
-// and "explode" function as user-defined callback
-// Returns number of bytes loaded
-//
-// char * buf - Pointer to a buffer where to store loaded data
-// unsigned int * size - Max. number of bytes to read
-// void * param - Custom pointer, parameter of implode/explode
-
-static unsigned int ReadInputData(char * buf, unsigned int * size, void * param)
-{
- TDataInfo * pInfo = (TDataInfo *)param;
- unsigned int nMaxAvail = (pInfo->nInBytes - pInfo->nInPos);
- unsigned int nToRead = *size;
-
- // Check the case when not enough data available
- if(nToRead > nMaxAvail)
- nToRead = nMaxAvail;
-
- // Load data and increment offsets
- memcpy(buf, pInfo->pInBuff + pInfo->nInPos, nToRead);
- pInfo->nInPos += nToRead;
-
- return nToRead;
-}
-
-// Function for store output data. Used by Pklib's "implode" and "explode"
-// as user-defined callback
-//
-// char * buf - Pointer to data to be written
-// unsigned int * size - Number of bytes to write
-// void * param - Custom pointer, parameter of implode/explode
-
-static void WriteOutputData(char * buf, unsigned int * size, void * param)
-{
- TDataInfo * pInfo = (TDataInfo *)param;
- unsigned int nMaxWrite = (pInfo->nMaxOut - pInfo->nOutPos);
- unsigned int nToWrite = *size;
-
- // Check the case when not enough space in the output buffer
- if(nToWrite > nMaxWrite)
- nToWrite = nMaxWrite;
-
- // Write output data and increments offsets
- memcpy(pInfo->pOutBuff + pInfo->nOutPos, buf, nToWrite);
- pInfo->nOutPos += nToWrite;
-}
-
-/*****************************************************************************/
-/* */
-/* "80" is IMA ADPCM stereo (de)compression */
-/* "40" is IMA ADPCM mono (de)compression */
-/* */
-/*****************************************************************************/
-
-int Compress_wave_mono(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel)
-{
- // Prepare the compression level for the next compression
- // (After us, the Huffmann compression will be called)
- if(0 < nCmpLevel && nCmpLevel <= 2)
- {
- nCmpLevel = 4;
- *pCmpType = 6;
- }
- else if(nCmpLevel == 3)
- {
- nCmpLevel = 6;
- *pCmpType = 8;
- }
- else
- {
- nCmpLevel = 5;
- *pCmpType = 7;
- }
- *pdwOutLength = CompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (short *)pbInBuffer, dwInLength, 1, nCmpLevel);
- return 0;
-}
-
-int Decompress_wave_mono(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- *pdwOutLength = DecompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (unsigned char *)pbInBuffer, dwInLength, 1);
- return 1;
-}
-
-int Compress_wave_stereo(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel)
-{
- // Prepare the compression type for the next compression
- // (After us, the Huffmann compression will be called)
- if(0 < nCmpLevel && nCmpLevel <= 2)
- {
- nCmpLevel = 4;
- *pCmpType = 6;
- }
- else if(nCmpLevel == 3)
- {
- nCmpLevel = 6;
- *pCmpType = 8;
- }
- else
- {
- nCmpLevel = 5;
- *pCmpType = 7;
- }
- *pdwOutLength = CompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (short *)pbInBuffer, dwInLength, 2, nCmpLevel);
- return 0;
-}
-
-int Decompress_wave_stereo(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- *pdwOutLength = DecompressWave((unsigned char *)pbOutBuffer, *pdwOutLength, (unsigned char *)pbInBuffer, dwInLength, 2);
- return 1;
-}
-
-/*****************************************************************************/
-/* */
-/* The "01" (de)compression is the Huffman (de)compression */
-/* */
-/*****************************************************************************/
-
-// 1500F4C0
-int Compress_huff(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int /* nCmpLevel */)
-{
- THuffmannTree ht; // Huffmann tree for compression
- TOutputStream os; // Output stream
-
- // Initialize output stream
- os.pbOutBuffer = (unsigned char *)pbOutBuffer;
- os.dwOutSize = *pdwOutLength;
- os.pbOutPos = (unsigned char *)pbOutBuffer;
- os.dwBitBuff = 0;
- os.nBits = 0;
-
- // Initialize the Huffmann tree for compression
- ht.InitTree(true);
-
- *pdwOutLength = ht.DoCompression(&os, (unsigned char *)pbInBuffer, dwInLength, *pCmpType);
-
- // The following code is not necessary to run, because it has no
- // effect on the output data. It only clears the huffmann tree, but when
- // the tree is on the stack, who cares ?
-// ht.UninitTree();
- return 0;
-}
-
-// 1500F5F0
-int Decompress_huff(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int /* dwInLength */)
-{
- THuffmannTree ht;
- TInputStream is;
-
- // Initialize input stream
-// is.pbInBuffer = (unsigned char *)pbInBuffer;
- is.dwBitBuff = BSWAP_INT32_UNSIGNED(*(unsigned long *)pbInBuffer);
- pbInBuffer += sizeof(unsigned long);
- is.pbInBuffer = (unsigned char *)pbInBuffer;
- is.nBits = 32;
-
- // Initialize the Huffmann tree for compression
- ht.InitTree(false);
- *pdwOutLength = ht.DoDecompression((unsigned char *)pbOutBuffer, *pdwOutLength, &is);
-
- // The following code is not necessary to run, because it has no
- // effect on the output data. It only clears the huffmann tree, but when
- // the tree is on the stack, who cares ?
-// ht.UninitTree();
- return 0;
-}
-
-/*****************************************************************************/
-/* */
-/* The "02" (de)compression is the ZLIB (de)compression */
-/* */
-/*****************************************************************************/
-
-int Compress_zlib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * /* pCmpType */, int /* nCmpLevel */)
-{
- z_stream z; // Stream information for zlib
- int nResult;
-
- // Fill the stream structure for zlib
- z.next_in = (Bytef *)pbInBuffer;
- z.avail_in = (uInt)dwInLength;
- z.total_in = dwInLength;
- z.next_out = (Bytef *)pbOutBuffer;
- z.avail_out = *pdwOutLength;
- z.total_out = 0;
- z.zalloc = NULL;
- z.zfree = NULL;
-
- // Initialize the compression structure. Storm.dll uses zlib version 1.1.3
- *pdwOutLength = 0;
- if((nResult = deflateInit(&z, Z_DEFAULT_COMPRESSION)) == 0)
- {
- // Call zlib to compress the data
- nResult = deflate(&z, Z_FINISH);
-
- if(nResult == Z_OK || nResult == Z_STREAM_END)
- *pdwOutLength = z.total_out;
-
- deflateEnd(&z);
- }
- return nResult;
-}
-
-int Decompress_zlib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- z_stream z; // Stream information for zlib
- int nResult;
-
- // Fill the stream structure for zlib
- z.next_in = (Bytef *)pbInBuffer;
- z.avail_in = (uInt)dwInLength;
- z.total_in = dwInLength;
- z.next_out = (Bytef *)pbOutBuffer;
- z.avail_out = *pdwOutLength;
- z.total_out = 0;
- z.zalloc = NULL;
- z.zfree = NULL;
-
- // Initialize the decompression structure. Storm.dll uses zlib version 1.1.3
- if((nResult = inflateInit(&z)) == 0)
- {
- // Call zlib to decompress the data
- nResult = inflate(&z, Z_FINISH);
- *pdwOutLength = z.total_out;
- inflateEnd(&z);
- }
- return nResult;
-}
-
-/*****************************************************************************/
-/* */
-/* The "08" (de)compression is the Pkware DCL (de)compression */
-/* */
-/*****************************************************************************/
-
-int Compress_pklib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int /* nCmpLevel */)
-{
- TDataInfo Info; // Data information
- char * work_buf = ALLOCMEM(char, CMP_BUFFER_SIZE);// Pklib's work buffer
- unsigned int dict_size; // Dictionary size
- unsigned int ctype; // Compression type
-
- // Fill data information structure
- Info.pInBuff = pbInBuffer;
- Info.nInPos = 0;
- Info.nInBytes = dwInLength;
- Info.pOutBuff = pbOutBuffer;
- Info.nOutPos = 0;
- Info.nMaxOut = *pdwOutLength;
-
- // Set the compression type and dictionary size
- ctype = (*pCmpType == 2) ? CMP_ASCII : CMP_BINARY;
- if (dwInLength < 0x600)
- dict_size = 0x400;
- else if(0x600 <= dwInLength && dwInLength < 0xC00)
- dict_size = 0x800;
- else
- dict_size = 0x1000;
-
- // Do the compression
- implode(ReadInputData, WriteOutputData, work_buf, &Info, &ctype, &dict_size);
- *pdwOutLength = Info.nOutPos;
- FREEMEM(work_buf);
- return 0;
-}
-
-int Decompress_pklib(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- TDataInfo Info; // Data information
- char * work_buf = ALLOCMEM(char, EXP_BUFFER_SIZE);// Pklib's work buffer
-
- // Fill data information structure
- Info.pInBuff = pbInBuffer;
- Info.nInPos = 0;
- Info.nInBytes = dwInLength;
- Info.pOutBuff = pbOutBuffer;
- Info.nOutPos = 0;
- Info.nMaxOut = *pdwOutLength;
-
- // Do the decompression
- explode(ReadInputData, WriteOutputData, work_buf, &Info);
-
- // Fix: If PKLIB is unable to decompress the data, they are uncompressed
- if(Info.nOutPos == 0)
- {
- Info.nOutPos = min(*pdwOutLength, dwInLength);
- memcpy(pbOutBuffer, pbInBuffer, Info.nOutPos);
- }
-
- *pdwOutLength = Info.nOutPos;
- FREEMEM(work_buf);
- return 0;
-}
-
-/*****************************************************************************/
-/* */
-/* The "10" (de)compression is the Bzip2 (de)compression */
-/* */
-/*****************************************************************************/
-
-int Compress_bzip2(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int * pCmpType, int nCmpLevel)
-{
- bz_stream strm;
- int blockSize100k;
- int workFactor = 30;
-
- // Keep compiler happy
- nCmpLevel = nCmpLevel;
-
- // Initialize the BZLIB compression
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
-
- // Adjust the block size
- blockSize100k = *pCmpType;
- if(blockSize100k < 1 || blockSize100k > 9)
- blockSize100k = 9;
-
- // Blizzard uses 9 as blockSize100k, (0 as workFactor)
- if(BZ2_bzCompressInit(&strm, blockSize100k, 0, workFactor) == 0)
- {
- strm.next_in = pbInBuffer;
- strm.avail_in = dwInLength;
- strm.next_out = pbOutBuffer;
- strm.avail_out = *pdwOutLength;
-
- // Perform the compression
- while(BZ2_bzCompress(&strm, (strm.avail_in != 0) ? BZ_RUN : BZ_FINISH) != BZ_STREAM_END);
-
- // Put the stream into idle state
- BZ2_bzCompressEnd(&strm);
- *pdwOutLength = strm.total_out_lo32;
- }
- else
- {
- *pdwOutLength = 0;
- }
-
- return 0;
-}
-
-int Decompress_bzip2(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- bz_stream strm;
-
- // Initialize the BZLIB decompression
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- if(BZ2_bzDecompressInit(&strm, 0, 0) == 0)
- {
- strm.next_in = pbInBuffer;
- strm.avail_in = dwInLength;
- strm.next_out = pbOutBuffer;
- strm.avail_out = *pdwOutLength;
-
- // Perform the decompression
- while(BZ2_bzDecompress(&strm) != BZ_STREAM_END);
-
- // Put the stream into idle state
- BZ2_bzDecompressEnd(&strm);
- *pdwOutLength = strm.total_out_lo32;
- }
- else
- {
- // Set zero output length
- *pdwOutLength = 0;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-/* */
-/* SCompCompress */
-/* */
-/*****************************************************************************/
-
-// This table contains compress functions which can be applied to
-// uncompressed blocks. Each bit set means the corresponding
-// compression method/function must be applied.
-//
-// WAVes compression Data compression
-// ------------------ -------------------
-// 1st block - 0x08 0x08 (D, HF, W2, SC, D2)
-// Rest blocks - 0x81 0x02 (W3)
-
-static TCompressTable cmp_table[] =
-{
- {MPQ_COMPRESSION_WAVE_MONO, Compress_wave_mono}, // IMA ADPCM mono compression
- {MPQ_COMPRESSION_WAVE_STEREO, Compress_wave_stereo}, // IMA ADPCM stereo compression
- {MPQ_COMPRESSION_HUFFMANN, Compress_huff}, // Huffmann compression
- {MPQ_COMPRESSION_ZLIB, Compress_zlib}, // Compression with the "zlib" library
- {MPQ_COMPRESSION_PKWARE, Compress_pklib}, // Compression with Pkware DCL
- {MPQ_COMPRESSION_BZIP2, Compress_bzip2} // Compression Bzip2 library
-};
-
-int WINAPI SCompCompress(char * pbCompressed, int * pdwOutLength, char * pbUncompressed, int dwInLength,
- int uCompressions, int nCmpType, int nCmpLevel)
-{
- char * pbTempBuff = NULL; // Temporary storage for decompressed data
- char * pbOutput = pbCompressed; // Current output buffer
- char * pbInput; // Current input buffer
- int uCompressions2;
- int dwCompressCount = 0;
- int dwDoneCount = 0;
- int dwOutSize = 0;
- int dwInSize = dwInLength;
- int dwEntries = (sizeof(cmp_table) / sizeof(TCompressTable));
- int nResult = 1;
- int i;
-
- // Check for valid parameters
- if(!pdwOutLength || *pdwOutLength < dwInLength || !pbCompressed || !pbUncompressed)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- // Count the compressions
- for(i = 0, uCompressions2 = uCompressions; i < dwEntries; i++)
- {
- if(uCompressions & cmp_table[i].dwMask)
- dwCompressCount++;
-
- uCompressions2 &= ~cmp_table[i].dwMask;
- }
-
- // If a compression remains, do nothing
- if(uCompressions2 != 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- // If more that one compression, allocate intermediate buffer
- if(dwCompressCount >= 2)
- pbTempBuff = ALLOCMEM(char, *pdwOutLength + 1);
-
- // Perform the compressions
- pbInput = pbUncompressed;
- dwInSize = dwInLength;
- for(i = 0, uCompressions2 = uCompressions; i < dwEntries; i++)
- {
- if(uCompressions2 & cmp_table[i].dwMask)
- {
- // Set the right output buffer
- dwCompressCount--;
- pbOutput = (dwCompressCount & 1) ? pbTempBuff : pbCompressed;
-
- // Perform the partial compression
- dwOutSize = *pdwOutLength - 1;
-
- cmp_table[i].Compress(pbOutput + 1, &dwOutSize, pbInput, dwInSize, &nCmpType, nCmpLevel);
- if(dwOutSize == 0)
- {
- SetLastError(ERROR_GEN_FAILURE);
- *pdwOutLength = 0;
- nResult = 0;
- break;
- }
-
- // If the compression failed, copy the block instead
- if(dwOutSize >= dwInSize - 1)
- {
- if(dwDoneCount > 0)
- pbOutput++;
-
- memcpy(pbOutput, pbInput, dwInSize);
- pbInput = pbOutput;
- uCompressions &= ~cmp_table[i].dwMask;
- dwOutSize = dwInSize;
- }
- else
- {
- pbInput = pbOutput + 1;
- dwInSize = dwOutSize;
- dwDoneCount++;
- }
- }
- }
-
- // Copy the compressed data to the correct output buffer
- if(nResult != 0)
- {
- if(uCompressions && (dwInSize + 1) < *pdwOutLength)
- {
- if(pbOutput != pbCompressed && pbOutput != pbCompressed + 1)
- memcpy(pbCompressed, pbOutput, dwInSize);
- *pbCompressed = (char)uCompressions;
- *pdwOutLength = dwInSize + 1;
- }
- else
- {
- memmove(pbCompressed, pbUncompressed, dwInSize);
- *pdwOutLength = dwInSize;
- }
- }
-
- // Cleanup and return
- if(pbTempBuff != NULL)
- FREEMEM(pbTempBuff);
- return nResult;
-}
-
-/*****************************************************************************/
-/* */
-/* SCompDecompress */
-/* */
-/*****************************************************************************/
-
-// This table contains decompress functions which can be applied to
-// uncompressed blocks. The compression mask is stored in the first byte
-// of compressed block
-static TDecompressTable dcmp_table[] =
-{
- {MPQ_COMPRESSION_BZIP2, Decompress_bzip2}, // Decompression with Bzip2 library
- {MPQ_COMPRESSION_PKWARE, Decompress_pklib}, // Decompression with Pkware Data Compression Library
- {MPQ_COMPRESSION_ZLIB, Decompress_zlib}, // Decompression with the "zlib" library
- {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression
- {MPQ_COMPRESSION_WAVE_STEREO, Decompress_wave_stereo}, // IMA ADPCM stereo decompression
- {MPQ_COMPRESSION_WAVE_MONO, Decompress_wave_mono} // IMA ADPCM mono decompression
-};
-
-int WINAPI SCompDecompress(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
-{
- char * pbTempBuff = NULL; // Temporary storage for decompressed data
- char * pbWorkBuff = NULL; // Where to store decompressed data
- int dwOutLength = *pdwOutLength; // For storage number of output bytes
- unsigned fDecompressions1; // Decompressions applied to the block
- unsigned fDecompressions2; // Just another copy of decompressions applied to the block
- int dwCount = 0; // Counter for every use
- int dwEntries = (sizeof(dcmp_table) / sizeof(TDecompressTable));
- int nResult = 1;
- int i;
-
- // If the input length is the same as output, do nothing.
- if(dwInLength == dwOutLength)
- {
- if(pbInBuffer == pbOutBuffer)
- return 1;
-
- memcpy(pbOutBuffer, pbInBuffer, dwInLength);
- *pdwOutLength = dwInLength;
- return 1;
- }
-
- // Get applied compression types and decrement data length
- fDecompressions1 = fDecompressions2 = (unsigned char)*pbInBuffer++;
- dwInLength--;
-
- // Search decompression table type and get all types of compression
- for(i = 0; i < dwEntries; i++)
- {
- // We have to apply this decompression ?
- if(fDecompressions1 & dcmp_table[i].dwMask)
- dwCount++;
-
- // Clear this flag from temporary variable.
- fDecompressions2 &= ~dcmp_table[i].dwMask;
- }
-
- // Check if there is some method unhandled
- // (E.g. compressed by future versions)
- if(fDecompressions2 != 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- // If there is more than only one compression, we have to allocate extra buffer
- if(dwCount >= 2)
- pbTempBuff = ALLOCMEM(char, dwOutLength);
-
- // Apply all decompressions
- for(i = 0, dwCount = 0; i < dwEntries; i++)
- {
- // If not used this kind of compression, skip the loop
- if(fDecompressions1 & dcmp_table[i].dwMask)
- {
- // If odd case, use target buffer for output, otherwise use allocated tempbuffer
- pbWorkBuff = (dwCount++ & 1) ? pbTempBuff : pbOutBuffer;
- dwOutLength = *pdwOutLength;
-
- // Decompress buffer using corresponding function
- dcmp_table[i].Decompress(pbWorkBuff, &dwOutLength, pbInBuffer, dwInLength);
- if(dwOutLength == 0)
- {
- SetLastError(ERROR_GEN_FAILURE);
- nResult = 0;
- break;
- }
-
- // Move output length to src length for next compression
- dwInLength = dwOutLength;
- pbInBuffer = pbWorkBuff;
- }
- }
-
- // If output buffer is not the same like target buffer, we have to copy data
- if(nResult != 0)
- {
- if(pbWorkBuff != pbOutBuffer)
- memcpy(pbOutBuffer, pbInBuffer, dwOutLength);
-
- }
-
- // Delete temporary buffer, if necessary
- if(pbTempBuff != NULL)
- FREEMEM(pbTempBuff);
-
- *pdwOutLength = dwOutLength;
- return nResult;
-}
-
-/*****************************************************************************/
-/* */
-/* SCompSetDataCompression */
-/* */
-/*****************************************************************************/
-
-int WINAPI SCompSetDataCompression(int nDataCompression)
-{
- int nValidMask = (MPQ_COMPRESSION_ZLIB | MPQ_COMPRESSION_PKWARE | MPQ_COMPRESSION_BZIP2);
-
- if((nDataCompression & nValidMask) != nDataCompression)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- SetDataCompression(nDataCompression);
- return TRUE;
-}
-
-
diff --git a/contrib/vmap_extractor_v2/stormlib/SFileCompactArchive.cpp b/contrib/vmap_extractor_v2/stormlib/SFileCompactArchive.cpp
deleted file mode 100644
index 9510b15ae1f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SFileCompactArchive.cpp
+++ /dev/null
@@ -1,691 +0,0 @@
-/*****************************************************************************/
-/* SFileCompactArchive.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Archive compacting function */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 14.04.03 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-/*****************************************************************************/
-/* Local structures */
-/*****************************************************************************/
-
-/*****************************************************************************/
-/* Local variables */
-/*****************************************************************************/
-
-static COMPACTCB CompactCB = NULL;
-static void * lpUserData = NULL;
-
-/*****************************************************************************/
-/* Local functions */
-/*****************************************************************************/
-
-// Creates a copy of hash table
-static TMPQHash * CopyHashTable(TMPQArchive * ha)
-{
- TMPQHash * pHashTableCopy = ALLOCMEM(TMPQHash, ha->pHeader->dwHashTableSize);
-
- if(pHashTableCopy != NULL)
- memcpy(pHashTableCopy, ha->pHashTable, sizeof(TMPQHash) * ha->pHeader->dwHashTableSize);
-
- return pHashTableCopy;
-}
-
-// TODO: Test for archives > 4GB
-static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, DWORD * pFileSeeds)
-{
- TMPQHash * pHashTableCopy = NULL; // Copy of the hash table
- TMPQHash * pHash;
- TMPQHash * pHashEnd = NULL; // End of the hash table
- DWORD dwFileCount = 0;
- int nError = ERROR_SUCCESS;
-
- // First of all, create a copy of hash table
- if(nError == ERROR_SUCCESS)
- {
- if((pHashTableCopy = CopyHashTable(ha)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- pHashEnd = pHashTableCopy + ha->pHeader->dwHashTableSize;
-
- // Notify the user
- if(CompactCB != NULL)
- CompactCB(lpUserData, CCB_CHECKING_FILES, 0, ha->pHeader->dwBlockTableSize);
- }
-
- // Now check all the files from the filelist
- if(nError == ERROR_SUCCESS)
- {
- SFILE_FIND_DATA wf;
- HANDLE hFind = SFileFindFirstFile((HANDLE)ha, "*", &wf, szListFile);
- BOOL bResult = TRUE;
-
- // Do while some files have been found
- while(hFind != NULL && bResult)
- {
- TMPQHash * pHash = GetHashEntry(ha, wf.cFileName);
-
- // If the hash table entry has been found, find it's position
- // in the hash table copy
- if(pHash != NULL)
- {
- pHash = pHashTableCopy + (pHash - ha->pHashTable);
- if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1)
- {
- TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex;
- DWORD dwSeed = 0;
-
- // Resolve the file seed. Use plain file name for it
- if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- char * szFileName = strrchr(wf.cFileName, '\\');
-
- if(szFileName == NULL)
- szFileName = wf.cFileName;
- else
- szFileName++;
-
- dwSeed = DecryptFileSeed(szFileName);
- if(pBlock->dwFlags & MPQ_FILE_FIXSEED)
- dwSeed = (dwSeed + pBlock->dwFilePos) ^ pBlock->dwFSize;
- }
- pFileSeeds[pHash->dwBlockIndex] = dwSeed;
-
- pHash->dwName1 = 0xFFFFFFFF;
- pHash->dwName2 = 0xFFFFFFFF;
- pHash->lcLocale = 0xFFFF;
- pHash->wPlatform = 0xFFFF;
- pHash->dwBlockIndex = 0xFFFFFFFF;
- }
- }
- // Notify the user
- if(CompactCB != NULL)
- CompactCB(lpUserData, CCB_CHECKING_FILES, ++dwFileCount, ha->pHeader->dwBlockTableSize);
-
- // Find the next file in the archive
- bResult = SFileFindNextFile(hFind, &wf);
- }
-
- if(hFind != NULL)
- SFileFindClose(hFind);
- }
-
- // When the filelist checking is complete, parse the hash table copy and find the
- if(nError == ERROR_SUCCESS)
- {
- // Notify the user about checking hash table
- dwFileCount = 0;
- if(CompactCB != NULL)
- CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, dwFileCount, ha->pHeader->dwBlockTableSize);
-
- for(pHash = pHashTableCopy; pHash < pHashEnd; pHash++)
- {
- // If there is an unresolved entry, try to detect its seed. If it fails,
- // we cannot complete the work
- if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1)
- {
- HANDLE hFile = NULL;
- DWORD dwFlags = 0;
- DWORD dwSeed = 0;
-
- if(SFileOpenFileEx((HANDLE)ha, (char *)(DWORD_PTR)pHash->dwBlockIndex, 0, &hFile))
- {
- TMPQFile * hf = (TMPQFile *)hFile;
- dwFlags = hf->pBlock->dwFlags;
- dwSeed = hf->dwSeed1;
- SFileCloseFile(hFile);
- }
-
- // If the file is encrypted, we have to check
- // If we can apply the file decryption seed
- if(dwFlags & MPQ_FILE_ENCRYPTED && dwSeed == 0)
- {
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
-
- // Remember the seed
- pFileSeeds[pHash->dwBlockIndex] = dwSeed;
-
- // Notify the user
- if(CompactCB != NULL)
- CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, ++dwFileCount, ha->pHeader->dwBlockTableSize);
- }
- }
- }
-
- // Delete the copy of hash table
- if(pHashTableCopy != NULL)
- FREEMEM(pHashTableCopy);
- return nError;
-}
-
-// Copies all file blocks into another archive.
-// TODO: Test for archives > 4GB
-static int CopyMpqFileBlocks(
- HANDLE hFile,
- TMPQArchive * ha,
- TMPQBlockEx * pBlockEx,
- TMPQBlock * pBlock,
- DWORD dwSeed)
-{
- LARGE_INTEGER FilePos = {0};
- DWORD * pdwBlockPos2 = NULL; // File block positions to be written to target file
- DWORD * pdwBlockPos = NULL; // File block positions (unencrypted)
- BYTE * pbBlock = NULL; // Buffer for the file block
- DWORD dwTransferred; // Number of bytes transferred
- DWORD dwCSize = 0; // Compressed file size
- DWORD dwBytes = 0; // Number of bytes
- DWORD dwSeed1 = 0; // File seed used for decryption
- DWORD dwSeed2 = 0; // File seed used for encryption
- DWORD nBlocks = 0; // Number of file blocks
- DWORD nBlock = 0; // Currently processed file block
- int nError = ERROR_SUCCESS;
-
- // When file length is zero, do nothing
- if(pBlock->dwFSize == 0)
- return ERROR_SUCCESS;
-
- // Calculate number of blocks in the file
- if(nError == ERROR_SUCCESS)
- {
- nBlocks = pBlock->dwFSize / ha->dwBlockSize;
- if(pBlock->dwFSize % ha->dwBlockSize)
- nBlocks++;
- pbBlock = ALLOCMEM(BYTE, ha->dwBlockSize);
- if(pbBlock == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Set the position to the begin of the file within archive
- if(nError == ERROR_SUCCESS)
- {
- FilePos.HighPart = pBlockEx->wFilePosHigh;
- FilePos.LowPart = pBlock->dwFilePos;
- FilePos.QuadPart += ha->MpqPos.QuadPart;
- if(SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN) != FilePos.LowPart)
- nError = GetLastError();
- }
-
- // Remember the position in the destination file
- if(nError == ERROR_SUCCESS)
- {
- FilePos.HighPart = 0;
- FilePos.LowPart = SetFilePointer(hFile, 0, &FilePos.HighPart, FILE_CURRENT);
- }
-
- // Resolve decryption seeds. The 'dwSeed' parameter is the decryption
- // seed for the file.
- if(nError == ERROR_SUCCESS && (pBlock->dwFlags & MPQ_FILE_ENCRYPTED))
- {
- dwSeed1 = dwSeed;
- if(pBlock->dwFlags & MPQ_FILE_FIXSEED)
- dwSeed = (dwSeed1 ^ pBlock->dwFSize) - pBlock->dwFilePos;
-
- dwSeed2 = dwSeed;
- if(pBlock->dwFlags & MPQ_FILE_FIXSEED)
- dwSeed2 = (dwSeed + (DWORD)(FilePos.QuadPart - ha->MpqPos.QuadPart)) ^ pBlock->dwFSize;
- }
-
- // Load the file positions from the archive and save it to the target file
- // (only if the file is compressed)
- if(pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- {
- // Allocate buffers
- if(nError == ERROR_SUCCESS)
- {
- pdwBlockPos = ALLOCMEM(DWORD, nBlocks + 2);
- pdwBlockPos2 = ALLOCMEM(DWORD, nBlocks + 2);
-
- if(pdwBlockPos == NULL || pdwBlockPos2 == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Load the block positions
- if(nError == ERROR_SUCCESS)
- {
- dwBytes = (nBlocks + 1) * sizeof(DWORD);
- if(pBlock->dwFlags & MPQ_FILE_HAS_EXTRA)
- dwBytes += sizeof(DWORD);
-
- ReadFile(ha->hFile, pdwBlockPos, dwBytes, &dwTransferred, NULL);
- if(dwTransferred != dwBytes)
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Re-encrypt the block table positions
- if(nError == ERROR_SUCCESS)
- {
- BSWAP_ARRAY32_UNSIGNED(pdwBlockPos, dwBytes / sizeof(DWORD));
- if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- DecryptMPQBlock(pdwBlockPos, dwBytes, dwSeed1 - 1);
- if(pdwBlockPos[0] != dwBytes)
- nError = ERROR_FILE_CORRUPT;
-
- memcpy(pdwBlockPos2, pdwBlockPos, dwBytes);
- EncryptMPQBlock(pdwBlockPos2, dwBytes, dwSeed2 - 1);
- }
- else
- {
- memcpy(pdwBlockPos2, pdwBlockPos, dwBytes);
- }
- BSWAP_ARRAY32_UNSIGNED(pdwBlockPos2, dwBytes / sizeof(DWORD));
- }
-
- // Write to the target file
- if(nError == ERROR_SUCCESS)
- {
- WriteFile(hFile, pdwBlockPos2, dwBytes, &dwTransferred, NULL);
- dwCSize += dwTransferred;
- if(dwTransferred != dwBytes)
- nError = ERROR_DISK_FULL;
- }
- }
-
- // Now we have to copy all file block. We will do it without
- // recompression, because re-compression is not necessary in this case
- if(nError == ERROR_SUCCESS)
- {
- for(nBlock = 0; nBlock < nBlocks; nBlock++)
- {
- // Fix: The last block must not be exactly the size of one block.
- dwBytes = ha->dwBlockSize;
- if(nBlock == nBlocks - 1)
- {
- dwBytes = pBlock->dwFSize - (ha->dwBlockSize * (nBlocks - 1));
- }
-
- if(pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- dwBytes = pdwBlockPos[nBlock+1] - pdwBlockPos[nBlock];
-
- // Read the file block
- ReadFile(ha->hFile, pbBlock, dwBytes, &dwTransferred, NULL);
- if(dwTransferred != dwBytes)
- {
- nError = ERROR_FILE_CORRUPT;
- break;
- }
-
- // If necessary, re-encrypt the block
- // Note: Recompression is not necessary here. Unlike encryption,
- // the compression does not depend on the position of the file in MPQ.
- if((pBlock->dwFlags & MPQ_FILE_ENCRYPTED) && dwSeed1 != dwSeed2)
- {
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBlock, dwBytes/sizeof(DWORD));
- DecryptMPQBlock((DWORD *)pbBlock, dwBytes, dwSeed1 + nBlock);
- EncryptMPQBlock((DWORD *)pbBlock, dwBytes, dwSeed2 + nBlock);
- BSWAP_ARRAY32_UNSIGNED((DWORD *)pbBlock, dwBytes/sizeof(DWORD));
- }
-
- // Now write the block back to the file
- WriteFile(hFile, pbBlock, dwBytes, &dwTransferred, NULL);
- dwCSize += dwTransferred;
- if(dwTransferred != dwBytes)
- {
- nError = ERROR_DISK_FULL;
- break;
- }
- }
- }
-
- // Copy the file extras, if any
- // These extras does not seem to be encrypted, and their purpose is unknown
- if(nError == ERROR_SUCCESS && (pBlock->dwFlags & MPQ_FILE_HAS_EXTRA))
- {
- dwBytes = pdwBlockPos[nBlocks + 1] - pdwBlockPos[nBlocks];
- if(dwBytes != 0)
- {
- ReadFile(ha->hFile, pbBlock, dwBytes, &dwTransferred, NULL);
- if(dwTransferred == dwBytes)
- {
- WriteFile(hFile, pbBlock, dwBytes, &dwTransferred, NULL);
- dwCSize += dwTransferred;
- if(dwTransferred != dwBytes)
- nError = ERROR_DISK_FULL;
- }
- else
- {
- nError = ERROR_FILE_CORRUPT;
- }
- }
- }
-
- // Update file position in the block table
- if(nError == ERROR_SUCCESS)
- {
- // At this point, number of bytes written should be exactly
- // the same like the compressed file size. If it isn't, there's something wrong
- // (maybe new archive version ?)
- assert(dwCSize == pBlock->dwCSize);
-
- // Update file pos in the block table
- FilePos.QuadPart -= ha->MpqPos.QuadPart;
- pBlockEx->wFilePosHigh = (USHORT)FilePos.HighPart;
- pBlock->dwFilePos = FilePos.LowPart;
- }
-
- // Cleanup and return
- if(pdwBlockPos2 != NULL)
- FREEMEM(pdwBlockPos2);
- if(pdwBlockPos != NULL)
- FREEMEM(pdwBlockPos);
- if(pbBlock != NULL)
- FREEMEM(pbBlock);
- return nError;
-}
-
-
-static int CopyNonMpqData(
- HANDLE hSrcFile,
- HANDLE hTrgFile,
- LARGE_INTEGER & DataSizeToCopy)
-{
- LARGE_INTEGER DataSize = DataSizeToCopy;
- DWORD dwTransferred;
- DWORD dwToRead;
- char DataBuffer[0x1000];
- int nError = ERROR_SUCCESS;
-
- while(DataSize.QuadPart > 0)
- {
- // Get the proper size of data
- dwToRead = sizeof(DataBuffer);
- if(DataSize.HighPart == 0 && DataSize.LowPart < dwToRead)
- dwToRead = DataSize.LowPart;
-
- // Read the source file
- ReadFile(hSrcFile, DataBuffer, dwToRead, &dwTransferred, NULL);
- if(dwTransferred != dwToRead)
- {
- nError = ERROR_CAN_NOT_COMPLETE;
- break;
- }
-
- // Write to the target file
- WriteFile(hTrgFile, DataBuffer, dwToRead, &dwTransferred, NULL);
- if(dwTransferred != dwToRead)
- {
- nError = ERROR_DISK_FULL;
- break;
- }
-
- // Decrement the number of data to be copied
- DataSize.QuadPart -= dwTransferred;
- }
-
- return ERROR_SUCCESS;
-}
-
-// TODO: Test for archives > 4GB
-static int CopyMpqFiles(HANDLE hFile, TMPQArchive * ha, DWORD * pFileSeeds)
-{
- TMPQBlockEx * pBlockEx;
- TMPQBlock * pBlock;
- DWORD dwSeed1;
- DWORD dwIndex;
- int nError = ERROR_SUCCESS;
-
- // Walk through all files and write them to the destination MPQ archive
- for(dwIndex = 0; dwIndex < ha->pHeader->dwBlockTableSize; dwIndex++)
- {
- pBlockEx = ha->pExtBlockTable + dwIndex;
- pBlock = ha->pBlockTable + dwIndex;
- dwSeed1 = pFileSeeds[dwIndex];
-
- // Notify the caller about work
- if(CompactCB != NULL)
- CompactCB(lpUserData, CCB_COMPACTING_FILES, dwIndex, ha->pHeader->dwBlockTableSize);
-
-// if(dwIndex == 0x1B9)
-// DebugBreak();
-
- // Copy all the file blocks
- // Debug: Break at (dwIndex == 5973)
- if(pBlock->dwFlags & MPQ_FILE_EXISTS)
- {
- nError = CopyMpqFileBlocks(hFile, ha, pBlockEx, pBlock, dwSeed1);
- if(nError != ERROR_SUCCESS)
- break;
- }
- }
-
- // Cleanup and exit
- return nError;
-}
-
-
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
-
-BOOL WINAPI SFileSetCompactCallback(HANDLE /* hMPQ */, COMPACTCB aCompactCB, void * lpData)
-{
- CompactCB = aCompactCB;
- lpUserData = lpData;
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// Archive compacting (incomplete)
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileCompactArchive(HANDLE hMPQ, const char * szListFile, BOOL /* bReserved */)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- HANDLE hFile = INVALID_HANDLE_VALUE;
- DWORD * pFileSeeds = NULL;
- char szTempFile[MAX_PATH] = "";
- char * szTemp = NULL;
- DWORD dwTransferred;
- int nError = ERROR_SUCCESS;
-
- // Test the valid parameters
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_PARAMETER;
-
- // Create the table with file seeds
- if(nError == ERROR_SUCCESS)
- {
- if((pFileSeeds = ALLOCMEM(DWORD, ha->pHeader->dwBlockTableSize)) != NULL)
- memset(pFileSeeds, 0, sizeof(DWORD) * ha->pHeader->dwBlockTableSize);
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // First of all, we have to check of we are able to decrypt all files.
- // If not, sorry, but the archive cannot be compacted.
- if(nError == ERROR_SUCCESS)
- nError = CheckIfAllFilesKnown(ha, szListFile, pFileSeeds);
-
- // Get the temporary file name and create it
- if(nError == ERROR_SUCCESS)
- {
- if(CompactCB != NULL)
- CompactCB(lpUserData, CCB_COPYING_NON_MPQ_DATA, 0, 0);
-
- strcpy(szTempFile, ha->szFileName);
- if((szTemp = strrchr(szTempFile, '.')) != NULL)
- strcpy(szTemp + 1, "mp_");
- else
- strcat(szTempFile, "_");
-
- hFile = CreateFile(szTempFile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- nError = GetLastError();
- }
-
- // Write the data before MPQ header (if any)
- if(nError == ERROR_SUCCESS && ha->MpqPos.QuadPart > 0)
- {
- SetFilePointer(ha->hFile, 0, NULL, FILE_BEGIN);
- if(ha->pShunt != NULL)
- nError = CopyNonMpqData(ha->hFile, hFile, ha->ShuntPos);
- else
- nError = CopyNonMpqData(ha->hFile, hFile, ha->MpqPos);
- }
-
- // Write the MPQ shunt (if any)
- if(nError == ERROR_SUCCESS && ha->pShunt != NULL)
- {
- BSWAP_TMPQSHUNT(ha->pShunt);
- WriteFile(hFile, ha->pShunt, sizeof(TMPQShunt), &dwTransferred, NULL);
- BSWAP_TMPQSHUNT(ha->pShunt);
-
- if(dwTransferred != sizeof(TMPQShunt))
- nError = ERROR_DISK_FULL;
- }
-
- // Write the data between MPQ shunt and the MPQ header (if any)
- if(nError == ERROR_SUCCESS && ha->pShunt != NULL)
- {
- LARGE_INTEGER BytesToCopy;
-
- BytesToCopy.QuadPart = ha->MpqPos.QuadPart - (ha->ShuntPos.QuadPart + sizeof(TMPQShunt));
- nError = CopyNonMpqData(ha->hFile, hFile, BytesToCopy);
- }
-
- // Write the MPQ header
- if(nError == ERROR_SUCCESS)
- {
- BSWAP_TMPQHEADER(ha->pHeader);
- WriteFile(hFile, ha->pHeader, ha->pHeader->dwHeaderSize, &dwTransferred, NULL);
- BSWAP_TMPQHEADER(ha->pHeader);
- if(dwTransferred != ha->pHeader->dwHeaderSize)
- nError = ERROR_DISK_FULL;
- }
-
- // Write the data between the header and between the first file
- // For this, we have to determine where the first file begins
- if(nError == ERROR_SUCCESS)
- {
- LARGE_INTEGER FirstFilePos;
- LARGE_INTEGER TempPos;
- TMPQBlockEx * pBlockEx = ha->pExtBlockTable;
- TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize;
- TMPQBlock * pBlock = ha->pBlockTable;
-
- // Maximum file position
- FirstFilePos.HighPart = 0x7FFFFFFF;
- FirstFilePos.LowPart = 0xFFFFFFFF;
-
- // Find the block with the least position in the MPQ
- while(pBlock < pBlockEnd)
- {
- TempPos.HighPart = pBlockEx->wFilePosHigh;
- TempPos.LowPart = pBlock->dwFilePos;
- if(TempPos.QuadPart < FirstFilePos.QuadPart)
- FirstFilePos = TempPos;
-
- pBlockEx++;
- pBlock++;
- }
-
- // Set the position in the source file right after the file header
- TempPos.QuadPart = ha->MpqPos.QuadPart + ha->pHeader->dwHeaderSize;
- SetFilePointer(ha->hFile, TempPos.LowPart, &TempPos.HighPart, FILE_BEGIN);
-
- // Get the number of bytes to copy
- FirstFilePos.QuadPart -= ha->pHeader->dwHeaderSize;
- nError = CopyNonMpqData(ha->hFile, hFile, FirstFilePos);
- }
-
- // Now write all file blocks.
- if(nError == ERROR_SUCCESS)
- nError = CopyMpqFiles(hFile, ha, pFileSeeds);
-
- // Now we need to update the tables positions
- // (but only if the tables are at the end of the file)
- if(nError == ERROR_SUCCESS)
- {
- LARGE_INTEGER RelativePos;
- LARGE_INTEGER FilePos = {0};
-
- // Set the hash table position
- FilePos.LowPart = SetFilePointer(hFile, 0, &FilePos.HighPart, FILE_CURRENT);
- RelativePos.QuadPart = FilePos.QuadPart - ha->MpqPos.QuadPart;
- ha->pHeader->wHashTablePosHigh = (USHORT)RelativePos.HighPart;
- ha->pHeader->dwHashTablePos = RelativePos.LowPart;
- ha->HashTablePos = FilePos;
-
- // Set the block table position
- RelativePos.QuadPart += ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- FilePos.QuadPart += ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- ha->pHeader->wBlockTablePosHigh = (USHORT)RelativePos.HighPart;
- ha->pHeader->dwBlockTablePos = RelativePos.LowPart;
- ha->BlockTablePos = FilePos;
-
- // Set the extended block table position
- RelativePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- FilePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- if(ha->ExtBlockTablePos.QuadPart != 0)
- {
- ha->pHeader->ExtBlockTablePos = RelativePos;
- ha->ExtBlockTablePos = FilePos;
-
- RelativePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx);
- FilePos.QuadPart += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx);
- }
-
- // Set the archive size
- ha->pHeader->dwArchiveSize = RelativePos.LowPart;
- ha->MpqSize = RelativePos;
- }
-
- // If succeeded, update the tables in the file
- if(nError == ERROR_SUCCESS)
- {
- CloseHandle(ha->hFile);
- ha->FilePointer.QuadPart = 0;
- ha->hFile = hFile;
- hFile = INVALID_HANDLE_VALUE;
- nError = SaveMPQTables(ha);
- }
-
- // If all succeeded, switch the archives
- if(nError == ERROR_SUCCESS)
- {
- if(CompactCB != NULL)
- CompactCB(lpUserData, CCB_CLOSING_ARCHIVE, 0, 0);
-
- if(!DeleteFile(ha->szFileName) || // Delete the old archive
- !CloseHandle(ha->hFile) || // Close the new archive
- !MoveFile(szTempFile, ha->szFileName)) // Rename the temporary archive
- nError = GetLastError();
- }
-
- // Now open the freshly renamed archive file
- if(nError == ERROR_SUCCESS)
- {
- ha->hFile = CreateFile(ha->szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if(ha->hFile == INVALID_HANDLE_VALUE)
- nError = GetLastError();
- }
-
- // Invalidate the positions of the archive
- if(nError == ERROR_SUCCESS)
- {
- ha->FilePointer.QuadPart = 0;
- ha->pLastFile = NULL;
- ha->dwBlockPos = 0;
- ha->dwBuffPos = 0;
- }
-
- // Cleanup and return
- if(hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
- if(pFileSeeds != NULL)
- FREEMEM(pFileSeeds);
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- DeleteFile(szTempFile);
- CompactCB = NULL;
- return (nError == ERROR_SUCCESS);
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/SFileCreateArchiveEx.cpp b/contrib/vmap_extractor_v2/stormlib/SFileCreateArchiveEx.cpp
deleted file mode 100644
index 2410920fc93..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SFileCreateArchiveEx.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/*****************************************************************************/
-/* SFileCreateArchiveEx.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* MPQ Editing functions */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 24.03.03 1.00 Lad Splitted from SFileOpenArchive.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define DEFAULT_BLOCK_SIZE 3 // Default size of the block
-
-//-----------------------------------------------------------------------------
-// Local tables
-
-static DWORD PowersOfTwo[] =
-{
- 0x0000002, 0x0000004, 0x0000008,
- 0x0000010, 0x0000020, 0x0000040, 0x0000080,
- 0x0000100, 0x0000200, 0x0000400, 0x0000800,
- 0x0001000, 0x0002000, 0x0004000, 0x0008000,
- 0x0010000, 0x0020000, 0x0040000, 0x0080000,
- 0x0000000
-};
-
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
-
-//-----------------------------------------------------------------------------
-// Opens or creates a (new) MPQ archive.
-//
-// szMpqName - Name of the archive to be created.
-//
-// dwCreationDisposition:
-//
-// Value Archive exists Archive doesn't exist
-// ---------- --------------------- ---------------------
-// CREATE_NEW Fails Creates new archive
-// CREATE_ALWAYS Overwrites existing Creates new archive
-// OPEN_EXISTING Opens the archive Fails
-// OPEN_ALWAYS Opens the archive Creates new archive
-//
-// The above mentioned values can be combined with the following flags:
-//
-// MPQ_CREATE_ARCHIVE_V1 - Creates MPQ archive version 1
-// MPQ_CREATE_ARCHIVE_V2 - Creates MPQ archive version 2
-//
-// dwHashTableSize - Size of the hash table (only if creating a new archive).
-// Must be between 2^4 (= 16) and 2^18 (= 262 144)
-//
-// phMpq - Receives handle to the archive
-//
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileCreateArchiveEx(const char * szMpqName, DWORD dwCreationDisposition, DWORD dwHashTableSize, HANDLE * phMPQ)
-{
- LARGE_INTEGER MpqPos = {0}; // Position of MPQ header in the file
- TMPQArchive * ha = NULL; // MPQ archive handle
- HANDLE hFile = INVALID_HANDLE_VALUE; // File handle
- DWORD dwTransferred = 0; // Number of bytes written into the archive
- USHORT wFormatVersion;
- BOOL bFileExists = FALSE;
- int nIndex = 0;
- int nError = ERROR_SUCCESS;
-
- // Pre-initialize the result value
- if(phMPQ != NULL)
- *phMPQ = NULL;
-
- // Check the parameters, if they are valid
- if(szMpqName == NULL || *szMpqName == 0 || phMPQ == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- // Check the value of dwCreationDisposition against file existence
- bFileExists = (GetFileAttributes(szMpqName) != 0xFFFFFFFF);
-
- // Extract format version from the "dwCreationDisposition"
- wFormatVersion = (USHORT)(dwCreationDisposition >> 0x10);
- dwCreationDisposition &= 0x0000FFFF;
-
- // If the file exists and open required, do it.
- if(bFileExists && (dwCreationDisposition == OPEN_EXISTING || dwCreationDisposition == OPEN_ALWAYS))
- {
- // Try to open the archive normal way. If it fails, it means that
- // the file exist, but it is not a MPQ archive.
- if(SFileOpenArchiveEx(szMpqName, 0, 0, phMPQ, GENERIC_READ | GENERIC_WRITE))
- return TRUE;
- }
-
- // Two error cases
- if(dwCreationDisposition == CREATE_NEW && bFileExists)
- {
- SetLastError(ERROR_ALREADY_EXISTS);
- return FALSE;
- }
- if(dwCreationDisposition == OPEN_EXISTING && bFileExists == FALSE)
- {
- SetLastError(ERROR_FILE_NOT_FOUND);
- return FALSE;
- }
-
- // At this point, we have to create the archive. If the file exists,
- // we will convert it to MPQ archive.
- // Check the value of hash table size. It has to be a power of two
- // and must be between HASH_TABLE_SIZE_MIN and HASH_TABLE_SIZE_MAX
- if(dwHashTableSize < HASH_TABLE_SIZE_MIN)
- dwHashTableSize = HASH_TABLE_SIZE_MIN;
- if(dwHashTableSize > HASH_TABLE_SIZE_MAX)
- dwHashTableSize = HASH_TABLE_SIZE_MAX;
-
- // Round the hash table size up to the nearest power of two
- for(nIndex = 0; PowersOfTwo[nIndex] != 0; nIndex++)
- {
- if(dwHashTableSize <= PowersOfTwo[nIndex])
- {
- dwHashTableSize = PowersOfTwo[nIndex];
- break;
- }
- }
-
- // Prepare the buffer for decryption engine
- if(nError == ERROR_SUCCESS)
- nError = PrepareStormBuffer();
-
- // Get the position where the MPQ header will begin.
- if(nError == ERROR_SUCCESS)
- {
- hFile = CreateFile(szMpqName,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- dwCreationDisposition,
- 0,
- NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- nError = GetLastError();
- }
-
- // Retrieve the file size and round it up to 0x200 bytes
- if(nError == ERROR_SUCCESS)
- {
- MpqPos.LowPart = GetFileSize(hFile, (LPDWORD)&MpqPos.HighPart);
- MpqPos.QuadPart += 0x1FF;
- MpqPos.LowPart &= 0xFFFFFE00;
-
- if(wFormatVersion == MPQ_FORMAT_VERSION_1 && MpqPos.HighPart != 0)
- nError = ERROR_DISK_FULL;
- if(wFormatVersion == MPQ_FORMAT_VERSION_2 && MpqPos.HighPart > 0x0000FFFF)
- nError = ERROR_DISK_FULL;
- }
-
- // Move to the end of the file (i.e. begin of the MPQ)
- if(nError == ERROR_SUCCESS)
- {
- if(SetFilePointer(hFile, MpqPos.LowPart, &MpqPos.HighPart, FILE_BEGIN) == 0xFFFFFFFF)
- nError = GetLastError();
- }
-
- // Set the new end of the file to the MPQ header position
- if(nError == ERROR_SUCCESS)
- {
- if(!SetEndOfFile(hFile))
- nError = GetLastError();
- }
-
- // Create the archive handle
- if(nError == ERROR_SUCCESS)
- {
- if((ha = ALLOCMEM(TMPQArchive, 1)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Fill the MPQ archive handle structure and create the header,
- // block buffer, hash table and block table
- if(nError == ERROR_SUCCESS)
- {
- memset(ha, 0, sizeof(TMPQArchive));
- strcpy(ha->szFileName, szMpqName);
- ha->hFile = hFile;
- ha->dwBlockSize = 0x200 << DEFAULT_BLOCK_SIZE;
- ha->MpqPos = MpqPos;
- ha->FilePointer = MpqPos;
- ha->pHeader = &ha->Header;
- ha->pHashTable = ALLOCMEM(TMPQHash, dwHashTableSize);
- ha->pBlockTable = ALLOCMEM(TMPQBlock, dwHashTableSize);
- ha->pExtBlockTable = ALLOCMEM(TMPQBlockEx, dwHashTableSize);
- ha->pbBlockBuffer = ALLOCMEM(BYTE, ha->dwBlockSize);
- ha->pListFile = NULL;
- ha->dwFlags |= MPQ_FLAG_CHANGED;
-
- if(!ha->pHashTable || !ha->pBlockTable || !ha->pExtBlockTable || !ha->pbBlockBuffer)
- nError = GetLastError();
- hFile = INVALID_HANDLE_VALUE;
- }
-
- // Fill the MPQ header and all buffers
- if(nError == ERROR_SUCCESS)
- {
- LARGE_INTEGER TempPos;
- TMPQHeader2 * pHeader = ha->pHeader;
- DWORD dwHeaderSize = (wFormatVersion == MPQ_FORMAT_VERSION_2) ? sizeof(TMPQHeader2) : sizeof(TMPQHeader);
-
- memset(pHeader, 0, sizeof(TMPQHeader2));
- pHeader->dwID = ID_MPQ;
- pHeader->dwHeaderSize = dwHeaderSize;
- pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
- pHeader->wFormatVersion = wFormatVersion;
- pHeader->wBlockSize = 3; // 0x1000 bytes per block
- pHeader->dwHashTableSize = dwHashTableSize;
-
- // Set proper hash table positions
- ha->HashTablePos.QuadPart = ha->MpqPos.QuadPart + pHeader->dwHeaderSize;
- ha->pHeader->dwHashTablePos = pHeader->dwHeaderSize;
- ha->pHeader->wHashTablePosHigh = 0;
-
- // Set proper block table positions
- ha->BlockTablePos.QuadPart = ha->HashTablePos.QuadPart +
- (ha->pHeader->dwHashTableSize * sizeof(TMPQHash));
- TempPos.QuadPart = ha->BlockTablePos.QuadPart - ha->MpqPos.QuadPart;
- ha->pHeader->dwBlockTablePos = TempPos.LowPart;
- ha->pHeader->wBlockTablePosHigh = (USHORT)TempPos.HighPart;
-
- // For now, we set extended block table positioon top zero unless we add enough
- // files to cause the archive size exceed 4 GB
- ha->ExtBlockTablePos.QuadPart = 0;
-
- // Clear all tables
- memset(ha->pBlockTable, 0, sizeof(TMPQBlock) * dwHashTableSize);
- memset(ha->pExtBlockTable, 0, sizeof(TMPQBlockEx) * dwHashTableSize);
- memset(ha->pHashTable, 0xFF, sizeof(TMPQHash) * dwHashTableSize);
- }
-
- // Write the MPQ header to the file
- if(nError == ERROR_SUCCESS)
- {
- DWORD dwHeaderSize = ha->pHeader->dwHeaderSize;
-
- BSWAP_TMPQHEADER(ha->pHeader);
- WriteFile(ha->hFile, ha->pHeader, dwHeaderSize, &dwTransferred, NULL);
- BSWAP_TMPQHEADER(ha->pHeader);
-
- if(dwTransferred != ha->pHeader->dwHeaderSize)
- nError = ERROR_DISK_FULL;
-
- ha->FilePointer.QuadPart = ha->MpqPos.QuadPart + dwTransferred;
- ha->MpqSize.QuadPart += dwTransferred;
- }
-
- // Create the internal listfile
- if(nError == ERROR_SUCCESS)
- nError = SListFileCreateListFile(ha);
-
- // Try to add the internal listfile
- if(nError == ERROR_SUCCESS)
- SFileAddListFile((HANDLE)ha, NULL);
-
- // Cleanup : If an error, delete all buffers and return
- if(nError != ERROR_SUCCESS)
- {
- FreeMPQArchive(ha);
- if(hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
- SetLastError(nError);
- }
-
- // Return the values
- *phMPQ = (HANDLE)ha;
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// Changes locale ID of a file
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
-
- // Invalid handle => do nothing
- if(IsValidFileHandle(hf) == FALSE || IsValidMpqHandle(hf->ha) == FALSE)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- // If the file has not been open for writing, do nothing.
- if(hf->ha->pListFile == NULL)
- return ERROR_ACCESS_DENIED;
-
- hf->pHash->lcLocale = (USHORT)lcNewLocale;
- hf->ha->dwFlags |= MPQ_FLAG_CHANGED;
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// Adds a file into the archive
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileAddFileEx(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality, int nFileType)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- HANDLE hFile = INVALID_HANDLE_VALUE;
- BOOL bReplaced = FALSE; // TRUE if replacing file in the archive
- int nError = ERROR_SUCCESS;
-
- if(nError == ERROR_SUCCESS)
- {
- // Check valid parameters
- if(IsValidMpqHandle(ha) == FALSE || szFileName == NULL || *szFileName == 0 || szArchivedName == NULL || *szArchivedName == 0)
- nError = ERROR_INVALID_PARAMETER;
-
- // Check the values of dwFlags
- if((dwFlags & MPQ_FILE_COMPRESS_PKWARE) && (dwFlags & MPQ_FILE_COMPRESS_MULTI))
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // If anyone is trying to add listfile, and the archive already has a listfile,
- // deny the operation, but return success.
- if(nError == ERROR_SUCCESS)
- {
- if(ha->pListFile != NULL && !_stricmp(szFileName, LISTFILE_NAME))
- return ERROR_SUCCESS;
- }
-
- // Open added file
- if(nError == ERROR_SUCCESS)
- {
- hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- nError = GetLastError();
- }
-
- if(nError == ERROR_SUCCESS)
- nError = AddFileToArchive(ha, hFile, szArchivedName, dwFlags, dwQuality, nFileType, &bReplaced);
-
- // Add the file into listfile also
- if(nError == ERROR_SUCCESS && bReplaced == FALSE)
- nError = SListFileAddNode(ha, szArchivedName);
-
- // Cleanup and exit
- if(hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-// Adds a data file into the archive
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileAddFile(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags)
-{
- return SFileAddFileEx(hMPQ, szFileName, szArchivedName, dwFlags, 0, SFILE_TYPE_DATA);
-}
-
-// Adds a WAVE file into the archive
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileAddWave(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality)
-{
- return SFileAddFileEx(hMPQ, szFileName, szArchivedName, dwFlags, dwQuality, SFILE_TYPE_WAVE);
-}
-
-//-----------------------------------------------------------------------------
-// BOOL SFileRemoveFile(HANDLE hMPQ, char * szFileName)
-//
-// This function removes a file from the archive. The file content
-// remains there, only the entries in the hash table and in the block
-// table are updated.
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileRemoveFile(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- TMPQBlockEx * pBlockEx = NULL; // Block entry of deleted file
- TMPQBlock * pBlock = NULL; // Block entry of deleted file
- TMPQHash * pHash = NULL; // Hash entry of deleted file
- DWORD dwBlockIndex = 0;
- int nError = ERROR_SUCCESS;
-
- // Check the parameters
- if(nError == ERROR_SUCCESS)
- {
- if(IsValidMpqHandle(ha) == FALSE)
- nError = ERROR_INVALID_PARAMETER;
- if(dwSearchScope != SFILE_OPEN_BY_INDEX && *szFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Do not allow to remove listfile
- if(nError == ERROR_SUCCESS)
- {
- if(dwSearchScope != SFILE_OPEN_BY_INDEX && !_stricmp(szFileName, LISTFILE_NAME))
- nError = ERROR_ACCESS_DENIED;
- }
-
- // Get hash entry belonging to this file
- if(nError == ERROR_SUCCESS)
- {
- if((pHash = GetHashEntryEx(ha, (char *)szFileName, lcLocale)) == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // If index was not found, or is greater than number of files, exit.
- if(nError == ERROR_SUCCESS)
- {
- if((dwBlockIndex = pHash->dwBlockIndex) > ha->pHeader->dwBlockTableSize)
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // Get block and test if the file is not already deleted
- if(nError == ERROR_SUCCESS)
- {
- pBlockEx = ha->pExtBlockTable + dwBlockIndex;
- pBlock = ha->pBlockTable + dwBlockIndex;
- if((pBlock->dwFlags & MPQ_FILE_EXISTS) == 0)
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // Now invalidate the block entry and the hash entry. Do not make any
- // relocations and file copying, use SFileCompactArchive for it.
- if(nError == ERROR_SUCCESS)
- {
- pBlockEx->wFilePosHigh = 0;
- pBlock->dwFilePos = 0;
- pBlock->dwFSize = 0;
- pBlock->dwCSize = 0;
- pBlock->dwFlags = 0;
- pHash->dwName1 = 0xFFFFFFFF;
- pHash->dwName2 = 0xFFFFFFFF;
- pHash->lcLocale = 0xFFFF;
- pHash->wPlatform = 0xFFFF;
- pHash->dwBlockIndex = HASH_ENTRY_DELETED;
-
- // Update MPQ archive
- ha->dwFlags |= MPQ_FLAG_CHANGED;
- }
-
- // Remove the file from the list file
- if(nError == ERROR_SUCCESS && lcLocale == LANG_NEUTRAL)
- nError = SListFileRemoveNode(ha, szFileName);
-
- // Resolve error and exit
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
-// Renames the file within the archive.
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileRenameFile(HANDLE hMPQ, const char * szFileName, const char * szNewFileName)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- TMPQHash * pOldHash = NULL; // Hash entry for the original file
- TMPQHash * pNewHash = NULL; // Hash entry for the renamed file
- DWORD dwBlockIndex = 0;
- int nError = ERROR_SUCCESS;
-
- // Test the valid parameters
- if(nError == ERROR_SUCCESS)
- {
- if(hMPQ == NULL || szNewFileName == NULL || *szNewFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
- if(szFileName == NULL || *szFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Do not allow to rename listfile
- if(nError == ERROR_SUCCESS)
- {
- if(!_stricmp(szFileName, LISTFILE_NAME))
- nError = ERROR_ACCESS_DENIED;
- }
-
- // Test if the file already exists in the archive
- if(nError == ERROR_SUCCESS)
- {
- if((pNewHash = GetHashEntryEx(ha, szNewFileName, lcLocale)) != NULL)
- nError = ERROR_ALREADY_EXISTS;
- }
-
- // Get the hash table entry for the original file
- if(nError == ERROR_SUCCESS)
- {
- if((pOldHash = GetHashEntryEx(ha, szFileName, lcLocale)) == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // Get the hash table entry for the renamed file
- if(nError == ERROR_SUCCESS)
- {
- // Save block table index and remove the hash table entry
- dwBlockIndex = pOldHash->dwBlockIndex;
- pOldHash->dwName1 = 0xFFFFFFFF;
- pOldHash->dwName2 = 0xFFFFFFFF;
- pOldHash->lcLocale = 0xFFFF;
- pOldHash->wPlatform = 0xFFFF;
- pOldHash->dwBlockIndex = HASH_ENTRY_DELETED;
-
- if((pNewHash = FindFreeHashEntry(ha, szNewFileName)) == NULL)
- nError = ERROR_CAN_NOT_COMPLETE;
- }
-
- // Save the block index and clear the hash entry
- if(nError == ERROR_SUCCESS)
- {
- // Copy the block table index
- pNewHash->dwBlockIndex = dwBlockIndex;
- ha->dwFlags |= MPQ_FLAG_CHANGED;
- }
-
- // Rename the file in the list file
- if(nError == ERROR_SUCCESS)
- nError = SListFileRenameNode(ha, szFileName, szNewFileName);
-
- // Resolve error and return
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (nError == ERROR_SUCCESS);
-}
-
diff --git a/contrib/vmap_extractor_v2/stormlib/SFileExtractFile.cpp b/contrib/vmap_extractor_v2/stormlib/SFileExtractFile.cpp
deleted file mode 100644
index 7f16cde0171..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SFileExtractFile.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*****************************************************************************/
-/* SFileExtractFile.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Simple extracting utility */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 20.06.03 1.00 Lad The first version of SFileExtractFile.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted)
-{
- HANDLE hLocalFile = INVALID_HANDLE_VALUE;
- HANDLE hMpqFile = NULL;
- int nError = ERROR_SUCCESS;
-
- // Create the local file
- if(nError == ERROR_SUCCESS)
- {
- hLocalFile = CreateFile(szExtracted, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
- if(hLocalFile == INVALID_HANDLE_VALUE)
- nError = GetLastError();
- }
-
- // Open the MPQ file
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileOpenFileEx(hMpq, szToExtract, 0, &hMpqFile))
- nError = GetLastError();
- }
-
- // Copy the file's content
- if(nError == ERROR_SUCCESS)
- {
- char szBuffer[0x1000];
- DWORD dwTransferred = 1;
-
- while(dwTransferred > 0)
- {
- SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL);
- if(dwTransferred == 0)
- break;
-
- WriteFile(hLocalFile, szBuffer, dwTransferred, &dwTransferred, NULL);
- if(dwTransferred == 0)
- break;
- }
- }
-
- // Close the files
- if(hMpqFile != NULL)
- SFileCloseFile(hMpqFile);
- if(hLocalFile != INVALID_HANDLE_VALUE)
- CloseHandle(hLocalFile);
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return (BOOL)(nError == ERROR_SUCCESS);
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/SFileFindFile.cpp b/contrib/vmap_extractor_v2/stormlib/SFileFindFile.cpp
deleted file mode 100644
index 41dbeba900c..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SFileFindFile.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/*****************************************************************************/
-/* SFileFindFile.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* A module for file searching within MPQs */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 25.03.03 1.00 Lad The first version of SFileFindFile.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define LISTFILE_CACHE_SIZE 0x1000
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static BOOL IsValidSearchHandle(TMPQSearch * hs)
-{
- if(hs == NULL || IsBadReadPtr(hs, sizeof(TMPQSearch)))
- return FALSE;
-
- if(!IsValidMpqHandle(hs->ha))
- return FALSE;
-
- return TRUE;
-}
-
-// This function compares a string with a wildcard search string.
-// returns TRUE, when the string matches with the wildcard.
-BOOL CheckWildCard(const char * szString, const char * szWildCard)
-{
- char * szTemp; // Temporary helper pointer
- int nResult = 0; // For memcmp return values
- int nMustNotMatch = 0; // Number of following chars int szString,
- // which must not match with szWildCard
- int nMustMatch = 0; // Number of the following characters,
- // which must match
-
- // When the string is empty, it does not match with every wildcard
- if(*szString == 0)
- return FALSE;
-
- // When the mask is empty, it matches to every wildcard
- if(szWildCard == NULL || *szWildCard == 0)
- return FALSE;
-
- // Do normal test
- for(;;)
- {
- switch(*szWildCard)
- {
- case '*': // Means "every number of characters"
- // Skip all asterisks
- while(*szWildCard == '*')
- szWildCard++;
-
- // When no more characters in wildcard, it means that the strings match
- if(*szWildCard == 0)
- return TRUE;
-
- // The next N characters must not agree
- nMustNotMatch |= 0x70000000;
- break;
-
- case '?': // Means "One or no character"
- while(*szWildCard == '?')
- {
- nMustNotMatch++;
- szWildCard++;
- }
- break;
-
- default:
- // If the two characters match
- if(toupper(*szString) == toupper(*szWildCard))
- {
- // When end of string, they agree
- if(*szString == 0)
- return TRUE;
-
- nMustNotMatch = 0;
- szWildCard++;
- szString++;
- break;
- }
-
- // If the next character must match, the string does not match
- if(nMustNotMatch == 0)
- return FALSE;
-
- // Count the characters which must match after characters
- // that must not match
- szTemp = (char *)szWildCard;
- nMustMatch = 0;
- while(*szTemp != 0 && *szTemp != '*' && *szTemp != '?')
- {
- nMustMatch++;
- szTemp++;
- }
-
- // Now skip characters from szString up to number of chars
- // that must not match
- nResult = -1;
- while(nMustNotMatch > 0 && *szString != 0)
- {
- if((nResult = _strnicmp(szString, szWildCard, nMustMatch)) == 0)
- break;
-
- szString++;
- nMustNotMatch--;
- }
-
- // Make one more comparison
- if(nMustNotMatch == 0)
- nResult = _strnicmp(szString, szWildCard, nMustMatch);
-
- // If a match has been found, continue the search
- if(nResult == 0)
- {
- nMustNotMatch = 0;
- szWildCard += nMustMatch;
- szString += nMustMatch;
- break;
- }
- return FALSE;
- }
- }
-}
-
-// Performs one MPQ search
-// TODO: Test for archives > 4GB
-static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
-{
- TMPQArchive * ha = hs->ha;
- TFileNode * pNode;
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash = ha->pHashTable + hs->dwNextIndex;
-
- // Do until some file found or no more files
- while(pHash < pHashEnd)
- {
- pNode = ha->pListFile[hs->dwNextIndex++];
-
- // If this entry is free, do nothing
- if(pHash->dwBlockIndex < HASH_ENTRY_FREE && (DWORD_PTR)pNode < HASH_ENTRY_FREE)
- {
- // Check the file name.
- if(CheckWildCard(pNode->szFileName, hs->szSearchMask))
- {
- TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex;
-
- lpFindFileData->lcLocale = pHash->lcLocale;
- lpFindFileData->dwFileSize = pBlock->dwFSize;
- lpFindFileData->dwFileFlags = pBlock->dwFlags;
- lpFindFileData->dwBlockIndex = pHash->dwBlockIndex;
- lpFindFileData->dwCompSize = pBlock->dwCSize;
-
- // Fill the file name and plain file name
- strcpy(lpFindFileData->cFileName, pNode->szFileName);
- lpFindFileData->szPlainName = strrchr(lpFindFileData->cFileName, '\\');
- if(lpFindFileData->szPlainName == NULL)
- lpFindFileData->szPlainName = lpFindFileData->cFileName;
- else
- lpFindFileData->szPlainName++;
-
- // Fill the next entry
- return ERROR_SUCCESS;
- }
- }
-
- pHash++;
- }
-
- // No more files found, return error
- return ERROR_NO_MORE_FILES;
-}
-
-// TODO: Test for archives > 4GB
-static void FreeMPQSearch(TMPQSearch *& hs)
-{
- if(hs != NULL)
- {
- FREEMEM(hs);
- hs = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-// TODO: Test for archives > 4GB
-HANDLE WINAPI SFileFindFirstFile(HANDLE hMPQ, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- TMPQSearch * hs = NULL; // Search object handle
- size_t nSize = 0;
- int nError = ERROR_SUCCESS;
-
- // Check for the valid parameters
- if(nError == ERROR_SUCCESS)
- {
- if(!IsValidMpqHandle(ha))
- nError = ERROR_INVALID_PARAMETER;
-
- if(szMask == NULL || lpFindFileData == NULL)
- nError = ERROR_INVALID_PARAMETER;
-
- if(szListFile == NULL && !IsValidMpqHandle(ha))
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Include the listfile into the MPQ's internal listfile
- // Note that if the listfile name is NULL, do nothing because the
- // internal listfile is always included.
- if(nError == ERROR_SUCCESS && szListFile != NULL)
- nError = SFileAddListFile((HANDLE)ha, szListFile);
-
- // Allocate the structure for MPQ search
- if(nError == ERROR_SUCCESS)
- {
- nSize = sizeof(TMPQSearch) + strlen(szMask) + 1;
- if((hs = (TMPQSearch *)ALLOCMEM(char, nSize)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Perform the first search
- if(nError == ERROR_SUCCESS)
- {
- memset(hs, 0, sizeof(TMPQSearch));
- hs->ha = ha;
- hs->dwNextIndex = 0;
- strcpy(hs->szSearchMask, szMask);
- nError = DoMPQSearch(hs, lpFindFileData);
- }
-
- // Cleanup
- if(nError != ERROR_SUCCESS)
- {
- FreeMPQSearch(hs);
- SetLastError(nError);
- }
-
- // Return the result value
- return (HANDLE)hs;
-}
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
-{
- TMPQSearch * hs = (TMPQSearch *)hFind;
- int nError = ERROR_SUCCESS;
-
- // Check the parameters
- if(nError == ERROR_SUCCESS)
- {
- if(!IsValidSearchHandle(hs) || lpFindFileData == NULL)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- if(nError == ERROR_SUCCESS)
- nError = DoMPQSearch(hs, lpFindFileData);
-
- if(nError != ERROR_SUCCESS)
- {
- SetLastError(nError);
- return FALSE;
- }
- return TRUE;
-}
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileFindClose(HANDLE hFind)
-{
- TMPQSearch * hs = (TMPQSearch *)hFind;
-
- // Check the parameters
- if(!IsValidSearchHandle(hs))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- FreeMPQSearch(hs);
- return TRUE;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/SFileOpenArchive.cpp b/contrib/vmap_extractor_v2/stormlib/SFileOpenArchive.cpp
deleted file mode 100644
index cadb4e023a2..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SFileOpenArchive.cpp
+++ /dev/null
@@ -1,497 +0,0 @@
-/*****************************************************************************/
-/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */
-/* */
-/* Author : Ladislav Zezula */
-/* E-mail : ladik@zezula.net */
-/* WWW : www.zezula.net */
-/*---------------------------------------------------------------------------*/
-/* Archive functions of Storm.dll */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of SFileOpenArchive.cpp */
-/* 19.11.03 1.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-/*****************************************************************************/
-/* Local functions */
-/*****************************************************************************/
-
-static BOOL IsAviFile(TMPQHeader * pHeader)
-{
- DWORD * AviHdr = (DWORD *)pHeader;
-
- // Test for 'RIFF', 'AVI ' or 'LIST'
- return (AviHdr[0] == 'FFIR' && AviHdr[2] == ' IVA' && AviHdr[3] == 'TSIL');
-}
-
-// This function gets the right positions of the hash table and the block table.
-// TODO: Test for archives > 4GB
-static int RelocateMpqTablePositions(TMPQArchive * ha)
-{
- TMPQHeader2 * pHeader = ha->pHeader;
- LARGE_INTEGER FileSize;
- LARGE_INTEGER TempSize;
-
- // Get the size of the file
- FileSize.LowPart = GetFileSize(ha->hFile, (LPDWORD)&FileSize.HighPart);
-
- // Set the proper hash table position
- ha->HashTablePos.HighPart = pHeader->wHashTablePosHigh;
- ha->HashTablePos.LowPart = pHeader->dwHashTablePos;
- ha->HashTablePos.QuadPart += ha->MpqPos.QuadPart;
- if(ha->HashTablePos.QuadPart > FileSize.QuadPart)
- return ERROR_BAD_FORMAT;
-
- // Set the proper block table position
- ha->BlockTablePos.HighPart = pHeader->wBlockTablePosHigh;
- ha->BlockTablePos.LowPart = pHeader->dwBlockTablePos;
- ha->BlockTablePos.QuadPart += ha->MpqPos.QuadPart;
- if(ha->BlockTablePos.QuadPart > FileSize.QuadPart)
- return ERROR_BAD_FORMAT;
-
- // Set the proper position of the extended block table
- if(pHeader->ExtBlockTablePos.QuadPart != 0)
- {
- ha->ExtBlockTablePos = pHeader->ExtBlockTablePos;
- ha->ExtBlockTablePos.QuadPart += ha->MpqPos.QuadPart;
- if(ha->ExtBlockTablePos.QuadPart > FileSize.QuadPart)
- return ERROR_BAD_FORMAT;
- }
-
- // Size of MPQ archive is computed as the biggest of
- // (EndOfBlockTable, EndOfHashTable, EndOfExtBlockTable)
- TempSize.QuadPart = ha->HashTablePos.QuadPart + (pHeader->dwHashTableSize * sizeof(TMPQHash));
- if(TempSize.QuadPart > ha->MpqSize.QuadPart)
- ha->MpqSize = TempSize;
- TempSize.QuadPart = ha->BlockTablePos.QuadPart + (pHeader->dwBlockTableSize * sizeof(TMPQBlock));
- if(TempSize.QuadPart > ha->MpqSize.QuadPart)
- ha->MpqSize = TempSize;
- TempSize.QuadPart = ha->ExtBlockTablePos.QuadPart + (pHeader->dwBlockTableSize * sizeof(TMPQBlockEx));
- if(TempSize.QuadPart > ha->MpqSize.QuadPart)
- ha->MpqSize = TempSize;
-
- // MPQ size does not include the bytes before MPQ header
- ha->MpqSize.QuadPart -= ha->MpqPos.QuadPart;
- return ERROR_SUCCESS;
-}
-
-
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
-
-//-----------------------------------------------------------------------------
-// SFileGetLocale and SFileSetLocale
-// Set the locale for all neewly opened archives and files
-
-LCID WINAPI SFileGetLocale()
-{
- return lcLocale;
-}
-
-LCID WINAPI SFileSetLocale(LCID lcNewLocale)
-{
- lcLocale = lcNewLocale;
- return lcLocale;
-}
-
-//-----------------------------------------------------------------------------
-// SFileOpenArchiveEx (not a public function !!!)
-//
-// szFileName - MPQ archive file name to open
-// dwPriority - When SFileOpenFileEx called, this contains the search priority for searched archives
-// dwFlags - If contains MPQ_OPEN_NO_LISTFILE, then the internal list file will not be used.
-// phMPQ - Pointer to store open archive handle
-
-BOOL SFileOpenArchiveEx(
- const char * szMpqName,
- DWORD dwPriority,
- DWORD dwFlags,
- HANDLE * phMPQ,
- DWORD dwAccessMode)
-{
- LARGE_INTEGER TempPos;
- TMPQArchive * ha = NULL; // Archive handle
- HANDLE hFile = INVALID_HANDLE_VALUE;// Opened archive file handle
- DWORD dwMaxBlockIndex = 0; // Maximum value of block entry
- DWORD dwBlockTableSize = 0; // Block table size.
- DWORD dwTransferred; // Number of bytes read
- DWORD dwBytes = 0; // Number of bytes to read
- int nError = ERROR_SUCCESS;
-
- // Check the right parameters
- if(nError == ERROR_SUCCESS)
- {
- if(szMpqName == NULL || *szMpqName == 0 || phMPQ == NULL)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Ensure that StormBuffer is allocated
- if(nError == ERROR_SUCCESS)
- nError = PrepareStormBuffer();
-
- // Open the MPQ archive file
- if(nError == ERROR_SUCCESS)
- {
- hFile = CreateFile(szMpqName, dwAccessMode, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- nError = GetLastError();
- }
-
- // Allocate the MPQhandle
- if(nError == ERROR_SUCCESS)
- {
- if((ha = ALLOCMEM(TMPQArchive, 1)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Initialize handle structure and allocate structure for MPQ header
- if(nError == ERROR_SUCCESS)
- {
- memset(ha, 0, sizeof(TMPQArchive));
- strncpy(ha->szFileName, szMpqName, strlen(szMpqName));
- ha->hFile = hFile;
- ha->dwPriority = dwPriority;
- ha->pHeader = &ha->Header;
- ha->pListFile = NULL;
- hFile = INVALID_HANDLE_VALUE;
- }
-
- // Find the offset of MPQ header within the file
- if(nError == ERROR_SUCCESS)
- {
- LARGE_INTEGER SearchPos = {0};
- LARGE_INTEGER MpqPos = {0};
- DWORD dwHeaderID;
-
- for(;;)
- {
- // Invalidate the MPQ ID and read the eventual header
- SetFilePointer(ha->hFile, MpqPos.LowPart, &MpqPos.HighPart, FILE_BEGIN);
- ReadFile(ha->hFile, ha->pHeader, sizeof(TMPQHeader2), &dwTransferred, NULL);
- dwHeaderID = BSWAP_INT32_UNSIGNED(ha->pHeader->dwID);
-
- // Special check : Some MPQs are actually AVI files, only with
- // changed extension.
- if(MpqPos.QuadPart == 0 && IsAviFile(ha->pHeader))
- {
- nError = ERROR_AVI_FILE;
- break;
- }
-
- // If different number of bytes read, break the loop
- if(dwTransferred != sizeof(TMPQHeader2))
- {
- nError = ERROR_BAD_FORMAT;
- break;
- }
-
- // If there is the MPQ shunt signature, process it
- if(dwHeaderID == ID_MPQ_SHUNT && ha->pShunt == NULL)
- {
- // Fill the shunt header
- ha->ShuntPos = MpqPos;
- ha->pShunt = &ha->Shunt;
- memcpy(ha->pShunt, ha->pHeader, sizeof(TMPQShunt));
- BSWAP_TMPQSHUNT(ha->pShunt);
-
- // Set the MPQ pos and repeat the search
- MpqPos.QuadPart = SearchPos.QuadPart + ha->pShunt->dwHeaderPos;
- continue;
- }
-
- // There must be MPQ header signature
- if(dwHeaderID == ID_MPQ)
- {
- BSWAP_TMPQHEADER(ha->pHeader);
-
- // Save the position where the MPQ header has been found
- ha->MpqPos = MpqPos;
-
- // If valid signature has been found, break the loop
- if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
- {
- // W3M Map Protectors set some garbage value into the "dwHeaderSize"
- // field of MPQ header. This value is apparently ignored by Storm.dll
- if(ha->pHeader->dwHeaderSize != sizeof(TMPQHeader) &&
- ha->pHeader->dwHeaderSize != sizeof(TMPQHeader2))
- {
- ha->dwFlags |= MPQ_FLAG_PROTECTED;
- ha->pHeader->dwHeaderSize = sizeof(TMPQHeader);
- }
-
- if(ha->pHeader->dwHashTablePos < ha->pHeader->dwArchiveSize &&
- ha->pHeader->dwBlockTablePos < ha->pHeader->dwArchiveSize)
- {
- break;
- }
- }
-
- if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_2)
- {
- break;
- }
-
- nError = ERROR_NOT_SUPPORTED;
- break;
- }
-
- // If a MPQ shunt already has been found,
- // and no MPQ header was at potision pointed by the shunt,
- // then the archive is corrupt
- if(ha->pShunt != NULL)
- {
- nError = ERROR_BAD_FORMAT;
- break;
- }
-
- // Move to the next possible offset
- SearchPos.QuadPart += 0x200;
- MpqPos = SearchPos;
- }
- }
-
- // Relocate tables position
- if(nError == ERROR_SUCCESS)
- {
- // Clear the fields not supported in older formats
- if(ha->pHeader->wFormatVersion < MPQ_FORMAT_VERSION_2)
- {
- ha->pHeader->ExtBlockTablePos.QuadPart = 0;
- ha->pHeader->wBlockTablePosHigh = 0;
- ha->pHeader->wHashTablePosHigh = 0;
- }
-
- ha->dwBlockSize = (0x200 << ha->pHeader->wBlockSize);
- nError = RelocateMpqTablePositions(ha);
- }
-
- // Allocate buffers
- if(nError == ERROR_SUCCESS)
- {
- //
- // Note that the block table should be as large as the hash table
- // (For later file additions).
- //
- // I have found a MPQ which has the block table larger than
- // the hash table. We should avoid buffer overruns caused by that.
- //
- dwBlockTableSize = max(ha->pHeader->dwHashTableSize, ha->pHeader->dwBlockTableSize);
-
- ha->pHashTable = ALLOCMEM(TMPQHash, ha->pHeader->dwHashTableSize);
- ha->pBlockTable = ALLOCMEM(TMPQBlock, dwBlockTableSize);
- ha->pExtBlockTable = ALLOCMEM(TMPQBlockEx, dwBlockTableSize);
- ha->pbBlockBuffer = ALLOCMEM(BYTE, ha->dwBlockSize);
-
- if(!ha->pHashTable || !ha->pBlockTable || !ha->pExtBlockTable || !ha->pbBlockBuffer)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Read the hash table into memory
- if(nError == ERROR_SUCCESS)
- {
- dwBytes = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
- SetFilePointer(ha->hFile, ha->HashTablePos.LowPart, &ha->HashTablePos.HighPart, FILE_BEGIN);
- ReadFile(ha->hFile, ha->pHashTable, dwBytes, &dwTransferred, NULL);
-
- if(dwTransferred != dwBytes)
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Decrypt hash table and check if it is correctly decrypted
- if(nError == ERROR_SUCCESS)
- {
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash;
-
- // We have to convert the hash table from LittleEndian
- BSWAP_ARRAY32_UNSIGNED((DWORD *)ha->pHashTable, (dwBytes / sizeof(DWORD)));
- DecryptHashTable((DWORD *)ha->pHashTable, (BYTE *)"(hash table)", (ha->pHeader->dwHashTableSize * 4));
-
- // Check hash table if is correctly decrypted
- for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
- {
- // Note: Some MPQs from World of Warcraft have wPlatform set to 0x0100.
-
- // If not free or deleted hash entry, check for valid values
- if(pHash->dwBlockIndex < HASH_ENTRY_DELETED)
- {
- // The block index should not be larger than size of the block table
- if(pHash->dwBlockIndex > ha->pHeader->dwBlockTableSize)
- {
- nError = ERROR_BAD_FORMAT;
- break;
- }
-
- // Remember the highest block table entry
- if(pHash->dwBlockIndex > dwMaxBlockIndex)
- dwMaxBlockIndex = pHash->dwBlockIndex;
- }
- }
- }
-
- // Now, read the block table
- if(nError == ERROR_SUCCESS)
- {
- memset(ha->pBlockTable, 0, dwBlockTableSize * sizeof(TMPQBlock));
-
- dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- SetFilePointer(ha->hFile, ha->BlockTablePos.LowPart, &ha->BlockTablePos.HighPart, FILE_BEGIN);
- ReadFile(ha->hFile, ha->pBlockTable, dwBytes, &dwTransferred, NULL);
-
- // We have to convert every DWORD in ha->block from LittleEndian
- BSWAP_ARRAY32_UNSIGNED((DWORD *)ha->pBlockTable, dwBytes / sizeof(DWORD));
-
- if(dwTransferred != dwBytes)
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Decrypt block table.
- // Some MPQs don't have Decrypted block table, e.g. cracked Diablo version
- // We have to check if block table is really encrypted
- if(nError == ERROR_SUCCESS)
- {
- TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize;
- TMPQBlock * pBlock = ha->pBlockTable;
- BOOL bBlockTableEncrypted = FALSE;
-
- // Verify all blocks entries in the table
- // The loop usually stops at the first entry
- while(pBlock < pBlockEnd)
- {
- // The lower 8 bits of the MPQ flags are always zero.
- // Note that this may change in next MPQ versions
- if(pBlock->dwFlags & 0x000000FF)
- {
- bBlockTableEncrypted = TRUE;
- break;
- }
-
- // Move to the next block table entry
- pBlock++;
- }
-
- if(bBlockTableEncrypted)
- {
- DecryptBlockTable((DWORD *)ha->pBlockTable,
- (BYTE *)"(block table)",
- (ha->pHeader->dwBlockTableSize * 4));
- }
- }
-
- // Now, read the extended block table.
- // For V1 archives, we still will maintain the extended block table
- // (it will be filled with zeros)
- // TODO: Test with >4GB
- if(nError == ERROR_SUCCESS)
- {
- memset(ha->pExtBlockTable, 0, dwBlockTableSize * sizeof(TMPQBlockEx));
-
- if(ha->pHeader->ExtBlockTablePos.QuadPart != 0)
- {
- dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx);
- SetFilePointer(ha->hFile,
- ha->ExtBlockTablePos.LowPart,
- &ha->ExtBlockTablePos.HighPart,
- FILE_BEGIN);
- ReadFile(ha->hFile, ha->pExtBlockTable, dwBytes, &dwTransferred, NULL);
-
- // We have to convert every DWORD in ha->block from LittleEndian
- BSWAP_ARRAY16_UNSIGNED((USHORT *)ha->pExtBlockTable, dwBytes / sizeof(USHORT));
-
- // The extended block table is not encrypted (so far)
- if(dwTransferred != dwBytes)
- nError = ERROR_FILE_CORRUPT;
- }
- }
-
- // Verify the both block tables (If the MPQ file is not protected)
- if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_PROTECTED) == 0)
- {
- TMPQBlockEx * pBlockEx = ha->pExtBlockTable;
- TMPQBlock * pBlockEnd = ha->pBlockTable + dwMaxBlockIndex + 1;
- TMPQBlock * pBlock = ha->pBlockTable;
-
- // If the MPQ file is not protected,
- // we will check if all sizes in the block table is correct.
- // Note that we will not relocate the block table (change from previous versions)
- for(; pBlock < pBlockEnd; pBlock++, pBlockEx++)
- {
- if(pBlock->dwFlags & MPQ_FILE_EXISTS)
- {
- // Get the 64-bit file position
- TempPos.HighPart = pBlockEx->wFilePosHigh;
- TempPos.LowPart = pBlock->dwFilePos;
-
- if(TempPos.QuadPart > ha->MpqSize.QuadPart || pBlock->dwCSize > ha->MpqSize.QuadPart)
- {
- nError = ERROR_BAD_FORMAT;
- break;
- }
- }
- }
- }
-
- // If the user didn't specified otherwise,
- // include the internal listfile to the TMPQArchive structure
- if((dwFlags & MPQ_OPEN_NO_LISTFILE) == 0)
- {
- if(nError == ERROR_SUCCESS)
- SListFileCreateListFile(ha);
-
- // Add the internal listfile
- if(nError == ERROR_SUCCESS)
- SFileAddListFile((HANDLE)ha, NULL);
- }
-
- // Cleanup and exit
- if(nError != ERROR_SUCCESS)
- {
- FreeMPQArchive(ha);
- if(hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
- SetLastError(nError);
- }
- else
- {
- if(pFirstOpen == NULL)
- pFirstOpen = ha;
- }
- *phMPQ = ha;
- return (nError == ERROR_SUCCESS);
-}
-
-BOOL WINAPI SFileOpenArchive(const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMPQ)
-{
- return SFileOpenArchiveEx(szMpqName, dwPriority, dwFlags, phMPQ, GENERIC_READ);
-}
-
-//-----------------------------------------------------------------------------
-// BOOL SFileCloseArchive(HANDLE hMPQ);
-//
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileCloseArchive(HANDLE hMPQ)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
-
- if(!IsValidMpqHandle(ha))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if(ha->dwFlags & MPQ_FLAG_CHANGED)
- {
- SListFileSaveToMpq(ha);
- SaveMPQTables(ha);
- }
- FreeMPQArchive(ha);
- return TRUE;
-}
-
diff --git a/contrib/vmap_extractor_v2/stormlib/SFileOpenFileEx.cpp b/contrib/vmap_extractor_v2/stormlib/SFileOpenFileEx.cpp
deleted file mode 100644
index dae312144eb..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SFileOpenFileEx.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/*****************************************************************************/
-/* SFileOpenFileEx.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.99 1.00 Lad The first version of SFileOpenFileEx.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-/*****************************************************************************/
-/* Local functions */
-/*****************************************************************************/
-
-// TODO: Test for archives > 4GB
-static BOOL OpenLocalFile(const char * szFileName, HANDLE * phFile)
-{
- TMPQFile * hf = NULL;
- HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
-
- if(hFile != INVALID_HANDLE_VALUE)
- {
- // Allocate and initialize file handle
- size_t nHandleSize = sizeof(TMPQFile) + strlen(szFileName);
- if((hf = (TMPQFile *)ALLOCMEM(char, nHandleSize)) != NULL)
- {
- memset(hf, 0, nHandleSize);
- strcpy(hf->szFileName, szFileName);
- hf->hFile = hFile;
- *phFile = hf;
- return TRUE;
- }
- else
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- }
- *phFile = NULL;
- return FALSE;
-}
-
-// TODO: Test for archives > 4GB
-static void FreeMPQFile(TMPQFile *& hf)
-{
- if(hf != NULL)
- {
- if(hf->hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hf->hFile);
- if(hf->pdwBlockPos != NULL)
- FREEMEM(hf->pdwBlockPos);
- if(hf->pbFileBuffer != NULL)
- FREEMEM(hf->pbFileBuffer);
- FREEMEM(hf);
- hf = NULL;
- }
-}
-
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
-
-//-----------------------------------------------------------------------------
-// SFileEnumLocales enums all locale versions within MPQ.
-// Functions fills all available language identifiers on a file into the buffer
-// pointed by plcLocales. There must be enough entries to copy the localed,
-// otherwise the function returns ERROR_INSUFFICIENT_BUFFER.
-
-// TODO: Test for archives > 4GB
-int WINAPI SFileEnumLocales(
- HANDLE hMPQ,
- const char * szFileName,
- LCID * plcLocales,
- DWORD * pdwMaxLocales,
- DWORD dwSearchScope)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- TMPQHash * pHash = NULL;
- TMPQHash * pHashEnd = NULL;
- DWORD dwLocales = 0;
- int nError = ERROR_SUCCESS;
-
- // Test the parameters
- if(nError == ERROR_SUCCESS)
- {
- if(!IsValidMpqHandle(ha) || pdwMaxLocales == NULL)
- nError = ERROR_INVALID_PARAMETER;
- if(dwSearchScope == SFILE_OPEN_BY_INDEX && (DWORD_PTR)szFileName > ha->pHeader->dwBlockTableSize)
- nError = ERROR_INVALID_PARAMETER;
- if(dwSearchScope != SFILE_OPEN_BY_INDEX && *szFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Retrieve the hash entry for the required file
- if(nError == ERROR_SUCCESS)
- {
- pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
-
- if(dwSearchScope == SFILE_OPEN_BY_INDEX)
- {
- for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
- {
- if(pHash->dwBlockIndex == (DWORD_PTR)szFileName)
- break;
- }
- if(pHash == pHashEnd)
- pHash = NULL;
- }
- else
- pHash = GetHashEntry(ha, szFileName);
- }
-
- // If the file was not found, sorry
- if(nError == ERROR_SUCCESS)
- {
- if(pHash == NULL)
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // Count the entries which correspond to the same file name
- if(nError == ERROR_SUCCESS)
- {
- TMPQHash * pSaveHash = pHash;
- DWORD dwName1 = pHash->dwName1;
- DWORD dwName2 = pHash->dwName2;
-
- // For nameless access, return 1 locale always
- if(dwSearchScope == SFILE_OPEN_BY_INDEX)
- dwLocales++;
- else
- {
- while(pHash < pHashEnd && pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2)
- {
- dwLocales++;
- pHash++;
- }
- }
-
- pHash = pSaveHash;
- }
-
- // Test if there is enough space to copy the locales
- if(nError == ERROR_SUCCESS)
- {
- DWORD dwMaxLocales = *pdwMaxLocales;
-
- *pdwMaxLocales = dwLocales;
- if(dwMaxLocales < dwLocales)
- nError = ERROR_INSUFFICIENT_BUFFER;
- }
-
- // Fill all the locales
- if(nError == ERROR_SUCCESS)
- {
- for(DWORD i = 0; i < dwLocales; i++, pHash++)
- *plcLocales++ = (LCID)pHash->lcLocale;
- }
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// SFileHasFile
-//
-// hMPQ - Handle of opened MPQ archive
-// szFileName - Name of file to look for
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileHasFile(HANDLE hMPQ, char * szFileName)
-{
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- int nError = ERROR_SUCCESS;
-
- if(nError == ERROR_SUCCESS)
- {
- if(ha == NULL)
- nError = ERROR_INVALID_PARAMETER;
- if(*szFileName == 0)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Prepare the file opening
- if(nError == ERROR_SUCCESS)
- {
- if(GetHashEntryEx(ha, szFileName, lcLocale) == NULL)
- {
- nError = ERROR_FILE_NOT_FOUND;
- }
- }
-
- // Cleanup
- if(nError != ERROR_SUCCESS)
- {
- SetLastError(nError);
- }
-
- return (nError == ERROR_SUCCESS);
-}
-
-
-//-----------------------------------------------------------------------------
-// SFileOpenFileEx
-//
-// hMPQ - Handle of opened MPQ archive
-// szFileName - Name of file to open
-// dwSearchScope - Where to search
-// phFile - Pointer to store opened file handle
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileOpenFileEx(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile)
-{
- LARGE_INTEGER FilePos;
- TMPQArchive * ha = (TMPQArchive *)hMPQ;
- TMPQFile * hf = NULL;
- TMPQHash * pHash = NULL; // Hash table index
- TMPQBlock * pBlock = NULL; // File block
- TMPQBlockEx * pBlockEx = NULL;
- DWORD dwHashIndex = 0; // Hash table index
- DWORD dwBlockIndex = (DWORD)-1; // Found table index
- size_t nHandleSize = 0; // Memory space necessary to allocate TMPQHandle
- int nError = ERROR_SUCCESS;
-
-#ifdef _DEBUG
- // Due to increasing numbers of files in MPQs, I had to change the behavior
- // of opening by file index. Now, the SFILE_OPEN_BY_INDEX value of dwSearchScope
- // must be entered. This check will allow to find code places that are incompatible
- // with the new behavior.
- if(dwSearchScope != SFILE_OPEN_BY_INDEX && szFileName != NULL)
- {
- assert((DWORD_PTR)szFileName > 0x10000);
- }
-#endif
-
- if(nError == ERROR_SUCCESS)
- {
- if(ha == NULL && dwSearchScope == SFILE_OPEN_FROM_MPQ)
- nError = ERROR_INVALID_PARAMETER;
- if(phFile == NULL)
- nError = ERROR_INVALID_PARAMETER;
- if(dwSearchScope == SFILE_OPEN_BY_INDEX && (DWORD_PTR)szFileName > ha->pHeader->dwBlockTableSize)
- nError = ERROR_INVALID_PARAMETER;
- if(dwSearchScope != SFILE_OPEN_BY_INDEX && (szFileName == NULL || *szFileName == 0))
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // Prepare the file opening
- if(nError == ERROR_SUCCESS)
- {
- // When the file is given by number, ...
- if(dwSearchScope == SFILE_OPEN_BY_INDEX)
- {
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
-
- // Set handle size to be sizeof(TMPQFile) + length of FileXXXXXXXX.xxx
- nHandleSize = sizeof(TMPQFile) + 20;
- for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
- {
- if((DWORD_PTR)szFileName == pHash->dwBlockIndex)
- {
- dwHashIndex = (DWORD)(pHash - ha->pHashTable);
- dwBlockIndex = pHash->dwBlockIndex;
- break;
- }
- }
- }
- else
- {
- // If we have to open a disk file
- if(dwSearchScope == SFILE_OPEN_LOCAL_FILE)
- return OpenLocalFile(szFileName, phFile);
-
- nHandleSize = sizeof(TMPQFile) + strlen(szFileName);
- if((pHash = GetHashEntryEx(ha, szFileName, lcLocale)) != NULL)
- {
- dwHashIndex = (DWORD)(pHash - ha->pHashTable);
- dwBlockIndex = pHash->dwBlockIndex;
- }
- }
- }
-
- // Get block index from file name and test it
- if(nError == ERROR_SUCCESS)
- {
- // If index was not found, or is greater than number of files, exit.
- if(dwBlockIndex == (DWORD)-1 || dwBlockIndex > ha->pHeader->dwBlockTableSize)
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- // Get block and test if the file was not already deleted.
- if(nError == ERROR_SUCCESS)
- {
- // Get both block tables and file position
- pBlockEx = ha->pExtBlockTable + dwBlockIndex;
- pBlock = ha->pBlockTable + dwBlockIndex;
- FilePos.HighPart = pBlockEx->wFilePosHigh;
- FilePos.LowPart = pBlock->dwFilePos;
-
- if(FilePos.QuadPart > ha->MpqSize.QuadPart ||
- pBlock->dwCSize > ha->MpqSize.QuadPart)
- nError = ERROR_FILE_CORRUPT;
- if((pBlock->dwFlags & MPQ_FILE_EXISTS) == 0)
- nError = ERROR_FILE_NOT_FOUND;
- if(pBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS)
- nError = ERROR_NOT_SUPPORTED;
- }
-
- // Allocate file handle
- if(nError == ERROR_SUCCESS)
- {
- if((hf = (TMPQFile *)ALLOCMEM(char, nHandleSize)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Initialize file handle
- if(nError == ERROR_SUCCESS)
- {
- memset(hf, 0, nHandleSize);
- hf->hFile = INVALID_HANDLE_VALUE;
- hf->ha = ha;
- hf->pBlockEx = pBlockEx;
- hf->pBlock = pBlock;
- hf->nBlocks = (hf->pBlock->dwFSize + ha->dwBlockSize - 1) / ha->dwBlockSize;
- hf->pHash = pHash;
-
- hf->MpqFilePos.HighPart = pBlockEx->wFilePosHigh;
- hf->MpqFilePos.LowPart = pBlock->dwFilePos;
- hf->MpqFilePos.QuadPart += ha->MpqPos.QuadPart;
-
- hf->dwHashIndex = dwHashIndex;
- hf->dwFileIndex = dwBlockIndex;
-
- // Allocate buffers for decompression.
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- {
- // Allocate buffer for block positions. At the begin of file are stored
- // DWORDs holding positions of each block relative from begin of file in the archive
- // As for newer MPQs, there may be one additional entry in the block table
- // (if the MPQ_FILE_HAS_EXTRA flag is set).
- // Allocate the buffer to include this DWORD as well
-
- if((hf->pdwBlockPos = ALLOCMEM(DWORD, hf->nBlocks + 2)) == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Decrypt file seed. Cannot be used if the file is given by index
- if(dwSearchScope != SFILE_OPEN_BY_INDEX)
- {
- if(hf->pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- const char * szTemp = strrchr(szFileName, '\\');
-
- strcpy(hf->szFileName, szFileName);
- if(szTemp != NULL)
- szFileName = szTemp + 1;
- hf->dwSeed1 = DecryptFileSeed((char *)szFileName);
-
- if(hf->pBlock->dwFlags & MPQ_FILE_FIXSEED)
- {
- hf->dwSeed1 = (hf->dwSeed1 + hf->pBlock->dwFilePos) ^ hf->pBlock->dwFSize;
- }
- }
- }
- else
- {
- // If the file is encrypted and not compressed, we cannot detect the file seed
- if(SFileGetFileName(hf, hf->szFileName) == FALSE)
- nError = GetLastError();
- }
- }
-
- // Cleanup
- if(nError != ERROR_SUCCESS)
- {
- FreeMPQFile(hf);
- SetLastError(nError);
- }
-
- *phFile = hf;
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// BOOL SFileCloseFile(HANDLE hFile);
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileCloseFile(HANDLE hFile)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
-
- if(!IsValidFileHandle(hf))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- // Set the last accessed file in the archive
- if(hf->ha != NULL)
- hf->ha->pLastFile = NULL;
-
- // Free the structure
- FreeMPQFile(hf);
- return TRUE;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/SFileReadFile.cpp b/contrib/vmap_extractor_v2/stormlib/SFileReadFile.cpp
deleted file mode 100644
index 27fd1e0f085..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SFileReadFile.cpp
+++ /dev/null
@@ -1,826 +0,0 @@
-/*****************************************************************************/
-/* SFileReadFile.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.99 1.00 Lad The first version of SFileReadFile.cpp */
-/* 24.03.99 1.00 Lad Added the SFileGetFileInfo function */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define ID_WAVE 0x46464952 // Signature of WAVes for name breaking
-#define ID_EXE 0x00005A4D // Signature of executable files
-
-//-----------------------------------------------------------------------------
-// Local structures
-
-struct TID2Ext
-{
- DWORD dwID;
- char * szExt;
-};
-
-//-----------------------------------------------------------------------------
-// ReadMPQBlock
-//
-// hf - MPQ File handle.
-// dwBlockPos - Position of block in the file (relative to file begin)
-// buffer - Pointer to target buffer to store blocks.
-// dwBlockSize - Number of bytes to read. Must be multiplier of block size.
-//
-// Returns number of bytes read.
-
-// TODO: Test for archives > 4GB
-static DWORD WINAPI ReadMPQBlocks(TMPQFile * hf, DWORD dwBlockPos, BYTE * buffer, DWORD blockBytes)
-{
- LARGE_INTEGER FilePos;
- TMPQArchive * ha = hf->ha; // Archive handle
- BYTE * tempBuffer = NULL; // Buffer for reading compressed data from the file
- DWORD dwFilePos = dwBlockPos; // Reading position from the file
- DWORD dwToRead; // Number of bytes to read
- DWORD blockNum; // Block number (needed for decrypt)
- DWORD dwBytesRead = 0; // Total number of bytes read
- DWORD bytesRemain = 0; // Number of data bytes remaining up to the end of the file
- DWORD nBlocks; // Number of blocks to load
- DWORD i;
-
- // Test parameters. Block position and block size must be block-aligned, block size nonzero
- if((dwBlockPos & (ha->dwBlockSize - 1)) || blockBytes == 0)
- return 0;
-
- // Check the end of file
- if((dwBlockPos + blockBytes) > hf->pBlock->dwFSize)
- blockBytes = hf->pBlock->dwFSize - dwBlockPos;
-
- bytesRemain = hf->pBlock->dwFSize - dwBlockPos;
- blockNum = dwBlockPos / ha->dwBlockSize;
- nBlocks = blockBytes / ha->dwBlockSize;
- if(blockBytes % ha->dwBlockSize)
- nBlocks++;
-
- // If file has variable block positions, we have to load them
- if((hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED) && hf->bBlockPosLoaded == FALSE)
- {
- // Move file pointer to the begin of the file in the MPQ
- if(hf->MpqFilePos.QuadPart != ha->FilePointer.QuadPart)
- {
- SetFilePointer(ha->hFile, hf->MpqFilePos.LowPart, &hf->MpqFilePos.HighPart, FILE_BEGIN);
- }
-
- // Read block positions from begin of file.
- dwToRead = (hf->nBlocks+1) * sizeof(DWORD);
- if(hf->pBlock->dwFlags & MPQ_FILE_HAS_EXTRA)
- dwToRead += sizeof(DWORD);
-
- // Read the block pos table and convert the buffer to little endian
- ReadFile(ha->hFile, hf->pdwBlockPos, dwToRead, &dwBytesRead, NULL);
- BSWAP_ARRAY32_UNSIGNED(hf->pdwBlockPos, (hf->nBlocks+1));
-
- //
- // If the archive if protected some way, perform additional check
- // Sometimes, the file appears not to be encrypted, but it is.
- //
- // Note: In WoW 1.10+, there's a new flag. With this flag present,
- // there's one additional entry in the block table.
- //
-
- if(hf->pdwBlockPos[0] != dwBytesRead)
- hf->pBlock->dwFlags |= MPQ_FILE_ENCRYPTED;
-
- // Decrypt loaded block positions if necessary
- if(hf->pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- // If we don't know the file seed, try to find it.
- if(hf->dwSeed1 == 0)
- hf->dwSeed1 = DetectFileSeed(hf->pdwBlockPos, dwBytesRead);
-
- // If we don't know the file seed, sorry but we cannot extract the file.
- if(hf->dwSeed1 == 0)
- return 0;
-
- // Decrypt block positions
- DecryptMPQBlock(hf->pdwBlockPos, dwBytesRead, hf->dwSeed1 - 1);
-
- // Check if the block positions are correctly decrypted
- // I don't know why, but sometimes it will result invalid block positions on some files
- if(hf->pdwBlockPos[0] != dwBytesRead)
- {
- // Try once again to detect file seed and decrypt the blocks
- // TODO: Test with >4GB
- SetFilePointer(ha->hFile, hf->MpqFilePos.LowPart, &hf->MpqFilePos.HighPart, FILE_BEGIN);
- ReadFile(ha->hFile, hf->pdwBlockPos, dwToRead, &dwBytesRead, NULL);
-
- BSWAP_ARRAY32_UNSIGNED(hf->pdwBlockPos, (hf->nBlocks+1));
- hf->dwSeed1 = DetectFileSeed(hf->pdwBlockPos, dwBytesRead);
- DecryptMPQBlock(hf->pdwBlockPos, dwBytesRead, hf->dwSeed1 - 1);
-
- // Check if the block positions are correctly decrypted
- if(hf->pdwBlockPos[0] != dwBytesRead)
- return 0;
- }
- }
-
- // Update hf's variables
- ha->FilePointer.QuadPart = hf->MpqFilePos.QuadPart + dwBytesRead;
- hf->bBlockPosLoaded = TRUE;
- }
-
- // Get file position and number of bytes to read
- dwFilePos = dwBlockPos;
- dwToRead = blockBytes;
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- {
- dwFilePos = hf->pdwBlockPos[blockNum];
- dwToRead = hf->pdwBlockPos[blockNum + nBlocks] - dwFilePos;
- }
- FilePos.QuadPart = hf->MpqFilePos.QuadPart + dwFilePos;
-
- // Get work buffer for store read data
- tempBuffer = buffer;
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- {
- if((tempBuffer = ALLOCMEM(BYTE, dwToRead)) == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
- }
-
- // Set file pointer, if necessary
- if(ha->FilePointer.QuadPart != FilePos.QuadPart)
- {
- SetFilePointer(ha->hFile, FilePos.LowPart, &FilePos.HighPart, FILE_BEGIN);
- }
-
- // 15018F87 : Read all requested blocks
- ReadFile(ha->hFile, tempBuffer, dwToRead, &dwBytesRead, NULL);
- ha->FilePointer.QuadPart = FilePos.QuadPart + dwBytesRead;
-
- // Block processing part.
- DWORD blockStart = 0; // Index of block start in work buffer
- DWORD blockSize = min(blockBytes, ha->dwBlockSize);
- DWORD index = blockNum; // Current block index
-
- dwBytesRead = 0; // Clear read byte counter
-
- // Walk through all blocks
- for(i = 0; i < nBlocks; i++, index++)
- {
- BYTE * inputBuffer = tempBuffer + blockStart;
- int outLength = ha->dwBlockSize;
-
- if(bytesRemain < (DWORD)outLength)
- outLength = bytesRemain;
-
- // Get current block length
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- blockSize = hf->pdwBlockPos[index+1] - hf->pdwBlockPos[index];
-
- // If block is encrypted, we have to decrypt it.
- if(hf->pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
- {
- BSWAP_ARRAY32_UNSIGNED((DWORD *)inputBuffer, blockSize / sizeof(DWORD));
-
- // If we don't know the seed, try to decode it as WAVE file
- if(hf->dwSeed1 == 0)
- hf->dwSeed1 = DetectFileSeed2((DWORD *)inputBuffer, 3, ID_WAVE, hf->pBlock->dwFSize - 8, 0x45564157);
-
- // Let's try MSVC's standard EXE or header
- if(hf->dwSeed1 == 0)
- hf->dwSeed1 = DetectFileSeed2((DWORD *)inputBuffer, 2, 0x00905A4D, 0x00000003);
-
- if(hf->dwSeed1 == 0)
- return 0;
-
- DecryptMPQBlock((DWORD *)inputBuffer, blockSize, hf->dwSeed1 + index);
- BSWAP_ARRAY32_UNSIGNED((DWORD *)inputBuffer, blockSize / sizeof(DWORD));
- }
-
- // If the block is really compressed, decompress it.
- // WARNING : Some block may not be compressed, it can be determined only
- // by comparing uncompressed and compressed size !!!
- if(blockSize < (DWORD)outLength)
- {
- // Is the file compressed with PKWARE Data Compression Library ?
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_PKWARE)
- Decompress_pklib((char *)buffer, &outLength, (char *)inputBuffer, (int)blockSize);
-
- // Is it a file compressed by Blizzard's multiple compression ?
- // Note that Storm.dll v 1.0.9 distributed with Warcraft III
- // passes the full path name of the opened archive as the new last parameter
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_MULTI)
- SCompDecompress((char *)buffer, &outLength, (char *)inputBuffer, (int)blockSize);
- dwBytesRead += outLength;
- buffer += outLength;
- }
- else
- {
- if(buffer != inputBuffer)
- memcpy(buffer, inputBuffer, blockSize);
-
- dwBytesRead += blockSize;
- buffer += blockSize;
- }
- blockStart += blockSize;
- bytesRemain -= outLength;
- }
-
- // Delete input buffer, if necessary
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESSED)
- FREEMEM(tempBuffer);
-
- return dwBytesRead;
-}
-
-// When this function is called, it is already ensured that the parameters are valid
-// (e.g. the "dwToRead + dwFilePos" is not greater than the file size)
-// TODO: Test for archives > 4GB
-static DWORD WINAPI ReadMPQFileSingleUnit(TMPQFile * hf, DWORD dwFilePos, BYTE * pbBuffer, DWORD dwToRead)
-{
- TMPQArchive * ha = hf->ha;
- DWORD dwBytesRead = 0;
-
- if(ha->FilePointer.QuadPart != hf->MpqFilePos.QuadPart)
- {
- SetFilePointer(ha->hFile, hf->MpqFilePos.LowPart, &hf->MpqFilePos.HighPart, FILE_BEGIN);
- ha->FilePointer = hf->MpqFilePos;
- }
-
- // If the file is really compressed, decompress it.
- // Otherwise, read the data as-is to the caller.
- if(hf->pBlock->dwCSize < hf->pBlock->dwFSize)
- {
- if(hf->pbFileBuffer == NULL)
- {
- BYTE * inputBuffer = NULL;
- int outputBufferSize = (int)hf->pBlock->dwFSize;
- int inputBufferSize = (int)hf->pBlock->dwCSize;
-
- hf->pbFileBuffer = ALLOCMEM(BYTE, outputBufferSize);
- inputBuffer = ALLOCMEM(BYTE, inputBufferSize);
- if(inputBuffer != NULL && hf->pbFileBuffer != NULL)
- {
- // Read the compressed file data
- ReadFile(ha->hFile, inputBuffer, inputBufferSize, &dwBytesRead, NULL);
-
- // Is the file compressed with PKWARE Data Compression Library ?
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_PKWARE)
- Decompress_pklib((char *)hf->pbFileBuffer, &outputBufferSize, (char *)inputBuffer, (int)inputBufferSize);
-
- // Is it a file compressed by Blizzard's multiple compression ?
- // Note that Storm.dll v 1.0.9 distributed with Warcraft III
- // passes the full path name of the opened archive as the new last parameter
- if(hf->pBlock->dwFlags & MPQ_FILE_COMPRESS_MULTI)
- SCompDecompress((char *)hf->pbFileBuffer, &outputBufferSize, (char *)inputBuffer, (int)inputBufferSize);
- }
-
- // Free the temporary buffer
- if(inputBuffer != NULL)
- FREEMEM(inputBuffer);
- }
-
- // Copy the file data, if any there
- if(hf->pbFileBuffer != NULL)
- {
- memcpy(pbBuffer, hf->pbFileBuffer + dwFilePos, dwToRead);
- dwBytesRead += dwToRead;
- }
- }
- else
- {
- // Read the uncompressed file data
- ReadFile(ha->hFile, pbBuffer, dwToRead, &dwBytesRead, NULL);
- dwBytesRead = (int)dwBytesRead;
- }
-
- return (DWORD)dwBytesRead;
-}
-
-
-//-----------------------------------------------------------------------------
-// ReadMPQFile
-
-// TODO: Test for archives > 4GB
-static DWORD WINAPI ReadMPQFile(TMPQFile * hf, DWORD dwFilePos, BYTE * pbBuffer, DWORD dwToRead)
-{
- TMPQArchive * ha = hf->ha;
- TMPQBlock * pBlock = hf->pBlock; // Pointer to file block
- DWORD dwBytesRead = 0; // Number of bytes read from the file
- DWORD dwBlockPos; // Position in the file aligned to the whole blocks
- DWORD dwLoaded;
-
- // File position is greater or equal to file size ?
- if(dwFilePos >= pBlock->dwFSize)
- return dwBytesRead;
-
- // If too few bytes in the file remaining, cut them
- if((pBlock->dwFSize - dwFilePos) < dwToRead)
- dwToRead = (pBlock->dwFSize - dwFilePos);
-
- // If the file is stored as single unit, handle it separately
- if(pBlock->dwFlags & MPQ_FILE_SINGLE_UNIT)
- return ReadMPQFileSingleUnit(hf, dwFilePos, pbBuffer, dwToRead);
-
- // Block position in the file
- dwBlockPos = dwFilePos & ~(ha->dwBlockSize - 1); // Position in the block
-
- // Load the first block, if incomplete. It may be loaded in the cache buffer.
- // We have to check if this block is loaded. If not, load it.
- if((dwFilePos % ha->dwBlockSize) != 0)
- {
- // Number of bytes remaining in the buffer
- DWORD dwToCopy;
- DWORD dwLoaded = ha->dwBlockSize;
-
- // Check if data are loaded in the cache
- if(hf != ha->pLastFile || dwBlockPos != ha->dwBlockPos)
- {
- // Load one MPQ block into archive buffer
- dwLoaded = ReadMPQBlocks(hf, dwBlockPos, ha->pbBlockBuffer, ha->dwBlockSize);
- if(dwLoaded == 0)
- return (DWORD)-1;
-
- // Save lastly accessed file and block position for later use
- ha->pLastFile = hf;
- ha->dwBlockPos = dwBlockPos;
- ha->dwBuffPos = dwFilePos % ha->dwBlockSize;
- }
- dwToCopy = dwLoaded - ha->dwBuffPos;
- if(dwToCopy > dwToRead)
- dwToCopy = dwToRead;
-
- // Copy data from block buffer into target buffer
- memcpy(pbBuffer, ha->pbBlockBuffer + ha->dwBuffPos, dwToCopy);
-
- // Update pointers
- dwToRead -= dwToCopy;
- dwBytesRead += dwToCopy;
- pbBuffer += dwToCopy;
- dwBlockPos += ha->dwBlockSize;
- ha->dwBuffPos += dwToCopy;
-
- // If all, return.
- if(dwToRead == 0)
- return dwBytesRead;
- }
-
- // Load the whole ("middle") blocks only if there are more or equal one block
- if(dwToRead > ha->dwBlockSize)
- {
- DWORD dwBlockBytes = dwToRead & ~(ha->dwBlockSize - 1);
-
- dwLoaded = ReadMPQBlocks(hf, dwBlockPos, pbBuffer, dwBlockBytes);
- if(dwLoaded == 0)
- return (DWORD)-1;
-
- // Update pointers
- dwToRead -= dwLoaded;
- dwBytesRead += dwLoaded;
- pbBuffer += dwLoaded;
- dwBlockPos += dwLoaded;
-
- // If all, return.
- if(dwToRead == 0)
- return dwBytesRead;
- }
-
- // Load the terminating block
- if(dwToRead > 0)
- {
- DWORD dwToCopy = ha->dwBlockSize;
-
- // Check if data are loaded in the cache
- if(hf != ha->pLastFile || dwBlockPos != ha->dwBlockPos)
- {
- // Load one MPQ block into archive buffer
- dwToCopy = ReadMPQBlocks(hf, dwBlockPos, ha->pbBlockBuffer, ha->dwBlockSize);
- if(dwToCopy == 0)
- return (DWORD)-1;
-
- // Save lastly accessed file and block position for later use
- ha->pLastFile = hf;
- ha->dwBlockPos = dwBlockPos;
- }
- ha->dwBuffPos = 0;
-
- // Check number of bytes read
- if(dwToCopy > dwToRead)
- dwToCopy = dwToRead;
-
- memcpy(pbBuffer, ha->pbBlockBuffer, dwToCopy);
- dwBytesRead += dwToCopy;
- ha->dwBuffPos = dwToCopy;
- }
-
- // Return what we've read
- return dwBytesRead;
-}
-
-//-----------------------------------------------------------------------------
-// SFileReadFile
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileReadFile(HANDLE hFile, VOID * lpBuffer, DWORD dwToRead, DWORD * pdwRead, LPOVERLAPPED lpOverlapped)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
- DWORD dwBytes = 0; // Number of bytes (for everything)
- int nError = ERROR_SUCCESS;
-
- // Zero the number of bytes read
- if(pdwRead != NULL)
- *pdwRead = 0;
-
- // Check valid parameters
- if(nError == ERROR_SUCCESS)
- {
- if(hf == NULL || lpBuffer == NULL)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // If direct access to the file, use Win32 for reading
- if(nError == ERROR_SUCCESS && hf->hFile != INVALID_HANDLE_VALUE)
- {
- DWORD dwTransferred;
-
- ReadFile(hf->hFile, lpBuffer, dwToRead, &dwTransferred, lpOverlapped);
- if(dwTransferred < dwToRead)
- {
- SetLastError(ERROR_HANDLE_EOF);
- return FALSE;
- }
-
- if(pdwRead != NULL)
- *pdwRead = dwTransferred;
- return TRUE;
- }
-
- // Read all the bytes available in the buffer (If any)
- if(nError == ERROR_SUCCESS)
- {
- if(dwToRead > 0)
- {
- dwBytes = ReadMPQFile(hf, hf->dwFilePos, (BYTE *)lpBuffer, dwToRead);
- if(dwBytes == (DWORD)-1)
- {
- SetLastError(ERROR_CAN_NOT_COMPLETE);
- return FALSE;
- }
- hf->ha->pLastFile = hf;
- hf->dwFilePos += dwBytes;
- }
- if(pdwRead != NULL)
- *pdwRead = dwBytes;
- }
-
- // Check number of bytes read. If not OK, return FALSE.
- if(dwBytes < dwToRead)
- {
- SetLastError(ERROR_HANDLE_EOF);
- return FALSE;
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// SFileGetFilePos
-//
-// Returns position of archive file in the archive (relative to begin of file)
-
-// TODO: Test for archives > 4GB
-DWORD WINAPI SFileGetFilePos(HANDLE hFile, DWORD * pdwFilePosHigh)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
-
- if(pdwFilePosHigh != NULL)
- *pdwFilePosHigh = 0;
-
- if(hf == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return (DWORD)-1;
- }
-
- // If opened as plain file, ...
- if(hf->hFile != INVALID_HANDLE_VALUE)
- return 0;
-
- // If opened from archive, return file size
- if(pdwFilePosHigh != NULL)
- *pdwFilePosHigh = hf->MpqFilePos.HighPart;
- return hf->MpqFilePos.LowPart;
-}
-
-//-----------------------------------------------------------------------------
-// SFileGetFileSize
-
-// TODO: Test for archives > 4GB
-DWORD WINAPI SFileGetFileSize(HANDLE hFile, DWORD * pdwFileSizeHigh)
-{
- TMPQFile * hf = (TMPQFile *)hFile;
-
- if(pdwFileSizeHigh != NULL)
- *pdwFileSizeHigh = 0;
-
- if(hf == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return (DWORD)-1;
- }
-
- // If opened as plain file, ...
- if(hf->hFile != INVALID_HANDLE_VALUE)
- return GetFileSize(hf->hFile, pdwFileSizeHigh);
-
- // If opened from archive, return file size
- return hf->pBlock->dwFSize;
-}
-
-// TODO: Test for archives > 4GB
-DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * pdwFilePosHigh, DWORD dwMethod)
-{
- TMPQArchive * ha;
- TMPQFile * hf = (TMPQFile *)hFile;
-
- if(hf == NULL || (pdwFilePosHigh != NULL && *pdwFilePosHigh != 0))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return (DWORD)-1;
- }
-
- // If opened as plain file, call Win32 API
- if(hf->hFile != INVALID_HANDLE_VALUE)
- return SetFilePointer(hf->hFile, lFilePos, pdwFilePosHigh, dwMethod);
- ha = hf->ha;
-
- switch(dwMethod)
- {
- case FILE_BEGIN:
- // Cannot set pointer before begin of file
- if(-lFilePos > (LONG)hf->dwFilePos)
- hf->dwFilePos = 0;
- else
- hf->dwFilePos = lFilePos;
- break;
-
- case FILE_CURRENT:
- // Cannot set pointer before begin of file
- if(-lFilePos > (LONG)hf->dwFilePos)
- hf->dwFilePos = 0;
- else
- hf->dwFilePos += lFilePos;
- break;
-
- case FILE_END:
- // Cannot set file position before begin of file
- if(-lFilePos >= (LONG)hf->pBlock->dwFSize)
- hf->dwFilePos = 0;
- else
- hf->dwFilePos = hf->pBlock->dwFSize + lFilePos;
- break;
-
- default:
- return ERROR_INVALID_PARAMETER;
- }
-
- if(hf == ha->pLastFile && (hf->dwFilePos & ~(ha->dwBlockSize - 1)) == ha->dwBlockPos)
- ha->dwBuffPos = hf->dwFilePos & (ha->dwBlockSize - 1);
- else
- {
- ha->pLastFile = NULL;
- ha->dwBuffPos = 0;
- }
-
- return hf->dwFilePos;
-}
-
-//-----------------------------------------------------------------------------
-// Tries to retrieve the file name
-
-static TID2Ext id2ext[] =
-{
- {0x1A51504D, "mpq"}, // MPQ archive header ID ('MPQ\x1A')
- {0x46464952, "wav"}, // WAVE header 'RIFF'
- {0x324B4D53, "smk"}, // Old "Smacker Video" files 'SMK2'
- {0x694B4942, "bik"}, // Bink video files (new)
- {0x0801050A, "pcx"}, // PCX images used in Diablo I
- {0x544E4F46, "fnt"}, // Font files used in Diablo II
- {0x6D74683C, "html"}, // HTML '<htm'
- {0x4D54483C, "html"}, // HTML '<HTM
- {0x216F6F57, "tbl"}, // Table files
- {0x31504C42, "blp"}, // BLP textures
- {0x32504C42, "blp"}, // BLP textures (v2)
- {0x584C444D, "mdx"}, // MDX files
- {0x45505954, "pud"}, // Warcraft II maps
- {0x38464947, "gif"}, // GIF images 'GIF8'
- {0x3032444D, "m2"}, // WoW ??? .m2
- {0x43424457, "dbc"}, // ??? .dbc
- {0x47585053, "bls"}, // WoW pixel shaders
- {0, NULL} // Terminator
-};
-
-// TODO: Test for archives > 4GB
-BOOL WINAPI SFileGetFileName(HANDLE hFile, char * szFileName)
-{
- TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle
- char * szExt = "xxx"; // Default extension
- DWORD dwFirstBytes[2]; // The first 4 bytes of the file
- DWORD dwFilePos; // Saved file position
- int nError = ERROR_SUCCESS;
- int i;
-
- // Pre-zero the output buffer
- if(szFileName != NULL)
- *szFileName = 0;
-
- // Check valid parameters
- if(nError == ERROR_SUCCESS)
- {
- if(hf == NULL || szFileName == NULL)
- nError = ERROR_INVALID_PARAMETER;
- }
-
- // If the file name is already filled, return it.
- if(nError == ERROR_SUCCESS && *hf->szFileName != 0)
- {
- if(szFileName != hf->szFileName)
- strcpy(szFileName, hf->szFileName);
- return TRUE;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- if(hf->dwFileIndex == (DWORD)-1)
- nError = ERROR_CAN_NOT_COMPLETE;
- }
-
- // Read the first 8 bytes from the file
- if(nError == ERROR_SUCCESS)
- {
- dwFirstBytes[0] = dwFirstBytes[1] = 0;
- dwFilePos = SFileSetFilePointer(hf, 0, NULL, FILE_CURRENT);
- if(!SFileReadFile(hFile, &dwFirstBytes, sizeof(dwFirstBytes), NULL))
- nError = GetLastError();
- BSWAP_ARRAY32_UNSIGNED(dwFirstBytes, sizeof(dwFirstBytes) / sizeof(DWORD));
- SFileSetFilePointer(hf, dwFilePos, NULL, FILE_BEGIN);
- }
-
- if(nError == ERROR_SUCCESS)
- {
- if((dwFirstBytes[0] & 0x0000FFFF) == ID_EXE)
- szExt = "exe";
- else if(dwFirstBytes[0] == 0x00000006 && dwFirstBytes[1] == 0x00000001)
- szExt = "dc6";
- else
- {
- for(i = 0; id2ext[i].szExt != NULL; i++)
- {
- if(id2ext[i].dwID == dwFirstBytes[0])
- {
- szExt = id2ext[i].szExt;
- break;
- }
- }
- }
-
- // Create the file name
- sprintf(hf->szFileName, "File%08lu.%s", hf->dwFileIndex, szExt);
- if(szFileName != hf->szFileName)
- strcpy(szFileName, hf->szFileName);
- }
- return (nError == ERROR_SUCCESS);
-}
-
-//-----------------------------------------------------------------------------
-// Retrieves an information about an archive or about a file within the archive
-//
-// hMpqOrFile - Handle to an MPQ archive or to a file
-// dwInfoType - Information to obtain
-
-// TODO: Test for archives > 4GB
-DWORD_PTR WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType)
-{
- TMPQArchive * ha = (TMPQArchive *)hMpqOrFile;
- TMPQFile * hf = (TMPQFile *)hMpqOrFile;
- TMPQBlock * pBlockEnd;
- TMPQBlock * pBlock;
- DWORD dwFileCount = 0;
- DWORD dwSeed;
-
- switch(dwInfoType)
- {
- case SFILE_INFO_ARCHIVE_SIZE:
- if(IsValidMpqHandle(ha))
- return ha->pHeader->dwArchiveSize;
- break;
-
- case SFILE_INFO_HASH_TABLE_SIZE: // Size of the hash table
- if(IsValidMpqHandle(ha))
- return ha->pHeader->dwHashTableSize;
- break;
-
- case SFILE_INFO_BLOCK_TABLE_SIZE: // Size of the hash table
- if(IsValidMpqHandle(ha))
- return ha->pHeader->dwBlockTableSize;
- break;
-
- case SFILE_INFO_BLOCK_SIZE:
- if(IsValidMpqHandle(ha))
- return ha->dwBlockSize;
- break;
-
- case SFILE_INFO_HASH_TABLE:
- if(IsValidMpqHandle(ha))
- return (DWORD_PTR)ha->pHashTable;
- break;
-
- case SFILE_INFO_BLOCK_TABLE:
- if(IsValidMpqHandle(ha))
- return (DWORD_PTR)ha->pBlockTable;
- break;
-
- case SFILE_INFO_NUM_FILES:
- if(IsValidMpqHandle(ha))
- {
- pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize;
- for(pBlock = ha->pBlockTable; pBlock < pBlockEnd; pBlock++)
- {
- if(pBlock->dwFlags & MPQ_FILE_EXISTS)
- dwFileCount++;
- }
- return dwFileCount;
- }
- break;
-
- case SFILE_INFO_HASH_INDEX:
- if(IsValidFileHandle(hf))
- return hf->dwHashIndex;
- break;
-
- case SFILE_INFO_CODENAME1:
- if(IsValidFileHandle(hf))
- return hf->pHash->dwName1;
- break;
-
- case SFILE_INFO_CODENAME2:
- if(IsValidFileHandle(hf))
- return hf->pHash->dwName2;
- break;
-
- case SFILE_INFO_LOCALEID:
- if(IsValidFileHandle(hf))
- return hf->pHash->lcLocale;
- break;
-
- case SFILE_INFO_BLOCKINDEX:
- if(IsValidFileHandle(hf))
- return hf->dwFileIndex;
- break;
-
- case SFILE_INFO_FILE_SIZE:
- if(IsValidFileHandle(hf))
- return hf->pBlock->dwFSize;
- break;
-
- case SFILE_INFO_COMPRESSED_SIZE:
- if(IsValidFileHandle(hf))
- return hf->pBlock->dwCSize;
- break;
-
- case SFILE_INFO_FLAGS:
- if(IsValidFileHandle(hf))
- return hf->pBlock->dwFlags;
- break;
-
- case SFILE_INFO_POSITION:
- if(IsValidFileHandle(hf))
- return hf->pBlock->dwFilePos;
- break;
-
- case SFILE_INFO_SEED:
- if(IsValidFileHandle(hf))
- return hf->dwSeed1;
- break;
-
- case SFILE_INFO_SEED_UNFIXED:
- if(IsValidFileHandle(hf))
- {
- dwSeed = hf->dwSeed1;
- if(hf->pBlock->dwFlags & MPQ_FILE_FIXSEED)
- dwSeed = (dwSeed ^ hf->pBlock->dwFSize) - (DWORD)(hf->MpqFilePos.QuadPart - hf->ha->MpqPos.QuadPart);
- return dwSeed;
- }
- break;
- }
-
- // Unknown parameter or invalid handle
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0xFFFFFFFF;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/SListFile.cpp b/contrib/vmap_extractor_v2/stormlib/SListFile.cpp
deleted file mode 100644
index c3723d17dcd..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/SListFile.cpp
+++ /dev/null
@@ -1,561 +0,0 @@
-/*****************************************************************************/
-/* SListFile.cpp Copyright (c) Ladislav Zezula 2004 */
-/*---------------------------------------------------------------------------*/
-/* Description: */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 12.06.04 1.00 Lad The first version of SListFile.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "SCommon.h"
-#include <assert.h>
-
-//-----------------------------------------------------------------------------
-// Listfile entry structure
-
-#define LISTFILE_CACHE_SIZE 0x1000 // Size of one cache element
-#define NO_MORE_CHARACTERS 256
-#define HASH_TABLE_SIZE 31 // Initial hash table size (should be a prime number)
-
-// TODO: Check on x64 !!!
-#define LISTFILE_ENTRY_DELETED (DWORD_PTR)(-2)
-#define LISTFILE_ENTRY_FREE (DWORD_PTR)(-1)
-
-struct TListFileCache
-{
- HANDLE hFile; // Stormlib file handle
- char * szMask; // File mask
- DWORD dwFileSize; // Total size of the cached file
- DWORD dwBuffSize; // File of the cache
- DWORD dwFilePos; // Position of the cache in the file
- BYTE * pBegin; // The begin of the listfile cache
- BYTE * pPos;
- BYTE * pEnd; // The last character in the file cache
-
- BYTE Buffer[1]; // Listfile cache itself
-};
-
-//-----------------------------------------------------------------------------
-// Local functions (cache)
-
-// Reloads the cache. Returns number of characters
-// that has been loaded into the cache.
-static int ReloadCache(TListFileCache * pCache)
-{
- // Check if there is enough characters in the cache
- // If not, we have to reload the next block
- if(pCache->pPos >= pCache->pEnd)
- {
- // If the cache is already at the end, do nothing more
- if((pCache->dwFilePos + pCache->dwBuffSize) >= pCache->dwFileSize)
- return 0;
-
- pCache->dwFilePos += pCache->dwBuffSize;
- SFileReadFile(pCache->hFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL);
- if(pCache->dwBuffSize == 0)
- return 0;
-
- // Set the buffer pointers
- pCache->pBegin =
- pCache->pPos = &pCache->Buffer[0];
- pCache->pEnd = pCache->pBegin + pCache->dwBuffSize;
- }
-
- return pCache->dwBuffSize;
-}
-
-static size_t ReadLine(TListFileCache * pCache, char * szLine, int nMaxChars)
-{
- char * szLineBegin = szLine;
- char * szLineEnd = szLine + nMaxChars - 1;
-
-__BeginLoading:
-
- // Skip newlines, spaces, tabs and another non-printable stuff
- while(pCache->pPos < pCache->pEnd && *pCache->pPos <= 0x20)
- pCache->pPos++;
-
- // Copy the remaining characters
- while(pCache->pPos < pCache->pEnd && szLine < szLineEnd)
- {
- // If we have found a newline, stop loading
- if(*pCache->pPos == 0x0D || *pCache->pPos == 0x0A)
- break;
-
- *szLine++ = *pCache->pPos++;
- }
-
- // If we now need to reload the cache, do it
- if(pCache->pPos == pCache->pEnd)
- {
- if(ReloadCache(pCache) > 0)
- goto __BeginLoading;
- }
-
- *szLine = 0;
- return (szLine - szLineBegin);
-}
-
-//-----------------------------------------------------------------------------
-// Local functions (listfile nodes)
-
-// This function creates the name for the listfile.
-// the file will be created under unique name in the temporary directory
-static void GetListFileName(TMPQArchive * /* ha */, char * szListFile)
-{
- char szTemp[MAX_PATH];
-
- // Create temporary file name int TEMP directory
- GetTempPath(sizeof(szTemp)-1, szTemp);
- GetTempFileName(szTemp, LISTFILE_NAME, 0, szListFile);
-}
-
-// Creates new listfile. The listfile is an array of TListFileNode
-// structures. The size of the array is the same like the hash table size,
-// the ordering is the same too (listfile item index is the same like
-// the index in the MPQ hash table)
-
-int SListFileCreateListFile(TMPQArchive * ha)
-{
- DWORD dwItems = ha->pHeader->dwHashTableSize;
-
- // The listfile should be NULL now
- assert(ha->pListFile == NULL);
-
- ha->pListFile = ALLOCMEM(TFileNode *, dwItems);
- if(ha->pListFile == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- memset(ha->pListFile, 0xFF, dwItems * sizeof(TFileNode *));
- return ERROR_SUCCESS;
-}
-
-// Adds a filename into the listfile. If the file name is already there,
-// does nothing.
-int SListFileAddNode(TMPQArchive * ha, const char * szFileName)
-{
- TFileNode * pNode = NULL;
- TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- TMPQHash * pHash0 = GetHashEntry(ha, szFileName);
- TMPQHash * pHash = pHash0;
- DWORD dwHashIndex = 0;
- size_t nLength; // File name lentgth
- DWORD dwName1;
- DWORD dwName2;
-
- // If the file does not exist within the MPQ, do nothing
- if(pHash == NULL)
- return ERROR_SUCCESS;
-
- // If the listfile entry already exists, do nothing
- dwHashIndex = (DWORD)(pHash - ha->pHashTable);
- dwName1 = pHash->dwName1;
- dwName2 = pHash->dwName2;
- if((DWORD_PTR)ha->pListFile[dwHashIndex] <= LISTFILE_ENTRY_DELETED)
- return ERROR_SUCCESS;
-
- // Create the listfile node and insert it into the listfile table
- nLength = strlen(szFileName);
- pNode = (TFileNode *)ALLOCMEM(char, sizeof(TFileNode) + nLength);
- pNode->dwRefCount = 0;
- pNode->nLength = nLength;
- strcpy(pNode->szFileName, szFileName);
-
- // Fill the nodes for all language versions
- while(pHash->dwBlockIndex < LISTFILE_ENTRY_DELETED)
- {
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2)
- {
- pNode->dwRefCount++;
- ha->pListFile[pHash - ha->pHashTable] = pNode;
- }
-
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pHash0)
- break;
- }
-
- return ERROR_SUCCESS;
-}
-
-// Removes a filename from the listfile.
-// If the name is not there, does nothing
-int SListFileRemoveNode(TMPQArchive * ha, const char * szFileName)
-{
- TFileNode * pNode = NULL;
- TMPQHash * pHash = GetHashEntry(ha, szFileName);
- size_t nHashIndex = 0;
-
- if(pHash != NULL)
- {
- nHashIndex = pHash - ha->pHashTable;
- pNode = ha->pListFile[nHashIndex];
- ha->pListFile[nHashIndex] = (TFileNode *)LISTFILE_ENTRY_DELETED;
-
- // If the reference count has reached zero, do nothing
- if(--pNode->dwRefCount == 0)
- FREEMEM(pNode);
- }
- return ERROR_SUCCESS;
-}
-
-
-// Renames a node. We will not deal with the renaming, we'll simply
-// remove the old node and insert the new one.
-// TODO: Test for archives > 4GB
-int SListFileRenameNode(TMPQArchive * ha, const char * szOldFileName, const char * szNewFileName)
-{
- SListFileRemoveNode(ha, szOldFileName);
- return SListFileAddNode(ha, szNewFileName);
-}
-
-// TODO: Test for archives > 4GB
-int SListFileFreeListFile(TMPQArchive * ha)
-{
- if(ha->pListFile != NULL)
- {
- for(DWORD i = 0; i < ha->pHeader->dwHashTableSize; i++)
- {
- TFileNode * pNode = ha->pListFile[i];
-
- if((DWORD_PTR)pNode < LISTFILE_ENTRY_FREE)
- {
- if(--pNode->dwRefCount == 0)
- {
- FREEMEM(pNode);
- ha->pListFile[i] = (TFileNode *)LISTFILE_ENTRY_FREE;
- }
- }
- }
-
- FREEMEM(ha->pListFile);
- ha->pListFile = NULL;
- }
-
- return ERROR_SUCCESS;
-}
-
-// Saves the whole listfile into the MPQ.
-// TODO: Test for archives > 4GB
-int SListFileSaveToMpq(TMPQArchive * ha)
-{
- TFileNode * pNode = NULL;
- TMPQHash * pHashEnd = NULL;
- TMPQHash * pHash0 = NULL;
- TMPQHash * pHash = NULL;
- HANDLE hFile = INVALID_HANDLE_VALUE;
- char szListFile[MAX_PATH];
- char szBuffer[MAX_PATH+4];
- DWORD dwTransferred;
- size_t nLength = 0;
- DWORD dwName1 = 0;
- DWORD dwName2 = 0;
- LCID lcSave = lcLocale;
- int nError = ERROR_SUCCESS;
-
- // If no listfile, do nothing
- if(ha->pListFile == NULL)
- return ERROR_SUCCESS;
-
- // Create the local listfile
- if(nError == ERROR_SUCCESS)
- {
- GetListFileName(ha, szListFile);
- hFile = CreateFile(szListFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- nError = GetLastError();
- }
-
- // Find the hash entry corresponding to listfile
- pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
- pHash0 = pHash = GetHashEntry(ha, 0);
- if(pHash == NULL)
- pHash0 = pHash = ha->pHashTable;
-
- // Save the file
- if(nError == ERROR_SUCCESS)
- {
- for(;;)
- {
- if(pHash->dwName1 != dwName1 && pHash->dwName2 != dwName2 && pHash->dwBlockIndex < LISTFILE_ENTRY_DELETED)
- {
- dwName1 = pHash->dwName1;
- dwName2 = pHash->dwName2;
- pNode = ha->pListFile[pHash - ha->pHashTable];
-
- if((DWORD_PTR)pNode < LISTFILE_ENTRY_DELETED)
- {
- memcpy(szBuffer, pNode->szFileName, pNode->nLength);
- szBuffer[pNode->nLength + 0] = 0x0D;
- szBuffer[pNode->nLength + 1] = 0x0A;
- WriteFile(hFile, szBuffer, (DWORD)(pNode->nLength + 2), &dwTransferred, NULL);
- }
- }
-
- if(++pHash >= pHashEnd)
- pHash = ha->pHashTable;
- if(pHash == pHash0)
- break;
- }
-
- // Write the listfile name (if not already there)
- if(GetHashEntry(ha, LISTFILE_NAME) == NULL)
- {
- nLength = strlen(LISTFILE_NAME);
- memcpy(szBuffer, LISTFILE_NAME, nLength);
- szBuffer[nLength + 0] = 0x0D;
- szBuffer[nLength + 1] = 0x0A;
- WriteFile(hFile, szBuffer, (DWORD)(nLength + 2), &dwTransferred, NULL);
- }
-
- // Add the listfile into the archive.
- SFileSetLocale(LANG_NEUTRAL);
- nError = AddFileToArchive(ha, hFile, LISTFILE_NAME, MPQ_FILE_COMPRESS_PKWARE | MPQ_FILE_ENCRYPTED | MPQ_FILE_REPLACEEXISTING, 0, SFILE_TYPE_DATA, NULL);
- }
-
- // Close the temporary file. This will delete it too.
- if(hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
-
- lcLocale = lcSave;
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// File functions
-
-// Adds a listfile into the MPQ archive.
-// Note that the function does not remove the
-// TODO: Test for archives > 4GB
-int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile)
-{
- TListFileCache * pCache = NULL;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- HANDLE hListFile = NULL;
- char szFileName[MAX_PATH + 1];
- DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
- DWORD dwCacheSize = 0;
- DWORD dwFileSize = 0;
- size_t nLength = 0;
- int nError = ERROR_SUCCESS;
-
- // If the szListFile is NULL, it means we have to open internal listfile
- if(szListFile == NULL)
- {
- szListFile = LISTFILE_NAME;
- dwSearchScope = SFILE_OPEN_FROM_MPQ;
- }
-
- // Open the local/internal listfile
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileOpenFileEx((HANDLE)ha, szListFile, dwSearchScope, &hListFile))
- nError = GetLastError();
- }
-
- if(nError == ERROR_SUCCESS)
- {
- dwCacheSize =
- dwFileSize = SFileGetFileSize(hListFile, NULL);
-
- // Try to allocate memory for the complete file. If it fails,
- // load the part of the file
- pCache = (TListFileCache *)ALLOCMEM(char, (sizeof(TListFileCache) + dwCacheSize));
- if(pCache == NULL)
- {
- dwCacheSize = LISTFILE_CACHE_SIZE;
- pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize);
- }
-
- if(pCache == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- // Initialize the file cache
- memset(pCache, 0, sizeof(TListFileCache));
- pCache->hFile = hListFile;
- pCache->dwFileSize = dwFileSize;
- pCache->dwBuffSize = dwCacheSize;
- pCache->dwFilePos = 0;
-
- // Fill the cache
- SFileReadFile(hListFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL);
-
- // Initialize the pointers
- pCache->pBegin =
- pCache->pPos = &pCache->Buffer[0];
- pCache->pEnd = pCache->pBegin + pCache->dwBuffSize;
-
- // Load the node tree
- while((nLength = ReadLine(pCache, szFileName, sizeof(szFileName) - 1)) > 0)
- SListFileAddNode(ha, szFileName);
-
- // Add well-known names
- // Sometimes, they are not in listfile, but they exist in the archive
- SListFileAddNode(ha, LISTFILE_NAME);
- SListFileAddNode(ha, SIGNATURE_NAME);
- SListFileAddNode(ha, ATTRIBUTES_NAME);
- }
-
- // Cleanup & exit
- if(pCache != NULL)
- SListFileFindClose((HANDLE)pCache);
- return nError;
-}
-
-//-----------------------------------------------------------------------------
-// Passing through the listfile
-
-// TODO: Test for archives > 4GB
-HANDLE SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
-{
- TListFileCache * pCache = NULL;
- TMPQArchive * ha = (TMPQArchive *)hMpq;
- HANDLE hListFile = NULL;
- DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
- DWORD dwCacheSize = 0;
- DWORD dwFileSize = 0;
- size_t nLength = 0;
- int nError = ERROR_SUCCESS;
-
- // Initialize the structure with zeros
- memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
-
- // If the szListFile is NULL, it means we have to open internal listfile
- if(szListFile == NULL)
- {
- szListFile = LISTFILE_NAME;
- dwSearchScope = SFILE_OPEN_FROM_MPQ;
- }
-
- // Open the local/internal listfile
- if(nError == ERROR_SUCCESS)
- {
- if(!SFileOpenFileEx((HANDLE)ha, szListFile, dwSearchScope, &hListFile))
- nError = GetLastError();
- }
-
- if(nError == ERROR_SUCCESS)
- {
- dwCacheSize =
- dwFileSize = SFileGetFileSize(hListFile, NULL);
-
- // Try to allocate memory for the complete file. If it fails,
- // load the part of the file
- pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize);
- if(pCache == NULL)
- {
- dwCacheSize = LISTFILE_CACHE_SIZE;
- pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize);
- }
-
- if(pCache == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- if(nError == ERROR_SUCCESS)
- {
- // Initialize the file cache
- memset(pCache, 0, sizeof(TListFileCache));
- pCache->hFile = hListFile;
- pCache->dwFileSize = dwFileSize;
- pCache->dwBuffSize = dwCacheSize;
- pCache->dwFilePos = 0;
- if(szMask != NULL)
- {
- pCache->szMask = ALLOCMEM(char, strlen(szMask) + 1);
- strcpy(pCache->szMask, szMask);
- }
-
- // Fill the cache
- SFileReadFile(hListFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL);
-
- // Initialize the pointers
- pCache->pBegin =
- pCache->pPos = &pCache->Buffer[0];
- pCache->pEnd = pCache->pBegin + pCache->dwBuffSize;
-
- for(;;)
- {
- // Read the (next) line
- nLength = ReadLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
- if(nLength == 0)
- {
- nError = ERROR_NO_MORE_FILES;
- break;
- }
-
- // If some mask entered, check it
- if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
- break;
- }
- }
-
- // Cleanup & exit
- if(nError != ERROR_SUCCESS)
- {
- memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
- SListFileFindClose((HANDLE)pCache);
- pCache = NULL;
-
- SetLastError(nError);
- }
- return (HANDLE)pCache;
-}
-
-// TODO: Test for archives > 4GB
-BOOL SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
-{
- TListFileCache * pCache = (TListFileCache *)hFind;
- size_t nLength;
- BOOL bResult = FALSE;
- int nError = ERROR_SUCCESS;
-
- for(;;)
- {
- // Read the (next) line
- nLength = ReadLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
- if(nLength == 0)
- {
- nError = ERROR_NO_MORE_FILES;
- break;
- }
-
- // If some mask entered, check it
- if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
- {
- bResult = TRUE;
- break;
- }
- }
-
- if(nError != ERROR_SUCCESS)
- SetLastError(nError);
- return bResult;
-}
-
-// TODO: Test for archives > 4GB
-BOOL SListFileFindClose(HANDLE hFind)
-{
- TListFileCache * pCache = (TListFileCache *)hFind;
-
- if(pCache != NULL)
- {
- if(pCache->hFile != NULL)
- SFileCloseFile(pCache->hFile);
- if(pCache->szMask != NULL)
- FREEMEM(pCache->szMask);
-
- FREEMEM(pCache);
- return TRUE;
- }
-
- return FALSE;
-}
-
diff --git a/contrib/vmap_extractor_v2/stormlib/StormDll.h b/contrib/vmap_extractor_v2/stormlib/StormDll.h
deleted file mode 100644
index 6d67820a22f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/StormDll.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*****************************************************************************/
-/* Storm.h Copyright Justin Olbrantz(Quantam) 2000 */
-/*---------------------------------------------------------------------------*/
-/* Storm Interface Library v1.0 for Windows */
-/* */
-/* Author : Justin Olbrantz(Quantam) */
-/* E-mail : omega@dragonfire.net */
-/* WWW : www.campaigncreations.com/starcraft/mpq2k/inside_mopaq/ */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.00 1.00 Qua The first version of Storm.h */
-/* 11.04.03 1.00 Lad Added some functions */
-/*****************************************************************************/
-
-// We need the Windows data types for the Storm prototypes
-#include <windows.h>
-
-#ifndef __STORM_H__
-#define __STORM_H__
-
-// Somethimes is necessary to change the function names so they
-// will not conflict with other MPQ tools.
-#ifdef STORM_ALTERNATE_NAMES
- #define SFILE(Name) Storm##Name
- #define SCOMP(Name) Storm##Name
-#else
- #define SFILE(Name) SFile##Name
- #define SCOMP(Name) SComp##Name
-#endif
-
-
-// Just in case anyone is still using C out there
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Storm file function prototypes
-BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ);
-BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ);
-BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength);
-BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile);
-BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile);
-BOOL WINAPI SFILE(CloseFile)(HANDLE hFile);
-DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh);
-BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ);
-BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength);
-DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod);
-BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped);
-LCID WINAPI SFILE(SetLocale)(LCID nNewLocale);
-BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength);
-BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath);
-
-// Storm (de)compression functions
-BOOL WINAPI SCOMP(Compress) (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel);
-BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength);
-
-
-#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP)
-#pragma comment(lib, "Storm.lib") // Force linking Storm.lib and thus Storm.dll
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __STORM_H__
diff --git a/contrib/vmap_extractor_v2/stormlib/StormLib.h b/contrib/vmap_extractor_v2/stormlib/StormLib.h
deleted file mode 100644
index eeb8daa6468..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/StormLib.h
+++ /dev/null
@@ -1,579 +0,0 @@
-/*****************************************************************************/
-/* StormLib.h Copyright (c) Ladislav Zezula 1999-2005 */
-/*---------------------------------------------------------------------------*/
-/* StormLib library v 5.00 */
-/* */
-/* Author : Ladislav Zezula */
-/* E-mail : ladik@zezula.net */
-/* WWW : http://www.zezula.net */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.99 1.00 Lad Created */
-/* 24.03.03 2.50 Lad Version 2.50 */
-/* 02.04.03 3.00 Lad Version 3.00 with compression */
-/* 11.04.03 3.01 Lad Renamed to StormLib.h for compatibility with */
-/* original headers for Storm.dll */
-/* 10.05.03 3.02 Lad Added Pkware DCL compression */
-/* 26.05.03 4.00 Lad Completed all compressions */
-/* 18.06.03 4.01 Lad Added SFileSetFileLocale */
-/* Added SFileExtractFile */
-/* 26.07.03 4.02 Lad Implemented nameless rename and delete */
-/* 26.07.03 4.03 Lad Added support for protected MPQs */
-/* 28.08.03 4.10 Lad Fixed bugs that caused StormLib incorrectly work */
-/* with Diablo I savegames and with files having full */
-/* hash table */
-/* 08.12.03 4.11 DCH Fixed bug in reading file block larger than 0x1000 */
-/* on certain files. */
-/* Fixed bug in AddFile with MPQ_FILE_REPLACE_EXISTING */
-/* (Thanx Daniel Chiamarello, dchiamarello@madvawes.com)*/
-/* 21.12.03 4.50 Lad Completed port for Mac */
-/* Fixed bug in compacting (if fsize is mul of 0x1000) */
-/* Fixed bug in SCompCompress */
-/* 27.05.04 4.51 Lad Changed memory management from new/delete to our */
-/* own macros */
-/* 22.06.04 4.60 Lad Optimized search. Support for multiple listfiles. */
-/* 30.09.04 4.61 Lad Fixed some bugs (Aaargh !!!) */
-/* Correctly works if HashTableSize > BlockTableSize */
-/* 29.12.04 4.70 Lad Fixed compatibility problem with MPQs from WoW */
-/* 14.07.05 5.00 Lad Added the BZLIB compression support */
-/* Added suport of files stored as single unit */
-/* 17.04.06 5.01 Lad Converted to MS Visual Studio 8.0 */
-/* Fixed issue with protected Warcraft 3 protected maps */
-/* 15.05.06 5.02 Lad Fixed issue with WoW 1.10+ */
-/* 07.09.06 5.10 Lad Fixed processing files longer than 2GB */
-/* 22.11.06 6.00 Lad Support for MPQ archives V2 */
-/*****************************************************************************/
-
-#ifndef __STORMLIB_H_
-#define __STORMLIB_H_
-
-#include "StormPort.h"
-
-//-----------------------------------------------------------------------------
-// Use the apropriate library
-//
-// The library type is encoded in the library name as the following
-// StormLibXYZ.lib
-//
-// X - D for Debug version, R for Release version
-// Y - A for ANSI version, U for Unicode version (Unicode version does not exist yet)
-// Z - S for static C library, D for multithreaded DLL C-library
-//
-
-#if defined(_MSC_VER) && !defined (__STORMLIB_SELF__)
- #ifdef _DEBUG // DEBUG VERSIONS
- #ifdef _DLL
- #pragma comment(lib, "StormLibDAD.lib") // Debug Ansi Dynamic version
- #else
- #pragma comment(lib, "StormLibDAS.lib") // Debug Ansi Static version
- #endif
- #else // RELEASE VERSIONS
- #ifdef _DLL
- #pragma comment(lib, "StormLibRAD.lib") // Release Ansi Dynamic version
- #else
- #pragma comment(lib, "StormLibRAS.lib") // Release Ansi Static version
- #endif
- #endif
-#endif
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A')
-#define ID_MPQ_SHUNT 0x1B51504D // MPQ shunt entry ('MPQ\x1B')
-
-#define ERROR_AVI_FILE 10000 // No MPQ file, but AVI file.
-
-// Values for SFileCreateArchiveEx
-#define HASH_TABLE_SIZE_MIN 0x00002
-#define HASH_TABLE_SIZE_MAX 0x40000
-
-#define HASH_ENTRY_DELETED 0xFFFFFFFE // Block index for deleted hash entry
-#define HASH_ENTRY_FREE 0xFFFFFFFF // Block index for free hash entry
-
-// Values for SFileOpenArchive
-#define SFILE_OPEN_HARD_DISK_FILE 2 // Open the archive on HDD
-#define SFILE_OPEN_CDROM_FILE 3 // Open the archive only if it is on CDROM
-
-// Values for SFileOpenFile
-#define SFILE_OPEN_FROM_MPQ 0 // Open the file from the MPQ archive
-#define SFILE_OPEN_BY_INDEX 1 // The 'szFileName' parameter is actually the file index
-#define SFILE_OPEN_LOCAL_FILE (DWORD)-1 // Open the file from the MPQ archive
-
-// Flags for TMPQArchive::dwFlags
-#define MPQ_FLAG_CHANGED 0x00000001 // If set, the MPQ has been changed
-#define MPQ_FLAG_PROTECTED 0x00000002 // Set on protected MPQs (like W3M maps)
-
-// Flags for SFileAddFile
-#define MPQ_FILE_COMPRESS_PKWARE 0x00000100 // Compression made by PKWARE Data Compression Library
-#define MPQ_FILE_COMPRESS_MULTI 0x00000200 // Multiple compressions
-#define MPQ_FILE_COMPRESSED 0x0000FF00 // File is compressed
-#define MPQ_FILE_ENCRYPTED 0x00010000 // Indicates whether file is encrypted
-#define MPQ_FILE_FIXSEED 0x00020000 // File decrypt seed has to be fixed
-#define MPQ_FILE_SINGLE_UNIT 0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam)
-#define MPQ_FILE_DUMMY_FILE 0x02000000 // The file is only 1 byte long and its name is a hash
-#define MPQ_FILE_HAS_EXTRA 0x04000000 // The file has extra data appended after regular data.
- // Must be with compressed files only
-#define MPQ_FILE_EXISTS 0x80000000 // Set if file exists, reset when the file was deleted
-#define MPQ_FILE_REPLACEEXISTING 0x80000000 // Replace when the file exist (SFileAddFile)
-
-#define MPQ_FILE_VALID_FLAGS (MPQ_FILE_COMPRESS_PKWARE | \
- MPQ_FILE_COMPRESS_MULTI | \
- MPQ_FILE_ENCRYPTED | \
- MPQ_FILE_FIXSEED | \
- MPQ_FILE_SINGLE_UNIT | \
- MPQ_FILE_DUMMY_FILE | \
- MPQ_FILE_HAS_EXTRA | \
- MPQ_FILE_EXISTS)
-
-// Compression types for multilpe compressions
-#define MPQ_COMPRESSION_HUFFMANN 0x01 // Huffmann compression (used on WAVE files only)
-#define MPQ_COMPRESSION_ZLIB 0x02 // ZLIB compression
-#define MPQ_COMPRESSION_PKWARE 0x08 // PKWARE DCL compression
-#define MPQ_COMPRESSION_BZIP2 0x10 // BZIP2 compression
-#define MPQ_COMPRESSION_WAVE_MONO 0x40 //
-#define MPQ_COMPRESSION_WAVE_STEREO 0x80 //
-
-
-// Constants for SFileAddWave
-#define MPQ_WAVE_QUALITY_HIGH 0 // Best quality, the worst compression
-#define MPQ_WAVE_QUALITY_MEDIUM 1 // Medium quality, medium compression
-#define MPQ_WAVE_QUALITY_LOW 2 // Low quality, the best compression
-
-// Constants for SFileGetFileInfo
-#define SFILE_INFO_ARCHIVE_SIZE 1 // MPQ size (value from header)
-#define SFILE_INFO_HASH_TABLE_SIZE 2 // Size of hash table, in entries
-#define SFILE_INFO_BLOCK_TABLE_SIZE 3 // Number of entries in the block table
-#define SFILE_INFO_BLOCK_SIZE 4 // Size of file block (in bytes)
-#define SFILE_INFO_HASH_TABLE 5 // Pointer to Hash table (TMPQHash *)
-#define SFILE_INFO_BLOCK_TABLE 6 // Pointer to Block Table (TMPQBlock *)
-#define SFILE_INFO_NUM_FILES 7 // Real number of files within archive
-//------
-#define SFILE_INFO_HASH_INDEX 8 // Hash index of file in MPQ
-#define SFILE_INFO_CODENAME1 9 // The first codename of the file
-#define SFILE_INFO_CODENAME2 10 // The second codename of the file
-#define SFILE_INFO_LOCALEID 11 // Locale ID of file in MPQ
-#define SFILE_INFO_BLOCKINDEX 12 // Index to Block Table
-#define SFILE_INFO_FILE_SIZE 13 // Original file size
-#define SFILE_INFO_COMPRESSED_SIZE 14 // Compressed file size
-#define SFILE_INFO_FLAGS 15 // File flags
-#define SFILE_INFO_POSITION 16 // File position within archive
-#define SFILE_INFO_SEED 17 // File decryption seed
-#define SFILE_INFO_SEED_UNFIXED 18 // Decryption seed not fixed to file pos and size
-
-// Values for compact callback
-#define CCB_CHECKING_FILES 1 // Checking archive (dwParam1 = current, dwParam2 = total)
-#define CCB_CHECKING_HASH_TABLE 2 // Checking hash table (dwParam1 = current, dwParam2 = total)
-#define CCB_COPYING_NON_MPQ_DATA 3 // Copying non-MPQ data: No params used
-#define CCB_COMPACTING_FILES 4 // Compacting archive (dwParam1 = current, dwParam2 = total)
-#define CCB_CLOSING_ARCHIVE 5 // Closing archive: No params used
-
-#define LISTFILE_NAME "(listfile)" // Name of internal listfile
-#define SIGNATURE_NAME "(signature)" // Name of internal signature
-#define ATTRIBUTES_NAME "(attributes)" // Name of internal attributes file
-
-#define STORMLIB_VERSION (0x0600) // Current version of StormLib
-
-#define MPQ_FORMAT_VERSION_1 0 // Up to The Burning Crusade
-#define MPQ_FORMAT_VERSION_2 1 // The Burning Crusade and newer,
-
-// Flags for SFileOpenArchiveEx
-#define MPQ_OPEN_NO_LISTFILE 0x00000001 // Don't add the internal listfile
-
-// supports archives with size > 4 GB
-// Additional flags for SFileCreateArchiveEx
-#define MPQ_CREATE_ARCHIVE_V1 0x00000000 // Creates archive with size up to 4GB
-#define MPQ_CREATE_ARCHIVE_V2 0x00010000 // Creates archive larger than 4 GB
-
-//-----------------------------------------------------------------------------
-// Structures
-
-#if (defined(WIN32) || defined(WIN64))
-#include <pshpack1.h>
-#else
-#pragma pack(1)
-#endif
-
-struct TMPQFile;
-
-struct TMPQShunt
-{
- // The ID_MPQ_SHUNT ('MPQ\x1B') signature
- DWORD dwID;
-
- DWORD dwUnknown;
-
- // Position of the MPQ header, relative to the begin of the shunt
- DWORD dwHeaderPos;
-};
-
-
-// MPQ file header
-struct TMPQHeader
-{
- // The ID_MPQ ('MPQ\x1A') signature
- DWORD dwID;
-
- // Size of the archive header
- DWORD dwHeaderSize;
-
- // Size of MPQ archive
- // This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive
- // is calculated as the size from the beginning of the archive to the end of the hash table,
- // block table, or extended block table (whichever is largest).
- DWORD dwArchiveSize;
-
- // 0 = Original format
- // 1 = Extended format (The Burning Crusade and newer)
- USHORT wFormatVersion;
-
- // Power of two exponent specifying the number of 512-byte disk sectors in each logical sector
- // in the archive. The size of each logical sector in the archive is 512 * 2^SectorSizeShift.
- // Bugs in the Storm library dictate that this should always be 3 (4096 byte sectors).
- USHORT wBlockSize;
-
- // Offset to the beginning of the hash table, relative to the beginning of the archive.
- DWORD dwHashTablePos;
-
- // Offset to the beginning of the block table, relative to the beginning of the archive.
- DWORD dwBlockTablePos;
-
- // Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for
- // the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
- DWORD dwHashTableSize;
-
- // Number of entries in the block table
- DWORD dwBlockTableSize;
-};
-
-
-// Extended MPQ file header. Valid only if wFormatVersion is 1 or higher
-struct TMPQHeader2 : public TMPQHeader
-{
- // Offset to the beginning of the extended block table, relative to the beginning of the archive.
- LARGE_INTEGER ExtBlockTablePos;
-
- // High 16 bits of the hash table offset for large archives.
- USHORT wHashTablePosHigh;
-
- // High 16 bits of the block table offset for large archives.
- USHORT wBlockTablePosHigh;
-};
-
-
-// Hash entry. All files in the archive are searched by their hashes.
-struct TMPQHash
-{
- // The hash of the file path, using method A.
- DWORD dwName1;
-
- // The hash of the file path, using method B.
- DWORD dwName2;
-
-#ifdef PLATFORM_LITTLE_ENDIAN
-
- // The language of the file. This is a Windows LANGID data type, and uses the same values.
- // 0 indicates the default language (American English), or that the file is language-neutral.
- USHORT lcLocale;
-
- // The platform the file is used for. 0 indicates the default platform.
- // No other values have been observed.
- USHORT wPlatform;
-
-#else
-
- USHORT wPlatform;
- USHORT lcLocale;
-
-#endif
-
- // If the hash table entry is valid, this is the index into the block table of the file.
- // Otherwise, one of the following two values:
- // - FFFFFFFFh: Hash table entry is empty, and has always been empty.
- // Terminates searches for a given file.
- // - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
- // Does not terminate searches for a given file.
- DWORD dwBlockIndex;
-};
-
-
-// File description block contains informations about the file
-struct TMPQBlock
-{
- // Offset of the beginning of the block, relative to the beginning of the archive.
- DWORD dwFilePos;
-
- // Compressed file size
- DWORD dwCSize;
-
- // Only valid if the block is a file; otherwise meaningless, and should be 0.
- // If the file is compressed, this is the size of the uncompressed file data.
- DWORD dwFSize;
-
- // Flags for the file. See MPQ_FILE_XXXX constants
- DWORD dwFlags;
-};
-
-
-// The extended block table was added to support archives larger than 4 gigabytes (2^32 bytes).
-// The table contains the upper bits of the archive offsets for each block in the block table.
-// It is simply an array of int16s, which become bits 32-47 of the archive offsets for each block,
-// with bits 48-63 being zero. Individual blocks in the archive are still limited to 4 gigabytes
-// in size. This table is only present in Burning Crusade format archives that exceed 4 gigabytes size.
-struct TMPQBlockEx
-{
- USHORT wFilePosHigh;
-};
-
-
-struct TFileNode
-{
- DWORD dwRefCount; // Number of references
- // There can be more files that have the same name.
- // (e.g. multiple language files). We don't want to
- // have an entry for each of them, so the entries will be referenced.
- // When a number of node references reaches zero,
- // the node will be deleted
-
- size_t nLength; // File name length
- char szFileName[1]; // File name, variable length
-};
-
-#if (defined(WIN32) || defined(WIN64))
-#include <poppack.h>
-#else
-#pragma options align=reset
-#endif
-
-// Archive handle structure. Note that it does not agree with Storm.dll's structure.
-struct TMPQArchive
-{
-// TMPQArchive * pNext; // Next archive (used by Storm.dll only)
-// TMPQArchive * pPrev; // Previous archive (used by Storm.dll only)
- char szFileName[MAX_PATH]; // Opened archive file name
- HANDLE hFile; // File handle
- DWORD dwPriority; // Priority of the archive
- LARGE_INTEGER ShuntPos; // Position of MPQShunt (only valid if a shunt is present)
- LARGE_INTEGER MpqPos; // MPQ position in the file, relative to the begin of the file
- LARGE_INTEGER MpqSize; // Size of MPQ archive
- LARGE_INTEGER HashTablePos; // Offset of the hast table in the MPQ, relative to the begin of the file
- LARGE_INTEGER BlockTablePos; // Offset of the hast table in the MPQ, relative to the begin
- LARGE_INTEGER ExtBlockTablePos; // Offset of the extended block table, relative to the begin
- LARGE_INTEGER FilePointer; // Current position in the file (relative to begin of the file)
-
- TMPQFile * pLastFile; // Recently read file
- DWORD dwBlockPos; // Position of loaded block in the file
- DWORD dwBlockSize; // Size of file block
- BYTE * pbBlockBuffer; // Buffer (cache) for file block
- DWORD dwBuffPos; // Position in block buffer
- TMPQShunt * pShunt; // MPQ shunt (NULL if not present in the file)
- TMPQHeader2 * pHeader; // MPQ file header
- TMPQHash * pHashTable; // Hash table
- TMPQBlock * pBlockTable; // Block table
- TMPQBlockEx * pExtBlockTable; // Extended block table
-
- TMPQShunt Shunt; // MPQ shunt. Valid only when ID_MPQ_SHUNT has been found
- TMPQHeader2 Header; // MPQ header
-
- // Non-Storm.dll members
- TFileNode ** pListFile; // File name array
-// HANDLE hListFile; // Handle to temporary listfile (when open with write access)
- DWORD dwFlags; // See MPQ_FLAG_XXXXX
-// BOOL bChanged; // TRUE if the archive was changed since open.
-// BOOL bProtected; // TRUE if the archive is protected by somehow
-};
-
-
-// File handle structure. Note that it does not agree with Storm.dll structures
-struct TMPQFile
-{
- HANDLE hFile; // File handle
- TMPQArchive * ha; // Archive handle
- TMPQHash * pHash; // Hash table entry
- TMPQBlockEx * pBlockEx; // Pointer to extended file block entry
- TMPQBlock * pBlock; // File block pointer
- DWORD dwSeed1; // Seed used for file decrypt
- DWORD dwFilePos; // Current file position
- LARGE_INTEGER MpqFilePos; // Position of the file data in MPQ archive
- // (relative to file begin)
-
- DWORD * pdwBlockPos; // Position of each file block (only for compressed files)
- DWORD nBlocks; // Number of blocks in the file (incl. the last noncomplete one)
- BOOL bBlockPosLoaded; // TRUE if block positions loaded
- BYTE * pbFileBuffer; // Decompressed file (for single unit files, size is the uncompressed file size)
-
- DWORD dwHashIndex; // Index to Hash table
- DWORD dwFileIndex; // Index to Block table
- char szFileName[1]; // File name (variable length)
-};
-
-
-// Used by searching in MPQ archives
-struct TMPQSearch
-{
- TMPQArchive * ha; // Handle to MPQ, where the search runs
- DWORD dwNextIndex; // The next searched hash index
- DWORD dwName1; // Lastly found Name1
- DWORD dwName2; // Lastly found Name2
- char szSearchMask[1]; // Search mask (variable length)
-};
-
-
-struct SFILE_FIND_DATA
-{
- char cFileName[MAX_PATH]; // Full name of the found file
- char * szPlainName; // Pointer to file part
- LCID lcLocale; // Locale version
- DWORD dwFileSize; // File size in bytes
- DWORD dwFileFlags; // File flags (compressed or encrypted)
- DWORD dwBlockIndex; // Block index for the file
- DWORD dwCompSize; // Compressed file size
-};
-
-//-----------------------------------------------------------------------------
-// Memory management
-//
-// We use our own macros for allocating/freeing memory. If you want
-// to redefine them, please keep the following rules
-//
-// - The memory allocation must return NULL if not enough memory
-// (i.e not to throw exception)
-// - It is not necessary to fill the allocated block with zeros
-// - Memory freeing function must not test the pointer to NULL.
-//
-
-
-__inline void * DebugMalloc(char * szFile, int nLine, int nSize)
-{
- void * ptr = malloc(nSize + 100);
- char * plain;
-
- plain = strrchr(szFile, '\\');
- if(plain == NULL)
- plain = strrchr(szFile, '/');
- if(plain == NULL)
- plain = szFile;
-
-#if _MSC_VER > 0x1300
- sprintf_s((char *)ptr, nSize+100, "%s(%u)", plain, nLine);
-#else
- sprintf((char *)ptr, "%s(%u)", plain, nLine);
-#endif
-
- return (char *)ptr + 100;
-}
-
-
-__inline void DebugFree(void * ptr)
-{
- free((char *)ptr - 100);
-}
-
-
-#ifndef ALLOCMEM
- #define ALLOCMEM(type, nitems) (type *)malloc((nitems) * sizeof(type))
- #define FREEMEM(ptr) free(ptr)
-#endif
-
-//#define ALLOCMEM(type, nitems) (type *)DebugMalloc(__FILE__, __LINE__, (nitems) * sizeof(type))
-//#define FREEMEM(ptr) DebugFree(ptr)
-
-//-----------------------------------------------------------------------------
-// Functions in StormLib - compatible with Storm.dll
-
-// Typedefs for functions exported by Storm.dll
-typedef LCID (WINAPI * SFILESETLOCALE)(LCID);
-typedef BOOL (WINAPI * SFILEOPENARCHIVE)(const char *, DWORD, DWORD, HANDLE *);
-typedef BOOL (WINAPI * SFILECLOSEARCHIVE)(HANDLE);
-typedef BOOL (WINAPI * SFILEOPENFILEEX)(HANDLE, const char *, DWORD, HANDLE *);
-typedef BOOL (WINAPI * SFILECLOSEFILE)(HANDLE);
-typedef DWORD (WINAPI * SFILEGETFILESIZE)(HANDLE, DWORD *);
-typedef DWORD (WINAPI * SFILESETFILEPOINTER)(HANDLE, LONG, LONG *, DWORD);
-typedef BOOL (WINAPI * SFILEREADFILE)(HANDLE, VOID *, DWORD, DWORD *, LPOVERLAPPED);
-
-// Archive opening/closing
-LCID WINAPI SFileSetLocale(LCID lcNewLocale);
-LCID WINAPI SFileGetLocale();
-BOOL WINAPI SFileOpenArchive(const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMPQ);
-BOOL WINAPI SFileCloseArchive(HANDLE hMPQ);
-
-// File opening/closing
-BOOL WINAPI SFileOpenFileEx(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile);
-BOOL WINAPI SFileCloseFile(HANDLE hFile);
-
-// File I/O
-DWORD WINAPI SFileGetFilePos(HANDLE hFile, DWORD * pdwFilePosHigh = NULL);
-DWORD WINAPI SFileGetFileSize(HANDLE hFile, DWORD * pdwFileSizeHigh = NULL);
-DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * pdwFilePosHigh, DWORD dwMethod);
-BOOL WINAPI SFileReadFile(HANDLE hFile, VOID * lpBuffer, DWORD dwToRead, DWORD * pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL);
-
-BOOL WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted);
-
-// Adds another listfile into MPQ. The currently added listfile(s) remain,
-// so you can use this API to combining more listfiles.
-// Note that this function is internally called by SFileFindFirstFile
-int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile);
-
-//-----------------------------------------------------------------------------
-// Functions in StormLib - not implemented in Storm.dll
-
-// Archive creating and editing
-BOOL WINAPI SFileCreateArchiveEx(const char * szMpqName, DWORD dwCreationDisposition, DWORD dwHashTableSize, HANDLE * phMPQ);
-BOOL WINAPI SFileAddFile(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags);
-BOOL WINAPI SFileAddWave(HANDLE hMPQ, const char * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality);
-BOOL WINAPI SFileRemoveFile(HANDLE hMPQ, const char * szFileName, DWORD dwSearchScope = SFILE_OPEN_BY_INDEX);
-BOOL WINAPI SFileRenameFile(HANDLE hMPQ, const char * szOldFileName, const char * szNewFileName);
-BOOL WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale);
-
-// Retrieving info about the file
-BOOL WINAPI SFileHasFile(HANDLE hMPQ, char * szFileName);
-BOOL WINAPI SFileGetFileName(HANDLE hFile, char * szFileName);
-DWORD_PTR WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType);
-
-// File search
-// Note that the SFileFindFirstFileEx has been removed. Use SListFileFindFirst/Next
-HANDLE WINAPI SFileFindFirstFile(HANDLE hMPQ, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile);
-BOOL WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
-BOOL WINAPI SFileFindClose(HANDLE hFind);
-
-// Listfile search
-HANDLE SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData);
-BOOL SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
-BOOL SListFileFindClose(HANDLE hFind);
-
-// Archive compacting
-typedef void (WINAPI * COMPACTCB)(void * lpUserData, DWORD dwWorkType, DWORD dwParam1, DWORD dwParam2);
-BOOL WINAPI SFileSetCompactCallback(HANDLE hMPQ, COMPACTCB CompactCB, void * lpData);
-BOOL WINAPI SFileCompactArchive(HANDLE hMPQ, const char * szListFile = NULL, BOOL bReserved = 0);
-
-// Locale support
-int WINAPI SFileEnumLocales(HANDLE hMPQ, const char * szFileName, LCID * plcLocales, DWORD * pdwMaxLocales, DWORD dwSearchScope = SFILE_OPEN_BY_INDEX);
-
-// (De)compression
-int WINAPI SCompCompress (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCompressions, int nCmpType, int nCmpLevel);
-int WINAPI SCompDecompress (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength);
-
-// Sets the default data compression for files added to MPQ,
-// if MPQ_FILE_COMPRESS_MULTI has been specified in call to SFileAddFile
-int WINAPI SCompSetDataCompression(int nDataCompression);
-
-//-----------------------------------------------------------------------------
-// Functions from Storm.dll. They use slightly different names for keeping
-// possibility to use them together with StormLib (StormXXX instead of SFileXXX)
-
-#ifdef __LINK_STORM_DLL__
- #define STORM_ALTERNATE_NAMES // Force Storm.h to use alternate fnc names
- #include "StormDll.h"
-#endif // __LINK_STORM_DLL__
-
-//-----------------------------------------------------------------------------
-// GFX decode functions. See GfxDecode.cpp for details and description
-
-USHORT WINAPI celGetFrameCount(BYTE * fileBuf);
-BYTE * WINAPI celGetFrameData(BYTE *fileBuf, BYTE *palette, USHORT xsize, USHORT frame, USHORT *ysize, USHORT *maxX=NULL);
-USHORT WINAPI cl2GetFrameCount(BYTE *fileBuf);
-BYTE ** WINAPI cl2GetDirData(BYTE *fileBuf, BYTE *palette, USHORT xsize, USHORT dir, USHORT *ysize);
-BYTE * WINAPI pcxGetData(BYTE *filebuf, DWORD filesize, BYTE transcol, USHORT *xsize, USHORT *ysize);
-
-#endif // __STORMLIB_H_
diff --git a/contrib/vmap_extractor_v2/stormlib/StormPort.h b/contrib/vmap_extractor_v2/stormlib/StormPort.h
deleted file mode 100644
index 6254f84e725..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/StormPort.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*****************************************************************************/
-/* StormPort.h Copyright (c) Marko Friedemann 2001 */
-/*---------------------------------------------------------------------------*/
-/* Portability module for the StormLib library. Contains a wrapper symbols */
-/* to make the compilation under Linux work */
-/* */
-/* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de> */
-/* Created at: Mon Jan 29 18:26:01 CEST 2001 */
-/* Computer: whiplash.flachland-chemnitz.de */
-/* System: Linux 2.4.0 on i686 */
-/* */
-/* Author: Sam Wilkins */
-/* System: Mac OS X and port to big endian processor */
-/* */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 29.01.01 1.00 Mar Created */
-/* 24.03.03 1.01 Lad Some cosmetic changes */
-/* 12.11.03 1.02 Dan Macintosh compatibility */
-/* 24.07.04 1.03 Sam Mac OS X compatibility */
-/* 22.11.06 1.04 Sam Mac OS X compatibility (for StormLib 6.0) */
-/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */
-/*****************************************************************************/
-
-#ifndef __STORMPORT_H__
-#define __STORMPORT_H__
-
-// Defines for Windows
-#if !defined(PLATFORM_DEFINED) && (defined(WIN32) || defined(WIN64))
-
- // In MSVC 8.0, there are some functions declared as deprecated.
- #if _MSC_VER >= 1400
- #define _CRT_SECURE_NO_DEPRECATE
- #define _CRT_NON_CONFORMING_SWPRINTFS
- #endif
-
- #include <assert.h>
- #include <stdio.h>
- #include <windows.h>
- #define PLATFORM_LITTLE_ENDIAN 1
-
- #ifdef WIN64
- #define PLATFORM_64BIT
- #else
- #define PLATFORM_32BIT
- #endif
-
- #define PLATFORM_DEFINED // The platform is known now
-
-#endif
-
-// Defines for Mac Carbon
-#if !defined(PLATFORM_DEFINED) && defined(__APPLE__) // Mac Carbon API
-
- // Macintosh using Carbon
- #include <Carbon/Carbon.h> // Mac OS X
- #define _stricmp strcasecmp // Case insensitive strcmp has a different name on this platform.
- #define _strnicmp strncasecmp
-
- typedef void * LPCSTR;
- typedef unsigned long * LPDWORD;
- typedef long * PLONG;
- typedef void * LPVOID;
- typedef unsigned int UINT;
-
- #define PKEXPORT
- #define __SYS_ZLIB
- #define __SYS_BZLIB
- #define LANG_NEUTRAL 0
-
- #if defined(__BIG_ENDIAN__)
- #define PLATFORM_LITTLE_ENDIAN 0
- #else
- #define PLATFORM_LITTLE_ENDIAN 1 // Apple is now making Macs with Intel CPUs
- #endif
- #define PLATFORM_DEFINED // The platform is known now
-
-#endif
-
-// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin*
-// Ladik : Why the hell Linux does not use some OS-dependent #define ?
-#if !defined(PLATFORM_DEFINED)
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
- #include <ctype.h>
- #include <assert.h>
-
- #define PLATFORM_LITTLE_ENDIAN 1
- #define PLATFORM_DEFINED
- #define LANG_NEUTRAL 0
-
-#endif /* not __powerc */
-
-
-#if !defined(WIN32) && !defined(WIN64)
-
- // Typedefs for ANSI C
- typedef unsigned char BYTE;
- typedef short SHORT;
- typedef unsigned short WORD;
- typedef unsigned short USHORT;
- typedef long LONG;
- typedef unsigned long DWORD;
- typedef unsigned long DWORD_PTR;
- typedef long LONG_PTR;
- typedef long long LONGLONG;
-#ifndef __OBJC__
- #define BOOL bool
-#endif
- typedef void * HANDLE;
- typedef void * LPOVERLAPPED; // Unsupported on Linux
- typedef char TCHAR;
- typedef unsigned long LCID;
-
- typedef void * LPCSTR;
- typedef unsigned long * LPDWORD;
- typedef long * PLONG;
- typedef void * LPVOID;
- typedef unsigned int UINT;
-
- typedef struct _FILETIME
- {
- DWORD dwLowDateTime;
- DWORD dwHighDateTime;
- }
- FILETIME, *PFILETIME;
-
- typedef union _LARGE_INTEGER
- {
- #if PLATFORM_LITTLE_ENDIAN
- struct
- {
- DWORD LowPart;
- LONG HighPart;
- };
- #else
- struct
- {
- LONG HighPart;
- DWORD LowPart;
- };
- #endif
- LONGLONG QuadPart;
- }
- LARGE_INTEGER, *PLARGE_INTEGER;
-
- // Some Windows-specific defines
- #ifndef MAX_PATH
- #define MAX_PATH 1024
- #endif
-
- #ifndef TRUE
- #define TRUE true
- #endif
-
- #ifndef FALSE
- #define FALSE false
- #endif
-
- #define VOID void
- #define WINAPI
-
- #define FILE_BEGIN SEEK_SET
- #define FILE_CURRENT SEEK_CUR
- #define FILE_END SEEK_END
-
- #define CREATE_NEW 1
- #define CREATE_ALWAYS 2
- #define OPEN_EXISTING 3
- #define OPEN_ALWAYS 4
-
- #define FILE_SHARE_READ 0x00000001L
- #define GENERIC_WRITE 0x40000000
- #define GENERIC_READ 0x80000000
-
- #define FILE_FLAG_DELETE_ON_CLOSE 1 // Sam: Added these two defines so it would compile.
- #define FILE_FLAG_SEQUENTIAL_SCAN 2
-
- #define ERROR_SUCCESS 0
- #define ERROR_INVALID_FUNCTION 1
- #define ERROR_FILE_NOT_FOUND 2
- #define ERROR_ACCESS_DENIED 5
- #define ERROR_NOT_ENOUGH_MEMORY 8
- #define ERROR_BAD_FORMAT 11
- #define ERROR_NO_MORE_FILES 18
- #define ERROR_GEN_FAILURE 31
- #define ERROR_HANDLE_EOF 38
- #define ERROR_HANDLE_DISK_FULL 39
- #define ERROR_NOT_SUPPORTED 50
- #define ERROR_INVALID_PARAMETER 87
- #define ERROR_DISK_FULL 112
- #define ERROR_CALL_NOT_IMPLEMENTED 120
- #define ERROR_ALREADY_EXISTS 183
- #define ERROR_CAN_NOT_COMPLETE 1003
- #define ERROR_PARAMETER_QUOTA_EXCEEDED 1283
- #define ERROR_FILE_CORRUPT 1392
- #define ERROR_INSUFFICIENT_BUFFER 4999
-
- #define INVALID_HANDLE_VALUE ((HANDLE) -1)
-
- #ifndef min
- #define min(a, b) ((a < b) ? a : b)
- #endif
-
- #ifndef max
- #define max(a, b) ((a > b) ? a : b)
- #endif
-
- #define _stricmp strcasecmp
- #define _strnicmp strncasecmp
-
- extern int globalerr;
-
- void SetLastError(int err);
- int GetLastError();
- char *ErrString(int err);
-
- // Emulation of functions for file I/O available in Win32
- HANDLE CreateFile(const char * lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, void * lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
- BOOL CloseHandle(HANDLE hObject);
-
- DWORD GetFileSize(HANDLE hFile, DWORD * lpFileSizeHigh);
- DWORD SetFilePointer(HANDLE, LONG lDistanceToMove, LONG * lpDistanceToMoveHigh, DWORD dwMoveMethod);
- BOOL SetEndOfFile(HANDLE hFile);
-
- BOOL ReadFile(HANDLE hFile, void * lpBuffer, DWORD nNumberOfBytesToRead, DWORD * lpNumberOfBytesRead, void * lpOverLapped);
- BOOL WriteFile(HANDLE hFile, const void * lpBuffer, DWORD nNumberOfBytesToWrite, DWORD * lpNumberOfBytesWritten, void * lpOverLapped);
-
- BOOL IsBadReadPtr(const void * ptr, int size);
- DWORD GetFileAttributes(const char * szileName);
-
- BOOL DeleteFile(const char * lpFileName);
- BOOL MoveFile(const char * lpFromFileName, const char * lpToFileName);
- void GetTempPath(DWORD szTempLength, char * szTemp);
- void GetTempFileName(const char * lpTempFolderPath, const char * lpFileName, DWORD something, char * szLFName);
-
- #define strnicmp strncasecmp
-
-#endif // !WIN32
-
-#if PLATFORM_LITTLE_ENDIAN
- #define BSWAP_INT16_UNSIGNED(a) (a)
- #define BSWAP_INT16_SIGNED(a) (a)
- #define BSWAP_INT32_UNSIGNED(a) (a)
- #define BSWAP_INT32_SIGNED(a) (a)
- #define BSWAP_ARRAY16_UNSIGNED(a,b) {}
- #define BSWAP_ARRAY32_UNSIGNED(a,b) {}
- #define BSWAP_TMPQSHUNT(a) {}
- #define BSWAP_TMPQHEADER(a) {}
-#else
- extern unsigned short SwapUShort(unsigned short);
- extern unsigned long SwapULong(unsigned long);
- extern short SwapShort(unsigned short);
- extern long SwapLong(unsigned long);
- extern void ConvertUnsignedLongBuffer(unsigned long *buffer, unsigned long nbLongs);
- extern void ConvertUnsignedShortBuffer(unsigned short *buffer, unsigned long nbShorts);
- extern void ConvertTMPQShunt(void *shunt);
- extern void ConvertTMPQHeader(void *header);
- #define BSWAP_INT16_UNSIGNED(a) SwapUShort((a))
- #define BSWAP_INT32_UNSIGNED(a) SwapULong((a))
- #define BSWAP_INT16_SIGNED(a) SwapShort((a))
- #define BSWAP_INT32_SIGNED(a) SwapLong((a))
- #define BSWAP_ARRAY16_UNSIGNED(a,b) ConvertUnsignedShortBuffer((a),(b))
- #define BSWAP_ARRAY32_UNSIGNED(a,b) ConvertUnsignedLongBuffer((a),(b))
- #define BSWAP_TMPQSHUNT(a) ConvertTMPQShunt((a))
- #define BSWAP_TMPQHEADER(a) ConvertTMPQHeader((a))
-#endif
-
-#endif // __STORMPORT_H__
diff --git a/contrib/vmap_extractor_v2/stormlib/StormPortLinux.cpp b/contrib/vmap_extractor_v2/stormlib/StormPortLinux.cpp
deleted file mode 100644
index afbbd985a7f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/StormPortLinux.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/********************************************************************
-*
-* Description: implementation for StormLib - linux port
-* intended to be used in GLdiablo
-*
-* ----> StormLib was originally developed for Windows by
-* Ladislav Zezula (www.zezula.net), and he did
-* a _great_ job! Thanks Ladislav!
-*
-* this is currently a quick and dirty hack to get it working
-* don't expect beauty and/or miracles :)
-*
-* these are function wraps to execute Windows API calls
-* as native Macintosh file calls (open/close/read/write/...)
-*
-* continue you work: added some wrapping functions for GNU/Linux by XPinguin
-*
-* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de>
-* Created at: Mon Jan 29 19:01:37 CEST 2001
-* Computer: whiplash.flachland-chemnitz.de
-* System: Linux 2.4.0 on i686
-*
-* Copyright (c) 2001 BMX-Chemnitz.DE All rights reserved.
-*
-********************************************************************/
-
-#ifndef _WIN32
-#include "StormPort.h"
-
-int globalerr;
-
-void SetLastError(int err)
-{
- globalerr = err;
-}
-
-int GetLastError()
-{
- return(globalerr);
-}
-
-char *ErrString(int err)
-{
- switch (err) {
- case ERROR_INVALID_FUNCTION:
- return "function not implemented";
- case ERROR_FILE_NOT_FOUND:
- return "file not found";
- case ERROR_ACCESS_DENIED:
- return "access denied";
- case ERROR_NOT_ENOUGH_MEMORY:
- return "not enough memory";
- case ERROR_BAD_FORMAT:
- return "bad format";
- case ERROR_NO_MORE_FILES:
- return "no more files";
- case ERROR_HANDLE_EOF:
- return "access beyound EOF";
- case ERROR_HANDLE_DISK_FULL:
- return "no space left on device";
- case ERROR_INVALID_PARAMETER:
- return "invalid parameter";
- case ERROR_DISK_FULL:
- return "no space left on device";
- case ERROR_ALREADY_EXISTS:
- return "file exists";
- case ERROR_CAN_NOT_COMPLETE:
- return "operation cannot be completed";
- default:
- return "unknown error";
- }
-}
-
-HANDLE CreateFile(const char *sFileName, DWORD ulMode, DWORD ulSharing, void *pSecAttrib, DWORD ulCreation, DWORD ulFlags, HANDLE hFile)
-{
- switch (ulCreation) {
- case OPEN_EXISTING:
- return (HANDLE)open(sFileName, O_RDONLY | O_LARGEFILE);
- case OPEN_ALWAYS:
- return (HANDLE)open(sFileName, O_RDWR | O_CREAT);
- case CREATE_NEW:
- return (HANDLE)open(sFileName, O_RDWR | O_CREAT | O_TRUNC);
- default:
- return INVALID_HANDLE_VALUE;
- }
-}
-
-BOOL CloseHandle(HANDLE hFile)
-{
- return (close((int)hFile) == 0);
-}
-
-DWORD GetFileSize(HANDLE hFile, DWORD *ulOffSetHigh)
-{
- if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE))
- return 0xffffffff;
-
- struct stat fileinfo;
- fstat((int)hFile, &fileinfo);
-
- return fileinfo.st_size;
-}
-
-DWORD SetFilePointer(HANDLE hFile, LONG lOffSetLow, LONG *pOffSetHigh, DWORD ulMethod)
-{
- return lseek64((int)hFile, (off64_t)(*pOffSetHigh) << 32 | (DWORD)lOffSetLow, ulMethod);
-}
-
-BOOL SetEndOfFile(HANDLE hFile)
-{
- return (ftruncate((int)hFile, lseek((int)hFile, 0, SEEK_CUR)) == 0);
-}
-
-BOOL ReadFile(HANDLE hFile, void *pBuffer, DWORD ulLen, DWORD *ulRead, void *pOverLapped)
-{
- ssize_t count;
- if ((count = read((int)hFile, pBuffer, ulLen)) == -1) {
- *ulRead = 0;
- return false;
- }
- *ulRead = count;
- return true;
-}
-
-BOOL WriteFile(HANDLE hFile, const void *pBuffer, DWORD ulLen, DWORD *ulWritten, void *pOverLapped)
-{
- ssize_t count;
- if ((count = write((int)hFile, pBuffer, ulLen)) == -1) {
- *ulWritten = 0;
- return false;
- }
- *ulWritten = count;
- return true;
-}
-
-// Check if a memory block is accessible for reading
-BOOL IsBadReadPtr(const void * ptr, int size)
-{
- return FALSE;
-}
-
-// Returns attributes of a file
-DWORD GetFileAttributes(const char * szFileName)
-{
- return 0;
-}
-
-void GetTempPath(DWORD szTempLength, char * szTemp)
-{
- strncpy(szTemp, P_tmpdir, szTempLength);
-}
-
-void GetTempFileName(const char * lpTempFolderPath, const char * lpFileName, DWORD something, char * szLFName)
-{
- strcpy(szLFName, tempnam(lpTempFolderPath, lpFileName));
-}
-
-BOOL DeleteFile(const char *lpFileName)
-{
- return (BOOL)remove(lpFileName);
-}
-
-BOOL MoveFile(const char *lpExistingFileName, const char *lpNewFileName)
-{
- return rename(lpExistingFileName, lpNewFileName);
-}
-
-#endif
diff --git a/contrib/vmap_extractor_v2/stormlib/StormPortMac.cpp b/contrib/vmap_extractor_v2/stormlib/StormPortMac.cpp
deleted file mode 100644
index 2477333ae02..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/StormPortMac.cpp
+++ /dev/null
@@ -1,762 +0,0 @@
-/********************************************************************
-*
-* Description: implementation for StormLib - Macintosh port
-*
-* these are function wraps to execute Windows API calls
-* as native Macintosh file calls (open/close/read/write/...)
-* requires Mac OS X
-*
-* Derived from Marko Friedemann <marko.friedemann@bmx-chemnitz.de>
-* StormPort.cpp for Linux
-*
-* Author: Daniel Chiaramello <daniel@chiaramello.net>
-*
-* Carbonized by: Sam Wilkins <swilkins1337@gmail.com>
-*
-********************************************************************/
-
-#ifndef _WIN32
-#include "StormPort.h"
-#include "StormLib.h"
-
-// FUNCTIONS EXTRACTED FROM MOREFILE PACKAGE!!!
-// FEEL FREE TO REMOVE THEM AND TO ADD THE ORIGINAL ONES!
-
-/*****************************************************************************
-* BEGIN OF MOREFILES COPY-PASTE
-*****************************************************************************/
-
-#ifdef __USEPRAGMAINTERNAL
- #ifdef __MWERKS__
- #pragma internal on
- #endif
-#endif
-
-union TLongAnd4Bytes
-{
- unsigned char bytes[4];
- unsigned long uvalue;
- signed long svalue;
-};
-
-
-static OSErr FSGetFullPath(const FSRef *ref, UInt8 *fullPath, UInt32 fullPathLength)
-{
- OSErr result;
-
- result = FSRefMakePath(ref, fullPath, fullPathLength);
-
- return result;
-}
-
-static OSErr FSLocationFromFullPath(const void *fullPath, FSRef *ref)
-{
- OSErr result;
-
- result = FSPathMakeRef((UInt8 *)fullPath, ref, NULL); // Create an FSRef from the path
- return result;
-}
-
-/*****************************************************************************/
-
-/*****************************************************************************/
-
-static OSErr FSCreateCompat(const FSRef *parentRef, OSType creator, OSType fileType, const UniChar *fileName,
- UniCharCount nameLength, FSRef *ref)
-{
- FSCatalogInfo theCatInfo;
- OSErr theErr;
- ((FileInfo *)&theCatInfo.finderInfo)->fileCreator = creator;
- ((FileInfo *)&theCatInfo.finderInfo)->fileType = fileType;
- ((FileInfo *)&theCatInfo.finderInfo)->finderFlags = 0;
- SetPt(&((FileInfo *)&theCatInfo.finderInfo)->location, 0, 0);
- ((FileInfo *)&theCatInfo.finderInfo)->reservedField = 0;
-
- theErr = FSCreateFileUnicode(parentRef, nameLength, fileName, kFSCatInfoFinderInfo, &theCatInfo, ref, NULL);
- return theErr;
-}
-
-
-/*****************************************************************************/
-
-static OSErr FSOpenDFCompat(FSRef *ref, char permission, short *refNum)
-{
- HFSUniStr255 forkName;
- OSErr theErr;
- Boolean isFolder, wasChanged;
-
- theErr = FSResolveAliasFile(ref, TRUE, &isFolder, &wasChanged);
- if (theErr != noErr)
- return theErr;
-
- FSGetDataForkName(&forkName);
- theErr = FSOpenFork(ref, forkName.length, forkName.unicode, permission, refNum);
- return theErr;
-}
-
-/*****************************************************************************
-* END OF MOREFILES COPY-PASTE
-*****************************************************************************/
-
-#pragma mark -
-
-int globalerr;
-
-/********************************************************************
-* SwapLong
-********************************************************************/
-
-unsigned long SwapULong(unsigned long data)
-{
- // Apple provided function
- uint32_t result;
-
- __asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
- return result;
-
-/*
- TLongAnd4Bytes Work;
- unsigned char * value_as_4bytes = (unsigned char *)&value;
-
- Work.bytes[0] = value_as_4bytes[3];
- Work.bytes[1] = value_as_4bytes[2];
- Work.bytes[2] = value_as_4bytes[1];
- Work.bytes[3] = value_as_4bytes[0];
-
- return Work.uvalue;
-*/
-}
-
-long SwapLong(unsigned long data)
-{
- // Apple provided function
- uint32_t result;
-
- __asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
- return (long)result;
-
-/*
- TLongAnd4Bytes Work;
- unsigned char * value_as_4bytes = (unsigned char *)&value;
-
- Work.bytes[0] = value_as_4bytes[3];
- Work.bytes[1] = value_as_4bytes[2];
- Work.bytes[2] = value_as_4bytes[1];
- Work.bytes[3] = value_as_4bytes[0];
-
- return Work.svalue;
-*/
-}
-
-/********************************************************************
-* SwapShort
-********************************************************************/
-unsigned short SwapUShort(unsigned short data)
-{
- // Apple provided function
- uint16_t result;
- __asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
- return result;
-}
-
-short SwapShort(unsigned short data)
-{
- // Apple provided function
- uint16_t result;
- __asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
- return (short)result;
-}
-
-/********************************************************************
-* ConvertUnsignedLongBuffer
-********************************************************************/
-void ConvertUnsignedLongBuffer(unsigned long *buffer, unsigned long nbLongs)
-{
- while (nbLongs-- > 0)
- {
- *buffer = SwapLong(*buffer);
- buffer++;
- }
-}
-
-/********************************************************************
-* ConvertUnsignedShortBuffer
-********************************************************************/
-void ConvertUnsignedShortBuffer(unsigned short *buffer, unsigned long nbShorts)
-{
- while (nbShorts-- > 0)
- {
- *buffer = SwapShort(*buffer);
- buffer++;
- }
-}
-
-/********************************************************************
-* ConvertTMPQShunt
-********************************************************************/
-void ConvertTMPQShunt(void *shunt)
-{
- TMPQShunt * theShunt = (TMPQShunt *)shunt;
-
- theShunt->dwID = SwapULong(theShunt->dwID);
- theShunt->dwUnknown = SwapULong(theShunt->dwUnknown);
- theShunt->dwHeaderPos = SwapULong(theShunt->dwHeaderPos);
-}
-
-/********************************************************************
-* ConvertTMPQHeader
-********************************************************************/
-void ConvertTMPQHeader(void *header)
-{
- TMPQHeader2 * theHeader = (TMPQHeader2 *)header;
-
- theHeader->dwID = SwapULong(theHeader->dwID);
- theHeader->dwHeaderSize = SwapULong(theHeader->dwHeaderSize);
- theHeader->dwArchiveSize = SwapULong(theHeader->dwArchiveSize);
- theHeader->wFormatVersion = SwapUShort(theHeader->wFormatVersion);
- theHeader->wBlockSize = SwapUShort(theHeader->wBlockSize);
- theHeader->dwHashTablePos = SwapULong(theHeader->dwHashTablePos);
- theHeader->dwBlockTablePos = SwapULong(theHeader->dwBlockTablePos);
- theHeader->dwHashTableSize = SwapULong(theHeader->dwHashTableSize);
- theHeader->dwBlockTableSize = SwapULong(theHeader->dwBlockTableSize);
-
- if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
- {
- DWORD dwTemp = theHeader->ExtBlockTablePos.LowPart;
- theHeader->ExtBlockTablePos.LowPart = theHeader->ExtBlockTablePos.HighPart;
- theHeader->ExtBlockTablePos.HighPart = dwTemp;
- theHeader->ExtBlockTablePos.LowPart = SwapULong(theHeader->ExtBlockTablePos.LowPart);
- theHeader->ExtBlockTablePos.HighPart = SwapULong(theHeader->ExtBlockTablePos.HighPart);
- theHeader->wHashTablePosHigh = SwapUShort(theHeader->wHashTablePosHigh);
- theHeader->wBlockTablePosHigh = SwapUShort(theHeader->wBlockTablePosHigh);
- }
-}
-
-/********************************************************************
-* ConvertTMPQHash
-********************************************************************/
-void ConvertHashTable(void *hashtable, DWORD nHashEntries)
-{
- TMPQHash * theHash = (TMPQHash *)hashtable;
- USHORT lcLocale;
-
- for(DWORD i = 0; i < nHashEntries; i++, theHash++)
- {
- lcLocale = theHash->lcLocale;
- theHash->lcLocale = theHash->wPlatform;
- theHash->wPlatform = lcLocale;
- }
-}
-
-#pragma mark -
-
-/********************************************************************
-* SetLastError
-********************************************************************/
-void SetLastError(int err)
-{
- globalerr = err;
-}
-
-/********************************************************************
-* GetLastError
-********************************************************************/
-int GetLastError()
-{
- return globalerr;
-}
-
-/********************************************************************
-* ErrString
-********************************************************************/
-char *ErrString(int err)
-{
- switch (err)
- {
- case ERROR_INVALID_FUNCTION:
- return "function not implemented";
- case ERROR_FILE_NOT_FOUND:
- return "file not found";
- case ERROR_ACCESS_DENIED:
- return "access denied";
- case ERROR_NOT_ENOUGH_MEMORY:
- return "not enough memory";
- case ERROR_BAD_FORMAT:
- return "bad format";
- case ERROR_NO_MORE_FILES:
- return "no more files";
- case ERROR_HANDLE_EOF:
- return "access beyound EOF";
- case ERROR_HANDLE_DISK_FULL:
- return "no space left on device";
- case ERROR_INVALID_PARAMETER:
- return "invalid parameter";
- case ERROR_DISK_FULL:
- return "no space left on device";
- case ERROR_ALREADY_EXISTS:
- return "file exists";
- case ERROR_CAN_NOT_COMPLETE:
- return "operation cannot be completed";
- case ERROR_INSUFFICIENT_BUFFER:
- return "insufficient buffer";
- default:
- return "unknown error";
- }
-}
-
-#pragma mark -
-
-/********************************************************************
-* GetTempPath - returns a '/' or ':'-terminated path
-* szTempLength: length for path
-* szTemp: file path
-********************************************************************/
-void GetTempPath(DWORD szTempLength, char * szTemp) // I think I'll change this to use FSRefs.
-{
- FSRef theFSRef;
- OSErr theErr = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, kCreateFolder, &theFSRef);
- if (theErr == noErr)
- {
- theErr = FSGetFullPath(&theFSRef, (UInt8 *)szTemp, MAX_PATH);
- if (theErr != noErr)
- szTemp[0] = '\0';
- }
- else
- szTemp[0] = '\0';
- strcat(szTemp, "/");
-
- SetLastError(theErr);
-}
-
-/********************************************************************
-* GetTempFileName
-* lpTempFolderPath: the temporary folder path, terminated by "/"
-* lpFileName: a file name base
-* something: unknown
-* szLFName: the final path, built from the path, the file name and a random pattern
-********************************************************************/
-void GetTempFileName(const char * lpTempFolderPath, const char * lpFileName, DWORD something, char * szLFName)
-{
-#pragma unused (something)
- char tmp[2] = "A";
-
- while (true)
- {
- HANDLE fHandle;
-
- strcpy(szLFName, lpTempFolderPath);
- strcat(szLFName, lpFileName);
- strcat(szLFName, tmp);
-
- if ((fHandle = CreateFile(szLFName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
- // OK we found it!
- break;
- CloseHandle(fHandle);
- tmp[0]++;
- }
-}
-
-/********************************************************************
-* DeleteFile
-* lpFileName: file path
-********************************************************************/
-BOOL DeleteFile(const char * lpFileName)
-{
- OSErr theErr;
- FSRef theFileRef;
-
- theErr = FSLocationFromFullPath(lpFileName, &theFileRef);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return FALSE;
- }
-
- theErr = FSDeleteObject(&theFileRef);
-
- SetLastError(theErr);
-
- return theErr == noErr;
-}
-
-/********************************************************************
-* MoveFile
-* lpFromFileName: old file path
-* lpToFileName: new file path
-********************************************************************/
-BOOL MoveFile(const char * lpFromFileName, const char * lpToFileName)
-{
- OSErr theErr;
- FSRef fromFileRef;
- FSRef toFileRef;
- FSRef parentFolderRef;
-
- // Get the path to the old file
- theErr = FSLocationFromFullPath(lpFromFileName, &fromFileRef);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return false;
- }
-
- // Get the path to the new folder for the file
- char folderName[strlen(lpToFileName)];
- CFStringRef folderPathCFString = CFStringCreateWithCString(NULL, lpToFileName, kCFStringEncodingUTF8);
- CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, folderPathCFString, kCFURLPOSIXPathStyle, FALSE);
- CFURLRef folderURL = CFURLCreateCopyDeletingLastPathComponent(NULL, fileURL);
- CFURLGetFileSystemRepresentation(folderURL, TRUE, (UInt8 *)folderName, strlen(lpToFileName));
- theErr = FSLocationFromFullPath(folderName, &parentFolderRef);
- CFRelease(fileURL);
- CFRelease(folderURL);
- CFRelease(folderPathCFString);
-
- // Move the old file
- theErr = FSMoveObject(&fromFileRef, &parentFolderRef, &toFileRef);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return false;
- }
-
- // Get a CFString for the new file name
- CFStringRef newFileNameCFString = CFStringCreateWithCString(NULL, lpToFileName, kCFStringEncodingUTF8);
- fileURL = CFURLCreateWithFileSystemPath(NULL, newFileNameCFString, kCFURLPOSIXPathStyle, FALSE);
- CFRelease(newFileNameCFString);
- newFileNameCFString = CFURLCopyLastPathComponent(fileURL);
- CFRelease(fileURL);
-
- // Convert CFString to Unicode and rename the file
- UniChar unicodeFileName[256];
- CFStringGetCharacters(newFileNameCFString, CFRangeMake(0, CFStringGetLength(newFileNameCFString)),
- unicodeFileName);
- theErr = FSRenameUnicode(&toFileRef, CFStringGetLength(newFileNameCFString), unicodeFileName,
- kTextEncodingUnknown, NULL);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- CFRelease(newFileNameCFString);
- return false;
- }
-
- CFRelease(newFileNameCFString);
-
- SetLastError(theErr);
- return true;
-}
-
-/********************************************************************
-* CreateFile
-* ulMode: GENERIC_READ | GENERIC_WRITE
-* ulSharing: FILE_SHARE_READ
-* pSecAttrib: NULL
-* ulCreation: OPEN_EXISTING, OPEN_ALWAYS, CREATE_NEW
-* ulFlags: 0
-* hFile: NULL
-********************************************************************/
-HANDLE CreateFile( const char *sFileName, /* file name */
- DWORD ulMode, /* access mode */
- DWORD ulSharing, /* share mode */
- void *pSecAttrib, /* SD */
- DWORD ulCreation, /* how to create */
- DWORD ulFlags, /* file attributes */
- HANDLE hFile ) /* handle to template file */
-{
-#pragma unused (ulSharing, pSecAttrib, ulFlags, hFile)
-
- OSErr theErr;
- FSRef theFileRef;
- FSRef theParentRef;
- short fileRef;
- char permission;
- static OSType gCreator;
- static OSType gType;
-
- theErr = FSLocationFromFullPath(sFileName, &theFileRef);
- if (theErr == fnfErr)
- { // Create the FSRef for the parent directory.
- memset(&theFileRef, 0, sizeof(FSRef));
- UInt8 folderName[MAX_PATH];
- CFStringRef folderPathCFString = CFStringCreateWithCString(NULL, sFileName, kCFStringEncodingUTF8);
- CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, folderPathCFString, kCFURLPOSIXPathStyle, FALSE);
- CFURLRef folderURL = CFURLCreateCopyDeletingLastPathComponent(NULL, fileURL);
- CFURLGetFileSystemRepresentation(folderURL, TRUE, folderName, MAX_PATH);
- theErr = FSLocationFromFullPath(folderName, &theParentRef);
- CFRelease(fileURL);
- CFRelease(folderURL);
- CFRelease(folderPathCFString);
- }
- if (theErr != noErr)
- {
- SetLastError(theErr);
- if (ulCreation == OPEN_EXISTING || theErr != fnfErr)
- return INVALID_HANDLE_VALUE;
- }
-
- if (ulCreation != OPEN_EXISTING)
- { /* We create the file */
- UniChar unicodeFileName[256];
- CFStringRef filePathCFString = CFStringCreateWithCString(NULL, sFileName, kCFStringEncodingUTF8);
- CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, filePathCFString, kCFURLPOSIXPathStyle, FALSE);
- CFStringRef fileNameCFString = CFURLCopyLastPathComponent(fileURL);
- CFStringGetCharacters(fileNameCFString, CFRangeMake(0, CFStringGetLength(fileNameCFString)),
- unicodeFileName);
- theErr = FSCreateCompat(&theParentRef, gCreator, gType, unicodeFileName,
- CFStringGetLength(fileNameCFString), &theFileRef);
- CFRelease(fileNameCFString);
- CFRelease(filePathCFString);
- CFRelease(fileURL);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return INVALID_HANDLE_VALUE;
- }
- }
-
- if (ulMode == GENERIC_READ)
- permission = fsRdPerm;
- else
- {
- if (ulMode == GENERIC_WRITE)
- permission = fsWrPerm;
- else
- permission = fsRdWrPerm;
- }
- theErr = FSOpenDFCompat(&theFileRef, permission, &fileRef);
-
- SetLastError(theErr);
-
- if (theErr == noErr)
- return (HANDLE)(int)fileRef;
- else
- return INVALID_HANDLE_VALUE;
-}
-
-/********************************************************************
-* CloseHandle
-********************************************************************/
-BOOL CloseHandle( HANDLE hFile ) /* handle to object */
-{
- OSErr theErr;
-
- if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE))
- return FALSE;
-
- theErr = FSCloseFork((short)(int)hFile);
-
- SetLastError(theErr);
-
- return theErr != noErr;
-}
-
-/********************************************************************
-* GetFileSize
-********************************************************************/
-DWORD GetFileSize( HANDLE hFile, /* handle to file */
- DWORD *ulOffSetHigh ) /* high-order word of file size */
-{
- SInt64 fileLength;
- OSErr theErr;
-
- if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE))
- {
- SetLastError(theErr);
- return -1u;
- }
-
- theErr = FSGetForkSize((short)(int)hFile, &fileLength);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return -1u;
- }
-
- if (ulOffSetHigh != NULL)
- *ulOffSetHigh = fileLength >> 32;
-
- SetLastError(theErr);
-
- return fileLength;
-}
-
-/********************************************************************
-* SetFilePointer
-* pOffSetHigh: NULL
-* ulMethod: FILE_BEGIN, FILE_CURRENT
-********************************************************************/
-DWORD SetFilePointer( HANDLE hFile, /* handle to file */
- LONG lOffSetLow, /* bytes to move pointer */
- LONG *pOffSetHigh, /* bytes to move pointer */
- DWORD ulMethod ) /* starting point */
-{
- OSErr theErr;
-
- if (ulMethod == FILE_CURRENT)
- {
- SInt64 bytesToMove;
-
- if (pOffSetHigh != NULL)
- bytesToMove = ((SInt64)*pOffSetHigh << 32) + lOffSetLow;
- else
- bytesToMove = lOffSetLow;
-
- SInt64 newPos;
-
- theErr = FSSetForkPosition((short)(int)hFile, fsFromMark, bytesToMove);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return -1u;
- }
-
- theErr = FSGetForkPosition((short)(int)hFile, &newPos);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return -1u;
- }
-
- if (pOffSetHigh != NULL)
- *pOffSetHigh = newPos >> 32;
-
- SetLastError(theErr);
- return newPos;
- }
- else if (ulMethod == FILE_BEGIN)
- {
- SInt64 bytesToMove;
-
- if (pOffSetHigh != NULL)
- bytesToMove = ((SInt64)*pOffSetHigh << 32) + lOffSetLow;
- else
- bytesToMove = lOffSetLow;
-
- theErr = FSSetForkPosition((short)(int)hFile, fsFromStart, bytesToMove);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return -1u;
- }
-
- SetLastError(theErr);
- return lOffSetLow;
- }
- else
- {
- SInt64 bytesToMove;
-
- if (pOffSetHigh != NULL)
- bytesToMove = ((SInt64)*pOffSetHigh << 32) + lOffSetLow;
- else
- bytesToMove = lOffSetLow;
-
- SInt64 newPos;
-
- theErr = FSSetForkPosition((short)(int)hFile, fsFromLEOF, bytesToMove);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return -1u;
- }
-
- theErr = FSGetForkPosition((short)(int)hFile, &newPos);
- if (theErr != noErr)
- {
- SetLastError(theErr);
- return -1u;
- }
-
- if (pOffSetHigh != NULL)
- *pOffSetHigh = newPos >> 32;
-
- SetLastError(theErr);
- return newPos;
- }
-}
-
-/********************************************************************
-* SetEndOfFile
-********************************************************************/
-BOOL SetEndOfFile( HANDLE hFile ) /* handle to file */
-{
- OSErr theErr;
-
- theErr = FSSetForkSize((short)(int)hFile, fsAtMark, 0);
-
- SetLastError(theErr);
-
- return theErr == noErr;
-}
-
-/********************************************************************
-* ReadFile
-* pOverLapped: NULL
-********************************************************************/
-BOOL ReadFile( HANDLE hFile, /* handle to file */
- void *pBuffer, /* data buffer */
- DWORD ulLen, /* number of bytes to read */
- DWORD *ulRead, /* number of bytes read */
- void *pOverLapped ) /* overlapped buffer */
-{
-#pragma unused (pOverLapped)
-
- ByteCount nbCharsRead;
- OSErr theErr;
-
- nbCharsRead = ulLen;
- theErr = FSReadFork((short)(int)hFile, fsAtMark, 0, nbCharsRead, pBuffer, &nbCharsRead);
- *ulRead = nbCharsRead;
-
- SetLastError(theErr);
-
- return theErr == noErr;
-}
-
-/********************************************************************
-* WriteFile
-* pOverLapped: NULL
-********************************************************************/
-BOOL WriteFile( HANDLE hFile, /* handle to file */
- const void *pBuffer, /* data buffer */
- DWORD ulLen, /* number of bytes to write */
- DWORD *ulWritten, /* number of bytes written */
- void *pOverLapped ) /* overlapped buffer */
-{
-#pragma unused (pOverLapped)
-
- ByteCount nbCharsToWrite;
- OSErr theErr;
-
- nbCharsToWrite = ulLen;
- theErr = FSWriteFork((short)(int)hFile, fsAtMark, 0, nbCharsToWrite, pBuffer, &nbCharsToWrite);
- *ulWritten = nbCharsToWrite;
-
- SetLastError(theErr);
-
- return theErr == noErr;
-}
-
-// Check if a memory block is accessible for reading. It's probably too
-// hard to check on Mac, so sorry, we'll just have to crash
-BOOL IsBadReadPtr(const void * ptr, int size)
-{
-#pragma unused (ptr, size)
-
- return FALSE;
-}
-
-// Returns attributes of a file. Actually, it doesn't, it just checks if
-// the file exists, since that's all StormLib uses it for
-DWORD GetFileAttributes(const char * szFileName)
-{
- FSRef theRef;
- OSErr theErr;
-
- theErr = FSLocationFromFullPath(szFileName, &theRef);
-
- if (theErr != noErr)
- return -1u;
- else
- return 0;
-}
-
-#endif
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/CHANGES b/contrib/vmap_extractor_v2/stormlib/bzip2/CHANGES
deleted file mode 100644
index e31b03a0118..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/CHANGES
+++ /dev/null
@@ -1,275 +0,0 @@
-
-
-0.9.0
-~~~~~
-First version.
-
-
-0.9.0a
-~~~~~~
-Removed 'ranlib' from Makefile, since most modern Unix-es
-don't need it, or even know about it.
-
-
-0.9.0b
-~~~~~~
-Fixed a problem with error reporting in bzip2.c. This does not effect
-the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the
-program proper) compress and decompress correctly, but give misleading
-error messages (internal panics) when an I/O error occurs, instead of
-reporting the problem correctly. This shouldn't give any data loss
-(as far as I can see), but is confusing.
-
-Made the inline declarations disappear for non-GCC compilers.
-
-
-0.9.0c
-~~~~~~
-Fixed some problems in the library pertaining to some boundary cases.
-This makes the library behave more correctly in those situations. The
-fixes apply only to features (calls and parameters) not used by
-bzip2.c, so the non-fixedness of them in previous versions has no
-effect on reliability of bzip2.c.
-
-In bzlib.c:
- * made zero-length BZ_FLUSH work correctly in bzCompress().
- * fixed bzWrite/bzRead to ignore zero-length requests.
- * fixed bzread to correctly handle read requests after EOF.
- * wrong parameter order in call to bzDecompressInit in
- bzBuffToBuffDecompress. Fixed.
-
-In compress.c:
- * changed setting of nGroups in sendMTFValues() so as to
- do a bit better on small files. This _does_ effect
- bzip2.c.
-
-
-0.9.5a
-~~~~~~
-Major change: add a fallback sorting algorithm (blocksort.c)
-to give reasonable behaviour even for very repetitive inputs.
-Nuked --repetitive-best and --repetitive-fast since they are
-no longer useful.
-
-Minor changes: mostly a whole bunch of small changes/
-bugfixes in the driver (bzip2.c). Changes pertaining to the
-user interface are:
-
- allow decompression of symlink'd files to stdout
- decompress/test files even without .bz2 extension
- give more accurate error messages for I/O errors
- when compressing/decompressing to stdout, don't catch control-C
- read flags from BZIP2 and BZIP environment variables
- decline to break hard links to a file unless forced with -f
- allow -c flag even with no filenames
- preserve file ownerships as far as possible
- make -s -1 give the expected block size (100k)
- add a flag -q --quiet to suppress nonessential warnings
- stop decoding flags after --, so files beginning in - can be handled
- resolved inconsistent naming: bzcat or bz2cat ?
- bzip2 --help now returns 0
-
-Programming-level changes are:
-
- fixed syntax error in GET_LL4 for Borland C++ 5.02
- let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
- fix overshoot of mode-string end in bzopen_or_bzdopen
- wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
- close file handles under all error conditions
- added minor mods so it compiles with DJGPP out of the box
- fixed Makefile so it doesn't give problems with BSD make
- fix uninitialised memory reads in dlltest.c
-
-0.9.5b
-~~~~~~
-Open stdin/stdout in binary mode for DJGPP.
-
-0.9.5c
-~~~~~~
-Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1
-version could cause the sorted order to be wrong in some extremely
-obscure cases. Also changed setting of quadrant in blocksort.c.
-
-0.9.5d
-~~~~~~
-The only functional change is to make bzlibVersion() in the library
-return the correct string. This has no effect whatsoever on the
-functioning of the bzip2 program or library. Added a couple of casts
-so the library compiles without warnings at level 3 in MS Visual
-Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
-changes are minor documentation changes.
-
-1.0
-~~~
-Several minor bugfixes and enhancements:
-
-* Large file support. The library uses 64-bit counters to
- count the volume of data passing through it. bzip2.c
- is now compiled with -D_FILE_OFFSET_BITS=64 to get large
- file support from the C library. -v correctly prints out
- file sizes greater than 4 gigabytes. All these changes have
- been made without assuming a 64-bit platform or a C compiler
- which supports 64-bit ints, so, except for the C library
- aspect, they are fully portable.
-
-* Decompression robustness. The library/program should be
- robust to any corruption of compressed data, detecting and
- handling _all_ corruption, instead of merely relying on
- the CRCs. What this means is that the program should
- never crash, given corrupted data, and the library should
- always return BZ_DATA_ERROR.
-
-* Fixed an obscure race-condition bug only ever observed on
- Solaris, in which, if you were very unlucky and issued
- control-C at exactly the wrong time, both input and output
- files would be deleted.
-
-* Don't run out of file handles on test/decompression when
- large numbers of files have invalid magic numbers.
-
-* Avoid library namespace pollution. Prefix all exported
- symbols with BZ2_.
-
-* Minor sorting enhancements from my DCC2000 paper.
-
-* Advance the version number to 1.0, so as to counteract the
- (false-in-this-case) impression some people have that programs
- with version numbers less than 1.0 are in some way, experimental,
- pre-release versions.
-
-* Create an initial Makefile-libbz2_so to build a shared library.
- Yes, I know I should really use libtool et al ...
-
-* Make the program exit with 2 instead of 0 when decompression
- fails due to a bad magic number (ie, an invalid bzip2 header).
- Also exit with 1 (as the manual claims :-) whenever a diagnostic
- message would have been printed AND the corresponding operation
- is aborted, for example
- bzip2: Output file xx already exists.
- When a diagnostic message is printed but the operation is not
- aborted, for example
- bzip2: Can't guess original name for wurble -- using wurble.out
- then the exit value 0 is returned, unless some other problem is
- also detected.
-
- I think it corresponds more closely to what the manual claims now.
-
-
-1.0.1
-~~~~~
-* Modified dlltest.c so it uses the new BZ2_ naming scheme.
-* Modified makefile-msc to fix minor build probs on Win2k.
-* Updated README.COMPILATION.PROBLEMS.
-
-There are no functionality changes or bug fixes relative to version
-1.0.0. This is just a documentation update + a fix for minor Win32
-build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
-utterly pointless. Don't bother.
-
-
-1.0.2
-~~~~~
-A bug fix release, addressing various minor issues which have appeared
-in the 18 or so months since 1.0.1 was released. Most of the fixes
-are to do with file-handling or documentation bugs. To the best of my
-knowledge, there have been no data-loss-causing bugs reported in the
-compression/decompression engine of 1.0.0 or 1.0.1.
-
-Note that this release does not improve the rather crude build system
-for Unix platforms. The general plan here is to autoconfiscate/
-libtoolise 1.0.2 soon after release, and release the result as 1.1.0
-or perhaps 1.2.0. That, however, is still just a plan at this point.
-
-Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in
-parentheses.
-
-* Fix an infinite segfault loop in 1.0.1 when a directory is
- encountered in -f (force) mode.
- (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)
-
-* Avoid double fclose() of output file on certain I/O error paths.
- (Solar Designer)
-
-* Don't fail with internal error 1007 when fed a long stream (> 48MB)
- of byte 251. Also print useful message suggesting that 1007s may be
- caused by bad memory.
- (noticed by Juan Pedro Vallejo, fixed by me)
-
-* Fix uninitialised variable silly bug in demo prog dlltest.c.
- (Jorj Bauer)
-
-* Remove 512-MB limitation on recovered file size for bzip2recover
- on selected platforms which support 64-bit ints. At the moment
- all GCC supported platforms, and Win32.
- (me, Alson van der Meulen)
-
-* Hard-code header byte values, to give correct operation on platforms
- using EBCDIC as their native character set (IBM's OS/390).
- (Leland Lucius)
-
-* Copy file access times correctly.
- (Marty Leisner)
-
-* Add distclean and check targets to Makefile.
- (Michael Carmack)
-
-* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS).
- (Rich Ireland, Bo Thorsen)
-
-* Pass -p (create parent dirs as needed) to mkdir during make install.
- (Jeremy Fusco)
-
-* Dereference symlinks when copying file permissions in -f mode.
- (Volker Schmidt)
-
-* Majorly simplify implementation of uInt64_qrm10.
- (Bo Lindbergh)
-
-* Check the input file still exists before deleting the output one,
- when aborting in cleanUpAndFail().
- (Joerg Prante, Robert Linden, Matthias Krings)
-
-Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
-of bzip2:
-
-* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.
-
-* Spelling changes and minor enhancements in bzip2.1.
-
-* Avoid race condition between creating the output file and setting its
- interim permissions safely, by using fopen_output_safely().
- No changes to bzip2recover since there is no issue with file
- permissions there.
-
-* do not print senseless report with -v when compressing an empty
- file.
-
-* bzcat -f works on non-bzip2 files.
-
-* do not try to escape shell meta-characters on unix (the shell takes
- care of these).
-
-* added --fast and --best aliases for -1 -9 for gzip compatibility.
-
-
-1.0.3 (15 Feb 05)
-~~~~~~~~~~~~~~~~~
-Fixes some minor bugs since the last version, 1.0.2.
-
-* Further robustification against corrupted compressed data.
- There are currently no known bitstreams which can cause the
- decompressor to crash, loop or access memory which does not
- belong to it. If you are using bzip2 or the library to
- decompress bitstreams from untrusted sources, an upgrade
- to 1.0.3 is recommended.
-
-* The documentation has been converted to XML, from which html
- and pdf can be derived.
-
-* Various minor bugs in the documentation have been fixed.
-
-* Fixes for various compilation warnings with newer versions of
- gcc, and on 64-bit platforms.
-
-* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
- This has been fixed.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/LICENSE b/contrib/vmap_extractor_v2/stormlib/bzip2/LICENSE
deleted file mode 100644
index e60845b4dcc..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/LICENSE
+++ /dev/null
@@ -1,40 +0,0 @@
-
-This program, "bzip2", the associated library "libbzip2", and all
-documentation, are copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
-3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
-4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
-Julian Seward, Cambridge, UK.
-jseward@acm.org
-bzip2/libbzip2 version 1.0.3 of 15 February 2005
-
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/Makefile-libbz2_so b/contrib/vmap_extractor_v2/stormlib/bzip2/Makefile-libbz2_so
deleted file mode 100644
index 458c5a135e7..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/Makefile-libbz2_so
+++ /dev/null
@@ -1,44 +0,0 @@
-
-# This Makefile builds a shared version of the library,
-# libbz2.so.1.0.3, with soname libbz2.so.1.0,
-# at least on x86-Linux (RedHat 7.2),
-# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98).
-# Please see the README file for some
-# important info about building the library like this.
-
-SHELL=/bin/sh
-CC=gcc
-BIGFILES=-D_FILE_OFFSET_BITS=64
-CFLAGS=-fpic -fPIC -Wall -Winline -O -g
-
-OBJS= blocksort.o \
- huffman.o \
- crctable.o \
- randtable.o \
- compress.o \
- decompress.o \
- bzlib.o
-
-all: $(OBJS)
- $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.3 $(OBJS)
- $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.3
- rm -f libbz2.so.1.0
- ln -s libbz2.so.1.0.3 libbz2.so.1.0
-
-clean:
- rm -f $(OBJS) bzip2.o libbz2.so.1.0.3 libbz2.so.1.0 bzip2-shared
-
-blocksort.o: blocksort.c
- $(CC) $(CFLAGS) -c blocksort.c
-huffman.o: huffman.c
- $(CC) $(CFLAGS) -c huffman.c
-crctable.o: crctable.c
- $(CC) $(CFLAGS) -c crctable.c
-randtable.o: randtable.c
- $(CC) $(CFLAGS) -c randtable.c
-compress.o: compress.c
- $(CC) $(CFLAGS) -c compress.c
-decompress.o: decompress.c
- $(CC) $(CFLAGS) -c decompress.c
-bzlib.o: bzlib.c
- $(CC) $(CFLAGS) -c bzlib.c
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/README b/contrib/vmap_extractor_v2/stormlib/bzip2/README
deleted file mode 100644
index 1aff4487e8c..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/README
+++ /dev/null
@@ -1,185 +0,0 @@
-
-This is the README for bzip2, a block-sorting file compressor, version
-1.0.3. This version is fully compatible with the previous public
-releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and 1.0.2.
-
-bzip2-1.0.3 is distributed under a BSD-style license. For details,
-see the file LICENSE.
-
-Complete documentation is available in Postscript form (manual.ps),
-PDF (manual.pdf) or html (manual.html). A plain-text version of the
-manual page is available as bzip2.txt. A statement about Y2K issues
-is now included in the file Y2K_INFO.
-
-
-HOW TO BUILD -- UNIX
-
-Type `make'. This builds the library libbz2.a and then the
-programs bzip2 and bzip2recover. Six self-tests are run.
-If the self-tests complete ok, carry on to installation:
-
-To install in /usr/bin, /usr/lib, /usr/man and /usr/include, type
- make install
-To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
- make install PREFIX=/xxx/yyy
-If you are (justifiably) paranoid and want to see what 'make install'
-is going to do, you can first do
- make -n install or
- make -n install PREFIX=/xxx/yyy respectively.
-The -n instructs make to show the commands it would execute, but
-not actually execute them.
-
-
-HOW TO BUILD -- UNIX, shared library libbz2.so.
-
-Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for
-Linux-ELF (RedHat 7.2 on an x86 box), with gcc. I make no claims
-that it works for any other platform, though I suspect it probably
-will work for most platforms employing both ELF and gcc.
-
-bzip2-shared, a client of the shared library, is also built, but not
-self-tested. So I suggest you also build using the normal Makefile,
-since that conducts a self-test. A second reason to prefer the
-version statically linked to the library is that, on x86 platforms,
-building shared objects makes a valuable register (%ebx) unavailable
-to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.
-
-Important note for people upgrading .so's from 0.9.0/0.9.5 to version
-1.0.X. All the functions in the library have been renamed, from (eg)
-bzCompress to BZ2_bzCompress, to avoid namespace pollution.
-Unfortunately this means that the libbz2.so created by
-Makefile-libbz2_so will not work with any program which used an older
-version of the library. Sorry. I do encourage library clients to
-make the effort to upgrade to use version 1.0, since it is both faster
-and more robust than previous versions.
-
-
-HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
-
-It's difficult for me to support compilation on all these platforms.
-My approach is to collect binaries for these platforms, and put them
-on the master web page (http://sources.redhat.com/bzip2). Look there.
-However (FWIW), bzip2-1.0.X is very standard ANSI C and should compile
-unmodified with MS Visual C. If you have difficulties building, you
-might want to read README.COMPILATION.PROBLEMS.
-
-At least using MS Visual C++ 6, you can build from the unmodified
-sources by issuing, in a command shell:
- nmake -f makefile.msc
-(you may need to first run the MSVC-provided script VCVARS32.BAT
- so as to set up paths to the MSVC tools correctly).
-
-
-VALIDATION
-
-Correct operation, in the sense that a compressed file can always be
-decompressed to reproduce the original, is obviously of paramount
-importance. To validate bzip2, I used a modified version of Mark
-Nelson's churn program. Churn is an automated test driver which
-recursively traverses a directory structure, using bzip2 to compress
-and then decompress each file it encounters, and checking that the
-decompressed data is the same as the original.
-
-
-
-Please read and be aware of the following:
-
-WARNING:
-
- This program (attempts to) compress data by performing several
- non-trivial transformations on it. Unless you are 100% familiar
- with *all* the algorithms contained herein, and with the
- consequences of modifying them, you should NOT meddle with the
- compression or decompression machinery. Incorrect changes can and
- very likely *will* lead to disastrous loss of data.
-
-
-DISCLAIMER:
-
- I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
- USE OF THIS PROGRAM, HOWSOEVER CAUSED.
-
- Every compression of a file implies an assumption that the
- compressed file can be decompressed to reproduce the original.
- Great efforts in design, coding and testing have been made to
- ensure that this program works correctly. However, the complexity
- of the algorithms, and, in particular, the presence of various
- special cases in the code which occur with very low but non-zero
- probability make it impossible to rule out the possibility of bugs
- remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS
- PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
- SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
-
- That is not to say this program is inherently unreliable. Indeed,
- I very much hope the opposite is true. bzip2 has been carefully
- constructed and extensively tested.
-
-
-PATENTS:
-
- To the best of my knowledge, bzip2 does not use any patented
- algorithms. However, I do not have the resources to carry out
- a patent search. Therefore I cannot give any guarantee of the
- above statement.
-
-End of legalities.
-
-
-WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
-
- * Approx 10% faster compression, 30% faster decompression
- * -t (test mode) is a lot quicker
- * Can decompress concatenated compressed files
- * Programming interface, so programs can directly read/write .bz2 files
- * Less restrictive (BSD-style) licensing
- * Flag handling more compatible with GNU gzip
- * Much more documentation, i.e., a proper user manual
- * Hopefully, improved portability (at least of the library)
-
-WHAT'S NEW IN 0.9.5 ?
-
- * Compression speed is much less sensitive to the input
- data than in previous versions. Specifically, the very
- slow performance caused by repetitive data is fixed.
- * Many small improvements in file and flag handling.
- * A Y2K statement.
-
-WHAT'S NEW IN 1.0.0 ?
-
- See the CHANGES file.
-
-WHAT'S NEW IN 1.0.2 ?
-
- See the CHANGES file.
-
-WHAT'S NEW IN 1.0.3 ?
-
- See the CHANGES file.
-
-
-I hope you find bzip2 useful. Feel free to contact me at
- jseward@bzip.org
-if you have any suggestions or queries. Many people mailed me with
-comments, suggestions and patches after the releases of bzip-0.15,
-bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and
-1.0.2, and the changes in bzip2 are largely a result of this feedback.
-I thank you for your comments.
-
-At least for the time being, bzip2's "home" is (or can be reached via)
-http://www.bzip.org
-
-Julian Seward
-jseward@bzip.org
-
-Cambridge, UK.
-
-18 July 1996 (version 0.15)
-25 August 1996 (version 0.21)
- 7 August 1997 (bzip2, version 0.1)
-29 August 1997 (bzip2, version 0.1pl2)
-23 August 1998 (bzip2, version 0.9.0)
- 8 June 1999 (bzip2, version 0.9.5)
- 4 Sept 1999 (bzip2, version 0.9.5d)
- 5 May 2000 (bzip2, version 1.0pre8)
-30 December 2001 (bzip2, version 1.0.2pre1)
-15 February 2005 (bzip2, version 1.0.3)
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/README.COMPILATION.PROBLEMS b/contrib/vmap_extractor_v2/stormlib/bzip2/README.COMPILATION.PROBLEMS
deleted file mode 100644
index f1bc396b765..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/README.COMPILATION.PROBLEMS
+++ /dev/null
@@ -1,39 +0,0 @@
-
-bzip2-1.0.3 should compile without problems on the vast majority of
-platforms. Using the supplied Makefile, I've built and tested it
-myself for x86-linux and x86_64-linux. With makefile.msc, Visual C++
-6.0 and nmake, you can build a native Win32 version too. Large file
-support seems to work correctly on at least alpha-tru64unix and
-x86-cygwin32 (on Windows 2000).
-
-When I say "large file" I mean a file of size 2,147,483,648 (2^31)
-bytes or above. Many older OSs can't handle files above this size,
-but many newer ones can. Large files are pretty huge -- most files
-you'll encounter are not Large Files.
-
-Earlier versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide
-variety of platforms without difficulty, and I hope this version will
-continue in that tradition. However, in order to support large files,
-I've had to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.
-This can cause problems.
-
-The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
-support is, as far as I know, the Recommended Way to get correct large
-file support. For more details, see the Large File Support
-Specification, published by the Large File Summit, at
- http://ftp.sas.com/standards/large.file
-
-As a general comment, if you get compilation errors which you think
-are related to large file support, try removing the above define from
-the Makefile, ie, delete the line
- BIGFILES=-D_FILE_OFFSET_BITS=64
-from the Makefile, and do 'make clean ; make'. This will give you a
-version of bzip2 without large file support, which, for most
-applications, is probably not a problem.
-
-Alternatively, try some of the platform-specific hints listed below.
-
-You can use the spewG.c program to generate huge files to test bzip2's
-large file support, if you are feeling paranoid. Be aware though that
-any compilation problems which affect bzip2 will also affect spewG.c,
-alas.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/README.XML.STUFF b/contrib/vmap_extractor_v2/stormlib/bzip2/README.XML.STUFF
deleted file mode 100644
index 0ff209f4466..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/README.XML.STUFF
+++ /dev/null
@@ -1,31 +0,0 @@
-The script xmlproc.sh takes an xml file as input,
-and processes it to create .pdf, .html or .ps output.
-It uses format.pl, a perl script to format <pre> blocks nicely,
- and add CDATA tags so writers do not have to use eg. &lt;
-
-The file "entities.xml" must be edited to reflect current
-version, year, etc.
-
-
-Usage:
-
- xmlproc.sh -v manual.xml
- Validates an xml file to ensure no dtd-compliance errors
-
- xmlproc.sh -html manual.xml
- Output: manual.html
-
- xmlproc.sh -pdf manual.xml
- Output: manual.pdf
-
- xmlproc.sh -ps manual.xml
- Output: manual.ps
-
-
-Notum bene:
-- pdfxmltex barfs if given a filename with an underscore in it
-
-- xmltex won't work yet - there's a bug in passivetex
- which we are all waiting for Sebastian to fix.
- So we are going the xml -> pdf -> ps route for the time being,
- using pdfxmltex.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/Y2K_INFO b/contrib/vmap_extractor_v2/stormlib/bzip2/Y2K_INFO
deleted file mode 100644
index 55fd56a2edb..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/Y2K_INFO
+++ /dev/null
@@ -1,34 +0,0 @@
-
-Y2K status of bzip2 and libbzip2, versions 0.1, 0.9.0 and 0.9.5
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Informally speaking:
- bzip2 is a compression program built on top of libbzip2,
- a library which does the real work of compression and
- decompression. As far as I am aware, libbzip2 does not have
- any date-related code at all.
-
- bzip2 itself copies dates from source to destination files
- when compressing or decompressing, using the 'stat' and 'utime'
- UNIX system calls. It doesn't examine, manipulate or store the
- dates in any way. So as far as I can see, there shouldn't be any
- problem with bzip2 providing 'stat' and 'utime' work correctly
- on your system.
-
- On non-unix platforms (those for which BZ_UNIX in bzip2.c is
- not set to 1), bzip2 doesn't even do the date copying.
-
- Overall, informally speaking, I don't think bzip2 or libbzip2
- have a Y2K problem.
-
-Formally speaking:
- I am not prepared to offer you any assurance whatsoever
- regarding Y2K issues in my software. You alone assume the
- entire risk of using the software. The disclaimer of liability
- in the LICENSE file in the bzip2 source distribution continues
- to apply on this issue as with every other issue pertaining
- to the software.
-
-Julian Seward
-Cambridge, UK
-25 August 1999
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-common.xsl b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-common.xsl
deleted file mode 100644
index 66fcd6fe0b6..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-common.xsl
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0"?> <!-- -*- sgml -*- -->
-<xsl:stylesheet
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-
-<!-- we like '1.2 Title' -->
-<xsl:param name="section.autolabel" select="'1'"/>
-<xsl:param name="section.label.includes.component.label" select="'1'"/>
-
-<!-- Do not put 'Chapter' at the start of eg 'Chapter 1. Doing This' -->
-<xsl:param name="local.l10n.xml" select="document('')"/>
-<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
- <l:l10n language="en">
- <l:context name="title-numbered">
- <l:template name="chapter" text="%n.&#160;%t"/>
- </l:context>
- </l:l10n>
-</l:i18n>
-
-<!-- don't generate sub-tocs for qanda sets -->
-<xsl:param name="generate.toc">
-set toc,title
-book toc,title,figure,table,example,equation
-chapter toc,title
-section toc
-sect1 toc
-sect2 toc
-sect3 toc
-sect4 nop
-sect5 nop
-qandaset toc
-qandadiv nop
-appendix toc,title
-article/appendix nop
-article toc,title
-preface toc,title
-reference toc,title
-</xsl:param>
-
-</xsl:stylesheet>
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-fo.xsl b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-fo.xsl
deleted file mode 100644
index 7f2a7674f04..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-fo.xsl
+++ /dev/null
@@ -1,257 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml -*- -->
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
-
-<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
-<xsl:import href="bz-common.xsl"/>
-
-<!-- set indent = yes while debugging, then change to NO -->
-<xsl:output method="xml" indent="yes"/>
-
-<!-- ensure only passivetex extensions are on -->
-<xsl:param name="stylesheet.result.type" select="'fo'"/>
-<!-- fo extensions: PDF bookmarks and index terms -->
-<xsl:param name="use.extensions" select="'1'"/>
-<xsl:param name="xep.extensions" select="0"/>
-<xsl:param name="fop.extensions" select="0"/>
-<xsl:param name="saxon.extensions" select="0"/>
-<xsl:param name="passivetex.extensions" select="1"/>
-<xsl:param name="tablecolumns.extension" select="'1'"/>
-
-<!-- ensure we are using single sided -->
-<xsl:param name="double.sided" select="'0'"/>
-
-<!-- insert cross references to page numbers -->
-<xsl:param name="insert.xref.page.number" select="1"/>
-
-<!-- <?custom-pagebreak?> inserts a page break at this point -->
-<xsl:template match="processing-instruction('custom-pagebreak')">
- <fo:block break-before='page'/>
-</xsl:template>
-
-<!-- show links in color -->
-<xsl:attribute-set name="xref.properties">
- <xsl:attribute name="color">blue</xsl:attribute>
-</xsl:attribute-set>
-
-<!-- make pre listings indented a bit + a bg colour -->
-<xsl:template match="programlisting | screen">
- <fo:block start-indent="0.25in" wrap-option="no-wrap"
- white-space-collapse="false" text-align="start"
- font-family="monospace" background-color="#f2f2f9"
- linefeed-treatment="preserve"
- xsl:use-attribute-sets="normal.para.spacing">
- <xsl:apply-templates/>
- </fo:block>
-</xsl:template>
-<!-- make verbatim output prettier -->
-<xsl:template match="literallayout">
- <fo:block start-indent="0.25in" wrap-option="no-wrap"
- white-space-collapse="false" text-align="start"
- font-family="monospace" background-color="#edf7f4"
- linefeed-treatment="preserve"
- space-before="0em" space-after="0em">
- <xsl:apply-templates/>
- </fo:block>
-</xsl:template>
-
-<!-- workaround bug in passivetex fo output for itemizedlist -->
-<xsl:template match="itemizedlist/listitem">
- <xsl:variable name="id">
- <xsl:call-template name="object.id"/></xsl:variable>
- <xsl:variable name="itemsymbol">
- <xsl:call-template name="list.itemsymbol">
- <xsl:with-param name="node" select="parent::itemizedlist"/>
- </xsl:call-template>
- </xsl:variable>
- <xsl:variable name="item.contents">
- <fo:list-item-label end-indent="label-end()">
- <fo:block>
- <xsl:choose>
- <xsl:when test="$itemsymbol='disc'">&#x2022;</xsl:when>
- <xsl:when test="$itemsymbol='bullet'">&#x2022;</xsl:when>
- <xsl:otherwise>&#x2022;</xsl:otherwise>
- </xsl:choose>
- </fo:block>
- </fo:list-item-label>
- <fo:list-item-body start-indent="body-start()">
- <xsl:apply-templates/> <!-- removed extra block wrapper -->
- </fo:list-item-body>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="parent::*/@spacing = 'compact'">
- <fo:list-item id="{$id}"
- xsl:use-attribute-sets="compact.list.item.spacing">
- <xsl:copy-of select="$item.contents"/>
- </fo:list-item>
- </xsl:when>
- <xsl:otherwise>
- <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
- <xsl:copy-of select="$item.contents"/>
- </fo:list-item>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<!-- workaround bug in passivetex fo output for orderedlist -->
-<xsl:template match="orderedlist/listitem">
- <xsl:variable name="id">
- <xsl:call-template name="object.id"/></xsl:variable>
- <xsl:variable name="item.contents">
- <fo:list-item-label end-indent="label-end()">
- <fo:block>
- <xsl:apply-templates select="." mode="item-number"/>
- </fo:block>
- </fo:list-item-label>
- <fo:list-item-body start-indent="body-start()">
- <xsl:apply-templates/> <!-- removed extra block wrapper -->
- </fo:list-item-body>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="parent::*/@spacing = 'compact'">
- <fo:list-item id="{$id}"
- xsl:use-attribute-sets="compact.list.item.spacing">
- <xsl:copy-of select="$item.contents"/>
- </fo:list-item>
- </xsl:when>
- <xsl:otherwise>
- <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
- <xsl:copy-of select="$item.contents"/>
- </fo:list-item>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<!-- workaround bug in passivetex fo output for variablelist -->
-<xsl:param name="variablelist.as.blocks" select="1"/>
-<xsl:template match="varlistentry" mode="vl.as.blocks">
- <xsl:variable name="id">
- <xsl:call-template name="object.id"/></xsl:variable>
- <fo:block id="{$id}" xsl:use-attribute-sets="list.item.spacing"
- keep-together.within-column="always"
- keep-with-next.within-column="always">
- <xsl:apply-templates select="term"/>
- </fo:block>
- <fo:block start-indent="0.5in" end-indent="0in"
- space-after.minimum="0.2em"
- space-after.optimum="0.4em"
- space-after.maximum="0.6em">
- <fo:block>
- <xsl:apply-templates select="listitem"/>
- </fo:block>
- </fo:block>
-</xsl:template>
-
-
-<!-- workaround bug in footers: force right-align w/two 80|30 cols -->
-<xsl:template name="footer.table">
- <xsl:param name="pageclass" select="''"/>
- <xsl:param name="sequence" select="''"/>
- <xsl:param name="gentext-key" select="''"/>
- <xsl:choose>
- <xsl:when test="$pageclass = 'index'">
- <xsl:attribute name="margin-left">0pt</xsl:attribute>
- </xsl:when>
- </xsl:choose>
- <xsl:variable name="candidate">
- <fo:table table-layout="fixed" width="100%">
- <fo:table-column column-number="1" column-width="80%"/>
- <fo:table-column column-number="2" column-width="20%"/>
- <fo:table-body>
- <fo:table-row height="14pt">
- <fo:table-cell text-align="left" display-align="after">
- <xsl:attribute name="relative-align">baseline</xsl:attribute>
- <fo:block>
- <fo:block> </fo:block><!-- empty cell -->
- </fo:block>
- </fo:table-cell>
- <fo:table-cell text-align="center" display-align="after">
- <xsl:attribute name="relative-align">baseline</xsl:attribute>
- <fo:block>
- <xsl:call-template name="footer.content">
- <xsl:with-param name="pageclass" select="$pageclass"/>
- <xsl:with-param name="sequence" select="$sequence"/>
- <xsl:with-param name="position" select="'center'"/>
- <xsl:with-param name="gentext-key" select="$gentext-key"/>
- </xsl:call-template>
- </fo:block>
- </fo:table-cell>
- </fo:table-row>
- </fo:table-body>
- </fo:table>
- </xsl:variable>
- <!-- Really output a footer? -->
- <xsl:choose>
- <xsl:when test="$pageclass='titlepage' and $gentext-key='book'
- and $sequence='first'">
- <!-- no, book titlepages have no footers at all -->
- </xsl:when>
- <xsl:when test="$sequence = 'blank' and $footers.on.blank.pages = 0">
- <!-- no output -->
- </xsl:when>
- <xsl:otherwise>
- <xsl:copy-of select="$candidate"/>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-
-<!-- fix bug in headers: force right-align w/two 40|60 cols -->
-<xsl:template name="header.table">
- <xsl:param name="pageclass" select="''"/>
- <xsl:param name="sequence" select="''"/>
- <xsl:param name="gentext-key" select="''"/>
- <xsl:choose>
- <xsl:when test="$pageclass = 'index'">
- <xsl:attribute name="margin-left">0pt</xsl:attribute>
- </xsl:when>
- </xsl:choose>
- <xsl:variable name="candidate">
- <fo:table table-layout="fixed" width="100%">
- <xsl:call-template name="head.sep.rule">
- <xsl:with-param name="pageclass" select="$pageclass"/>
- <xsl:with-param name="sequence" select="$sequence"/>
- <xsl:with-param name="gentext-key" select="$gentext-key"/>
- </xsl:call-template>
- <fo:table-column column-number="1" column-width="40%"/>
- <fo:table-column column-number="2" column-width="60%"/>
- <fo:table-body>
- <fo:table-row height="14pt">
- <fo:table-cell text-align="left" display-align="before">
- <xsl:attribute name="relative-align">baseline</xsl:attribute>
- <fo:block>
- <fo:block> </fo:block><!-- empty cell -->
- </fo:block>
- </fo:table-cell>
- <fo:table-cell text-align="center" display-align="before">
- <xsl:attribute name="relative-align">baseline</xsl:attribute>
- <fo:block>
- <xsl:call-template name="header.content">
- <xsl:with-param name="pageclass" select="$pageclass"/>
- <xsl:with-param name="sequence" select="$sequence"/>
- <xsl:with-param name="position" select="'center'"/>
- <xsl:with-param name="gentext-key" select="$gentext-key"/>
- </xsl:call-template>
- </fo:block>
- </fo:table-cell>
- </fo:table-row>
- </fo:table-body>
- </fo:table>
- </xsl:variable>
- <!-- Really output a header? -->
- <xsl:choose>
- <xsl:when test="$pageclass = 'titlepage' and $gentext-key = 'book'
- and $sequence='first'">
- <!-- no, book titlepages have no headers at all -->
- </xsl:when>
- <xsl:when test="$sequence = 'blank' and $headers.on.blank.pages = 0">
- <!-- no output -->
- </xsl:when>
- <xsl:otherwise>
- <xsl:copy-of select="$candidate"/>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-
-</xsl:stylesheet>
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-html.xsl b/contrib/vmap_extractor_v2/stormlib/bzip2/bz-html.xsl
deleted file mode 100644
index 1785fffbc95..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bz-html.xsl
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?> <!-- -*- sgml -*- -->
-<!DOCTYPE xsl:stylesheet [ <!ENTITY bz-css SYSTEM "./bzip.css"> ]>
-
-<xsl:stylesheet
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-
-<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
-<xsl:import href="bz-common.xsl"/>
-
-<!-- use 8859-1 encoding -->
-<xsl:output method="html" encoding="ISO-8859-1" indent="yes"/>
-
-<!-- we include the css directly when generating one large file -->
-<xsl:template name="user.head.content">
- <style type="text/css" media="screen">
- <xsl:text>&bz-css;</xsl:text>
- </style>
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff b/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff
deleted file mode 100644
index 3c2eb859fca..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
-
-# Bzcmp/diff wrapped for bzip2,
-# adapted from zdiff by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
-
-# Bzcmp and bzdiff are used to invoke the cmp or the diff pro-
-# gram on compressed files. All options specified are passed
-# directly to cmp or diff. If only 1 file is specified, then
-# the files compared are file1 and an uncompressed file1.gz.
-# If two files are specified, then they are uncompressed (if
-# necessary) and fed to cmp or diff. The exit status from cmp
-# or diff is preserved.
-
-PATH="/usr/bin:$PATH"; export PATH
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
- *cmp) comp=${CMP-cmp} ;;
- *) comp=${DIFF-diff} ;;
-esac
-
-OPTIONS=
-FILES=
-for ARG
-do
- case "$ARG" in
- -*) OPTIONS="$OPTIONS $ARG";;
- *) if test -f "$ARG"; then
- FILES="$FILES $ARG"
- else
- echo "${prog}: $ARG not found or not a regular file"
- exit 1
- fi ;;
- esac
-done
-if test -z "$FILES"; then
- echo "Usage: $prog [${comp}_options] file [file]"
- exit 1
-fi
-tmp=`tempfile -d /tmp -p bz` || {
- echo 'cannot create a temporary file' >&2
- exit 1
-}
-set $FILES
-if test $# -eq 1; then
- FILE=`echo "$1" | sed 's/.bz2$//'`
- bzip2 -cd "$FILE.bz2" | $comp $OPTIONS - "$FILE"
- STAT="$?"
-
-elif test $# -eq 2; then
- case "$1" in
- *.bz2)
- case "$2" in
- *.bz2)
- F=`echo "$2" | sed 's|.*/||;s|.bz2$||'`
- bzip2 -cdfq "$2" > $tmp
- bzip2 -cdfq "$1" | $comp $OPTIONS - $tmp
- STAT="$?"
- /bin/rm -f $tmp;;
-
- *) bzip2 -cdfq "$1" | $comp $OPTIONS - "$2"
- STAT="$?";;
- esac;;
- *) case "$2" in
- *.bz2)
- bzip2 -cdfq "$2" | $comp $OPTIONS "$1" -
- STAT="$?";;
- *) $comp $OPTIONS "$1" "$2"
- STAT="$?";;
- esac;;
- esac
- exit "$STAT"
-else
- echo "Usage: $prog [${comp}_options] file [file]"
- exit 1
-fi
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff.1
deleted file mode 100644
index adb7a8e724e..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzdiff.1
+++ /dev/null
@@ -1,47 +0,0 @@
-\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
-\"for Debian GNU/Linux
-.TH BZDIFF 1
-.SH NAME
-bzcmp, bzdiff \- compare bzip2 compressed files
-.SH SYNOPSIS
-.B bzcmp
-[ cmp_options ] file1
-[ file2 ]
-.br
-.B bzdiff
-[ diff_options ] file1
-[ file2 ]
-.SH DESCRIPTION
-.I Bzcmp
-and
-.I bzdiff
-are used to invoke the
-.I cmp
-or the
-.I diff
-program on bzip2 compressed files. All options specified are passed
-directly to
-.I cmp
-or
-.IR diff "."
-If only 1 file is specified, then the files compared are
-.I file1
-and an uncompressed
-.IR file1 ".bz2."
-If two files are specified, then they are uncompressed if necessary and fed to
-.I cmp
-or
-.IR diff "."
-The exit status from
-.I cmp
-or
-.I diff
-is preserved.
-.SH "SEE ALSO"
-cmp(1), diff(1), bzmore(1), bzless(1), bzgrep(1), bzip2(1)
-.SH BUGS
-Messages from the
-.I cmp
-or
-.I diff
-programs refer to temporary filenames instead of those specified.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep b/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep
deleted file mode 100644
index dbfc00e8dbe..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/sh
-
-# Bzgrep wrapped for bzip2,
-# adapted from zgrep by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
-## zgrep notice:
-## zgrep -- a wrapper around a grep program that decompresses files as needed
-## Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
-
-PATH="/usr/bin:$PATH"; export PATH
-
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
- *egrep) grep=${EGREP-egrep} ;;
- *fgrep) grep=${FGREP-fgrep} ;;
- *) grep=${GREP-grep} ;;
-esac
-pat=""
-while test $# -ne 0; do
- case "$1" in
- -e | -f) opt="$opt $1"; shift; pat="$1"
- if test "$grep" = grep; then # grep is buggy with -e on SVR4
- grep=egrep
- fi;;
- -A | -B) opt="$opt $1 $2"; shift;;
- -*) opt="$opt $1";;
- *) if test -z "$pat"; then
- pat="$1"
- else
- break;
- fi;;
- esac
- shift
-done
-
-if test -z "$pat"; then
- echo "grep through bzip2 files"
- echo "usage: $prog [grep_options] pattern [files]"
- exit 1
-fi
-
-list=0
-silent=0
-op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
-case "$op" in
- *l*) list=1
-esac
-case "$op" in
- *h*) silent=1
-esac
-
-if test $# -eq 0; then
- bzip2 -cdfq | $grep $opt "$pat"
- exit $?
-fi
-
-res=0
-for i do
- if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi
- if test $list -eq 1; then
- bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i
- r=$?
- elif test $# -eq 1 -o $silent -eq 1; then
- bzip2 -cdfq "$i" | $grep $opt "$pat"
- r=$?
- else
- bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${i}:|"
- r=$?
- fi
- test "$r" -ne 0 && res="$r"
-done
-exit $res
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep.1
deleted file mode 100644
index 930af8c7fcb..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzgrep.1
+++ /dev/null
@@ -1,56 +0,0 @@
-\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
-\"for Debian GNU/Linux
-.TH BZGREP 1
-.SH NAME
-bzgrep, bzfgrep, bzegrep \- search possibly bzip2 compressed files for a regular expression
-.SH SYNOPSIS
-.B bzgrep
-[ grep_options ]
-.BI [\ -e\ ] " pattern"
-.IR filename ".\|.\|."
-.br
-.B bzegrep
-[ egrep_options ]
-.BI [\ -e\ ] " pattern"
-.IR filename ".\|.\|."
-.br
-.B bzfgrep
-[ fgrep_options ]
-.BI [\ -e\ ] " pattern"
-.IR filename ".\|.\|."
-.SH DESCRIPTION
-.IR Bzgrep
-is used to invoke the
-.I grep
-on bzip2-compressed files. All options specified are passed directly to
-.I grep.
-If no file is specified, then the standard input is decompressed
-if necessary and fed to grep.
-Otherwise the given files are uncompressed if necessary and fed to
-.I grep.
-.PP
-If
-.I bzgrep
-is invoked as
-.I bzegrep
-or
-.I bzfgrep
-then
-.I egrep
-or
-.I fgrep
-is used instead of
-.I grep.
-If the GREP environment variable is set,
-.I bzgrep
-uses it as the
-.I grep
-program to be invoked. For example:
-
- for sh: GREP=fgrep bzgrep string files
- for csh: (setenv GREP fgrep; bzgrep string files)
-.SH AUTHOR
-Charles Levert (charles@comm.polymtl.ca). Adapted to bzip2 by Philippe
-Troin <phil@fifi.org> for Debian GNU/Linux.
-.SH "SEE ALSO"
-grep(1), egrep(1), fgrep(1), bzdiff(1), bzmore(1), bzless(1), bzip2(1)
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip.css b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip.css
deleted file mode 100644
index 43193d8db0b..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Colours:
-#74240f dark brown h1, h2, h3, h4
-#336699 medium blue links
-#339999 turquoise link hover colour
-#202020 almost black general text
-#761596 purple md5sum text
-#626262 dark gray pre border
-#eeeeee very light gray pre background
-#f2f2f9 very light blue nav table background
-#3366cc medium blue nav table border
-*/
-
-a, a:link, a:visited, a:active { color: #336699; }
-a:hover { color: #339999; }
-
-body { font: 80%/126% sans-serif; }
-h1, h2, h3, h4 { color: #74240f; }
-
-dt { color: #336699; font-weight: bold }
-dd {
- margin-left: 1.5em;
- padding-bottom: 0.8em;
-}
-
-/* -- ruler -- */
-div.hr_blue {
- height: 3px;
- background:#ffffff url("/images/hr_blue.png") repeat-x; }
-div.hr_blue hr { display:none; }
-
-/* release styles */
-#release p { margin-top: 0.4em; }
-#release .md5sum { color: #761596; }
-
-
-/* ------ styles for docs|manuals|howto ------ */
-/* -- lists -- */
-ul {
- margin: 0px 4px 16px 16px;
- padding: 0px;
- list-style: url("/images/li-blue.png");
-}
-ul li {
- margin-bottom: 10px;
-}
-ul ul {
- list-style-type: none;
- list-style-image: none;
- margin-left: 0px;
-}
-
-/* header / footer nav tables */
-table.nav {
- border: solid 1px #3366cc;
- background: #f2f2f9;
- background-color: #f2f2f9;
- margin-bottom: 0.5em;
-}
-/* don't have underlined links in chunked nav menus */
-table.nav a { text-decoration: none; }
-table.nav a:hover { text-decoration: underline; }
-table.nav td { font-size: 85%; }
-
-code, tt, pre { font-size: 120%; }
-code, tt { color: #761596; }
-
-div.literallayout, pre.programlisting, pre.screen {
- color: #000000;
- padding: 0.5em;
- background: #eeeeee;
- border: 1px solid #626262;
- background-color: #eeeeee;
- margin: 4px 0px 4px 0px;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1
deleted file mode 100644
index d2c06615683..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1
+++ /dev/null
@@ -1,454 +0,0 @@
-.PU
-.TH bzip2 1
-.SH NAME
-bzip2, bunzip2 \- a block-sorting file compressor, v1.0.3
-.br
-bzcat \- decompresses files to stdout
-.br
-bzip2recover \- recovers data from damaged bzip2 files
-
-.SH SYNOPSIS
-.ll +8
-.B bzip2
-.RB [ " \-cdfkqstvzVL123456789 " ]
-[
-.I "filenames \&..."
-]
-.ll -8
-.br
-.B bunzip2
-.RB [ " \-fkvsVL " ]
-[
-.I "filenames \&..."
-]
-.br
-.B bzcat
-.RB [ " \-s " ]
-[
-.I "filenames \&..."
-]
-.br
-.B bzip2recover
-.I "filename"
-
-.SH DESCRIPTION
-.I bzip2
-compresses files using the Burrows-Wheeler block sorting
-text compression algorithm, and Huffman coding. Compression is
-generally considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of the PPM
-family of statistical compressors.
-
-The command-line options are deliberately very similar to
-those of
-.I GNU gzip,
-but they are not identical.
-
-.I bzip2
-expects a list of file names to accompany the
-command-line flags. Each file is replaced by a compressed version of
-itself, with the name "original_name.bz2".
-Each compressed file
-has the same modification date, permissions, and, when possible,
-ownership as the corresponding original, so that these properties can
-be correctly restored at decompression time. File name handling is
-naive in the sense that there is no mechanism for preserving original
-file names, permissions, ownerships or dates in filesystems which lack
-these concepts, or have serious file name length restrictions, such as
-MS-DOS.
-
-.I bzip2
-and
-.I bunzip2
-will by default not overwrite existing
-files. If you want this to happen, specify the \-f flag.
-
-If no file names are specified,
-.I bzip2
-compresses from standard
-input to standard output. In this case,
-.I bzip2
-will decline to
-write compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.
-
-.I bunzip2
-(or
-.I bzip2 \-d)
-decompresses all
-specified files. Files which were not created by
-.I bzip2
-will be detected and ignored, and a warning issued.
-.I bzip2
-attempts to guess the filename for the decompressed file
-from that of the compressed file as follows:
-
- filename.bz2 becomes filename
- filename.bz becomes filename
- filename.tbz2 becomes filename.tar
- filename.tbz becomes filename.tar
- anyothername becomes anyothername.out
-
-If the file does not end in one of the recognised endings,
-.I .bz2,
-.I .bz,
-.I .tbz2
-or
-.I .tbz,
-.I bzip2
-complains that it cannot
-guess the name of the original file, and uses the original name
-with
-.I .out
-appended.
-
-As with compression, supplying no
-filenames causes decompression from
-standard input to standard output.
-
-.I bunzip2
-will correctly decompress a file which is the
-concatenation of two or more compressed files. The result is the
-concatenation of the corresponding uncompressed files. Integrity
-testing (\-t)
-of concatenated
-compressed files is also supported.
-
-You can also compress or decompress files to the standard output by
-giving the \-c flag. Multiple files may be compressed and
-decompressed like this. The resulting outputs are fed sequentially to
-stdout. Compression of multiple files
-in this manner generates a stream
-containing multiple compressed file representations. Such a stream
-can be decompressed correctly only by
-.I bzip2
-version 0.9.0 or
-later. Earlier versions of
-.I bzip2
-will stop after decompressing
-the first file in the stream.
-
-.I bzcat
-(or
-.I bzip2 -dc)
-decompresses all specified files to
-the standard output.
-
-.I bzip2
-will read arguments from the environment variables
-.I BZIP2
-and
-.I BZIP,
-in that order, and will process them
-before any arguments read from the command line. This gives a
-convenient way to supply default arguments.
-
-Compression is always performed, even if the compressed
-file is slightly
-larger than the original. Files of less than about one hundred bytes
-tend to get larger, since the compression mechanism has a constant
-overhead in the region of 50 bytes. Random data (including the output
-of most file compressors) is coded at about 8.05 bits per byte, giving
-an expansion of around 0.5%.
-
-As a self-check for your protection,
-.I
-bzip2
-uses 32-bit CRCs to
-make sure that the decompressed version of a file is identical to the
-original. This guards against corruption of the compressed data, and
-against undetected bugs in
-.I bzip2
-(hopefully very unlikely). The
-chances of data corruption going undetected is microscopic, about one
-chance in four billion for each file processed. Be aware, though, that
-the check occurs upon decompression, so it can only tell you that
-something is wrong. It can't help you
-recover the original uncompressed
-data. You can use
-.I bzip2recover
-to try to recover data from
-damaged files.
-
-Return values: 0 for a normal exit, 1 for environmental problems (file
-not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
-compressed file, 3 for an internal consistency error (eg, bug) which
-caused
-.I bzip2
-to panic.
-
-.SH OPTIONS
-.TP
-.B \-c --stdout
-Compress or decompress to standard output.
-.TP
-.B \-d --decompress
-Force decompression.
-.I bzip2,
-.I bunzip2
-and
-.I bzcat
-are
-really the same program, and the decision about what actions to take is
-done on the basis of which name is used. This flag overrides that
-mechanism, and forces
-.I bzip2
-to decompress.
-.TP
-.B \-z --compress
-The complement to \-d: forces compression, regardless of the
-invocation name.
-.TP
-.B \-t --test
-Check integrity of the specified file(s), but don't decompress them.
-This really performs a trial decompression and throws away the result.
-.TP
-.B \-f --force
-Force overwrite of output files. Normally,
-.I bzip2
-will not overwrite
-existing output files. Also forces
-.I bzip2
-to break hard links
-to files, which it otherwise wouldn't do.
-
-bzip2 normally declines to decompress files which don't have the
-correct magic header bytes. If forced (-f), however, it will pass
-such files through unmodified. This is how GNU gzip behaves.
-.TP
-.B \-k --keep
-Keep (don't delete) input files during compression
-or decompression.
-.TP
-.B \-s --small
-Reduce memory usage, for compression, decompression and testing. Files
-are decompressed and tested using a modified algorithm which only
-requires 2.5 bytes per block byte. This means any file can be
-decompressed in 2300k of memory, albeit at about half the normal speed.
-
-During compression, \-s selects a block size of 200k, which limits
-memory use to around the same figure, at the expense of your compression
-ratio. In short, if your machine is low on memory (8 megabytes or
-less), use \-s for everything. See MEMORY MANAGEMENT below.
-.TP
-.B \-q --quiet
-Suppress non-essential warning messages. Messages pertaining to
-I/O errors and other critical events will not be suppressed.
-.TP
-.B \-v --verbose
-Verbose mode -- show the compression ratio for each file processed.
-Further \-v's increase the verbosity level, spewing out lots of
-information which is primarily of interest for diagnostic purposes.
-.TP
-.B \-L --license -V --version
-Display the software version, license terms and conditions.
-.TP
-.B \-1 (or \-\-fast) to \-9 (or \-\-best)
-Set the block size to 100 k, 200 k .. 900 k when compressing. Has no
-effect when decompressing. See MEMORY MANAGEMENT below.
-The \-\-fast and \-\-best aliases are primarily for GNU gzip
-compatibility. In particular, \-\-fast doesn't make things
-significantly faster.
-And \-\-best merely selects the default behaviour.
-.TP
-.B \--
-Treats all subsequent arguments as file names, even if they start
-with a dash. This is so you can handle files with names beginning
-with a dash, for example: bzip2 \-- \-myfilename.
-.TP
-.B \--repetitive-fast --repetitive-best
-These flags are redundant in versions 0.9.5 and above. They provided
-some coarse control over the behaviour of the sorting algorithm in
-earlier versions, which was sometimes useful. 0.9.5 and above have an
-improved algorithm which renders these flags irrelevant.
-
-.SH MEMORY MANAGEMENT
-.I bzip2
-compresses large files in blocks. The block size affects
-both the compression ratio achieved, and the amount of memory needed for
-compression and decompression. The flags \-1 through \-9
-specify the block size to be 100,000 bytes through 900,000 bytes (the
-default) respectively. At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-.I bunzip2
-then allocates itself just enough memory to decompress
-the file. Since block sizes are stored in compressed files, it follows
-that the flags \-1 to \-9 are irrelevant to and so ignored
-during decompression.
-
-Compression and decompression requirements,
-in bytes, can be estimated as:
-
- Compression: 400k + ( 8 x block size )
-
- Decompression: 100k + ( 4 x block size ), or
- 100k + ( 2.5 x block size )
-
-Larger block sizes give rapidly diminishing marginal returns. Most of
-the compression comes from the first two or three hundred k of block
-size, a fact worth bearing in mind when using
-.I bzip2
-on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block size.
-
-For files compressed with the default 900k block size,
-.I bunzip2
-will require about 3700 kbytes to decompress. To support decompression
-of any file on a 4 megabyte machine,
-.I bunzip2
-has an option to
-decompress using approximately half this amount of memory, about 2300
-kbytes. Decompression speed is also halved, so you should use this
-option only where necessary. The relevant flag is -s.
-
-In general, try and use the largest block size memory constraints allow,
-since that maximises the compression achieved. Compression and
-decompression speed are virtually unaffected by block size.
-
-Another significant point applies to files which fit in a single block
--- that means most files you'd encounter using a large block size. The
-amount of real memory touched is proportional to the size of the file,
-since the file is smaller than a block. For example, compressing a file
-20,000 bytes long with the flag -9 will cause the compressor to
-allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
-kbytes of it. Similarly, the decompressor will allocate 3700k but only
-touch 100k + 20000 * 4 = 180 kbytes.
-
-Here is a table which summarises the maximum memory usage for different
-block sizes. Also recorded is the total compressed size for 14 files of
-the Calgary Text Compression Corpus totalling 3,141,622 bytes. This
-column gives some feel for how compression varies with block size.
-These figures tend to understate the advantage of larger block sizes for
-larger files, since the Corpus is dominated by smaller files.
-
- Compress Decompress Decompress Corpus
- Flag usage usage -s usage Size
-
- -1 1200k 500k 350k 914704
- -2 2000k 900k 600k 877703
- -3 2800k 1300k 850k 860338
- -4 3600k 1700k 1100k 846899
- -5 4400k 2100k 1350k 845160
- -6 5200k 2500k 1600k 838626
- -7 6100k 2900k 1850k 834096
- -8 6800k 3300k 2100k 828642
- -9 7600k 3700k 2350k 828642
-
-.SH RECOVERING DATA FROM DAMAGED FILES
-.I bzip2
-compresses files in blocks, usually 900kbytes long. Each
-block is handled independently. If a media or transmission error causes
-a multi-block .bz2
-file to become damaged, it may be possible to
-recover data from the undamaged blocks in the file.
-
-The compressed representation of each block is delimited by a 48-bit
-pattern, which makes it possible to find the block boundaries with
-reasonable certainty. Each block also carries its own 32-bit CRC, so
-damaged blocks can be distinguished from undamaged ones.
-
-.I bzip2recover
-is a simple program whose purpose is to search for
-blocks in .bz2 files, and write each block out into its own .bz2
-file. You can then use
-.I bzip2
-\-t
-to test the
-integrity of the resulting files, and decompress those which are
-undamaged.
-
-.I bzip2recover
-takes a single argument, the name of the damaged file,
-and writes a number of files "rec00001file.bz2",
-"rec00002file.bz2", etc, containing the extracted blocks.
-The output filenames are designed so that the use of
-wildcards in subsequent processing -- for example,
-"bzip2 -dc rec*file.bz2 > recovered_data" -- processes the files in
-the correct order.
-
-.I bzip2recover
-should be of most use dealing with large .bz2
-files, as these will contain many blocks. It is clearly
-futile to use it on damaged single-block files, since a
-damaged block cannot be recovered. If you wish to minimise
-any potential data loss through media or transmission errors,
-you might consider compressing with a smaller
-block size.
-
-.SH PERFORMANCE NOTES
-The sorting phase of compression gathers together similar strings in the
-file. Because of this, files containing very long runs of repeated
-symbols, like "aabaabaabaab ..." (repeated several hundred times) may
-compress more slowly than normal. Versions 0.9.5 and above fare much
-better than previous versions in this respect. The ratio between
-worst-case and average-case compression time is in the region of 10:1.
-For previous versions, this figure was more like 100:1. You can use the
-\-vvvv option to monitor progress in great detail, if you want.
-
-Decompression speed is unaffected by these phenomena.
-
-.I bzip2
-usually allocates several megabytes of memory to operate
-in, and then charges all over it in a fairly random fashion. This means
-that performance, both for compressing and decompressing, is largely
-determined by the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss rate have
-been observed to give disproportionately large performance improvements.
-I imagine
-.I bzip2
-will perform best on machines with very large caches.
-
-.SH CAVEATS
-I/O error messages are not as helpful as they could be.
-.I bzip2
-tries hard to detect I/O errors and exit cleanly, but the details of
-what the problem is sometimes seem rather misleading.
-
-This manual page pertains to version 1.0.3 of
-.I bzip2.
-Compressed data created by this version is entirely forwards and
-backwards compatible with the previous public releases, versions
-0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and 1.0.2, but with the following
-exception: 0.9.0 and above can correctly decompress multiple
-concatenated compressed files. 0.1pl2 cannot do this; it will stop
-after decompressing just the first file in the stream.
-
-.I bzip2recover
-versions prior to 1.0.2 used 32-bit integers to represent
-bit positions in compressed files, so they could not handle compressed
-files more than 512 megabytes long. Versions 1.0.2 and above use
-64-bit ints on some platforms which support them (GNU supported
-targets, and Windows). To establish whether or not bzip2recover was
-built with such a limitation, run it without arguments. In any event
-you can build yourself an unlimited version if you can recompile it
-with MaybeUInt64 set to be an unsigned 64-bit integer.
-
-
-
-.SH AUTHOR
-Julian Seward, jsewardbzip.org.
-
-http://www.bzip.org
-
-The ideas embodied in
-.I bzip2
-are due to (at least) the following
-people: Michael Burrows and David Wheeler (for the block sorting
-transformation), David Wheeler (again, for the Huffman coder), Peter
-Fenwick (for the structured coding model in the original
-.I bzip,
-and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-.I bzip).
-I am much
-indebted for their help, support and advice. See the manual in the
-source distribution for pointers to sources of documentation. Christian
-von Roques encouraged me to look for faster sorting algorithms, so as to
-speed up compression. Bela Lubkin encouraged me to improve the
-worst-case compression performance.
-Donna Robinson XMLised the documentation.
-The bz* scripts are derived from those of GNU gzip.
-Many people sent patches, helped
-with portability problems, lent machines, gave advice and were generally
-helpful.
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1.preformatted b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1.preformatted
deleted file mode 100644
index 129ca835c9c..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.1.preformatted
+++ /dev/null
@@ -1,399 +0,0 @@
-bzip2(1) bzip2(1)
-
-
-
-NNAAMMEE
- bzip2, bunzip2 − a blockâ€sorting file compressor, v1.0.3
- bzcat − decompresses files to stdout
- bzip2recover − recovers data from damaged bzip2 files
-
-
-SSYYNNOOPPSSIISS
- bbzziipp22 [ −−ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._. ]
- bbuunnzziipp22 [ −−ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._. ]
- bbzzccaatt [ −−ss ] [ _f_i_l_e_n_a_m_e_s _._._. ]
- bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e
-
-
-DDEESSCCRRIIPPTTIIOONN
- _b_z_i_p_2 compresses files using the Burrowsâ€Wheeler block
- sorting text compression algorithm, and Huffman coding.
- Compression is generally considerably better than that
- achieved by more conventional LZ77/LZ78â€based compressors,
- and approaches the performance of the PPM family of sta­
- tistical compressors.
-
- The commandâ€line options are deliberately very similar to
- those of _G_N_U _g_z_i_p_, but they are not identical.
-
- _b_z_i_p_2 expects a list of file names to accompany the com­
- mandâ€line flags. Each file is replaced by a compressed
- version of itself, with the name "original_name.bz2".
- Each compressed file has the same modification date, per­
- missions, and, when possible, ownership as the correspond­
- ing original, so that these properties can be correctly
- restored at decompression time. File name handling is
- naive in the sense that there is no mechanism for preserv­
- ing original file names, permissions, ownerships or dates
- in filesystems which lack these concepts, or have serious
- file name length restrictions, such as MSâ€DOS.
-
- _b_z_i_p_2 and _b_u_n_z_i_p_2 will by default not overwrite existing
- files. If you want this to happen, specify the −f flag.
-
- If no file names are specified, _b_z_i_p_2 compresses from
- standard input to standard output. In this case, _b_z_i_p_2
- will decline to write compressed output to a terminal, as
- this would be entirely incomprehensible and therefore
- pointless.
-
- _b_u_n_z_i_p_2 (or _b_z_i_p_2 _−_d_) decompresses all specified files.
- Files which were not created by _b_z_i_p_2 will be detected and
- ignored, and a warning issued. _b_z_i_p_2 attempts to guess
- the filename for the decompressed file from that of the
- compressed file as follows:
-
- filename.bz2 becomes filename
- filename.bz becomes filename
- filename.tbz2 becomes filename.tar
- filename.tbz becomes filename.tar
- anyothername becomes anyothername.out
-
- If the file does not end in one of the recognised endings,
- _._b_z_2_, _._b_z_, _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot
- guess the name of the original file, and uses the original
- name with _._o_u_t appended.
-
- As with compression, supplying no filenames causes decom­
- pression from standard input to standard output.
-
- _b_u_n_z_i_p_2 will correctly decompress a file which is the con­
- catenation of two or more compressed files. The result is
- the concatenation of the corresponding uncompressed files.
- Integrity testing (−t) of concatenated compressed files is
- also supported.
-
- You can also compress or decompress files to the standard
- output by giving the −c flag. Multiple files may be com­
- pressed and decompressed like this. The resulting outputs
- are fed sequentially to stdout. Compression of multiple
- files in this manner generates a stream containing multi­
- ple compressed file representations. Such a stream can be
- decompressed correctly only by _b_z_i_p_2 version 0.9.0 or
- later. Earlier versions of _b_z_i_p_2 will stop after decom­
- pressing the first file in the stream.
-
- _b_z_c_a_t (or _b_z_i_p_2 _â€_d_c_) decompresses all specified files to
- the standard output.
-
- _b_z_i_p_2 will read arguments from the environment variables
- _B_Z_I_P_2 and _B_Z_I_P_, in that order, and will process them
- before any arguments read from the command line. This
- gives a convenient way to supply default arguments.
-
- Compression is always performed, even if the compressed
- file is slightly larger than the original. Files of less
- than about one hundred bytes tend to get larger, since the
- compression mechanism has a constant overhead in the
- region of 50 bytes. Random data (including the output of
- most file compressors) is coded at about 8.05 bits per
- byte, giving an expansion of around 0.5%.
-
- As a selfâ€check for your protection, _b_z_i_p_2 uses 32â€bit
- CRCs to make sure that the decompressed version of a file
- is identical to the original. This guards against corrup­
- tion of the compressed data, and against undetected bugs
- in _b_z_i_p_2 (hopefully very unlikely). The chances of data
- corruption going undetected is microscopic, about one
- chance in four billion for each file processed. Be aware,
- though, that the check occurs upon decompression, so it
- can only tell you that something is wrong. It can’t help
- you recover the original uncompressed data. You can use
- _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
-
- Return values: 0 for a normal exit, 1 for environmental
- problems (file not found, invalid flags, I/O errors, &c),
- 2 to indicate a corrupt compressed file, 3 for an internal
- consistency error (eg, bug) which caused _b_z_i_p_2 to panic.
-
-
-OOPPTTIIOONNSS
- −−cc â€â€â€â€ssttddoouutt
- Compress or decompress to standard output.
-
- −−dd â€â€â€â€ddeeccoommpprreessss
- Force decompression. _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are
- really the same program, and the decision about
- what actions to take is done on the basis of which
- name is used. This flag overrides that mechanism,
- and forces _b_z_i_p_2 to decompress.
-
- −−zz â€â€â€â€ccoommpprreessss
- The complement to −d: forces compression,
- regardless of the invocation name.
-
- −−tt â€â€â€â€tteesstt
- Check integrity of the specified file(s), but don’t
- decompress them. This really performs a trial
- decompression and throws away the result.
-
- −−ff â€â€â€â€ffoorrccee
- Force overwrite of output files. Normally, _b_z_i_p_2
- will not overwrite existing output files. Also
- forces _b_z_i_p_2 to break hard links to files, which it
- otherwise wouldn’t do.
-
- bzip2 normally declines to decompress files which
- don’t have the correct magic header bytes. If
- forced (â€f), however, it will pass such files
- through unmodified. This is how GNU gzip behaves.
-
- −−kk â€â€â€â€kkeeeepp
- Keep (don’t delete) input files during compression
- or decompression.
-
- −−ss â€â€â€â€ssmmaallll
- Reduce memory usage, for compression, decompression
- and testing. Files are decompressed and tested
- using a modified algorithm which only requires 2.5
- bytes per block byte. This means any file can be
- decompressed in 2300k of memory, albeit at about
- half the normal speed.
-
- During compression, −s selects a block size of
- 200k, which limits memory use to around the same
- figure, at the expense of your compression ratio.
- In short, if your machine is low on memory (8
- megabytes or less), use −s for everything. See
- MEMORY MANAGEMENT below.
-
- −−qq â€â€â€â€qquuiieett
- Suppress nonâ€essential warning messages. Messages
- pertaining to I/O errors and other critical events
- will not be suppressed.
-
- −−vv â€â€â€â€vveerrbboossee
- Verbose mode â€â€ show the compression ratio for each
- file processed. Further −v’s increase the ver­
- bosity level, spewing out lots of information which
- is primarily of interest for diagnostic purposes.
-
- −−LL â€â€â€â€lliicceennssee â€â€VV â€â€â€â€vveerrssiioonn
- Display the software version, license terms and
- conditions.
-
- −−11 ((oorr −−−−ffaasstt)) ttoo −−99 ((oorr −−−−bbeesstt))
- Set the block size to 100 k, 200 k .. 900 k when
- compressing. Has no effect when decompressing.
- See MEMORY MANAGEMENT below. The −−fast and −−best
- aliases are primarily for GNU gzip compatibility.
- In particular, −−fast doesn’t make things signifi­
- cantly faster. And −−best merely selects the
- default behaviour.
-
- −− Treats all subsequent arguments as file names, even
- if they start with a dash. This is so you can han­
- dle files with names beginning with a dash, for
- example: bzip2 −†−myfilename.
-
- −−â€â€rreeppeettiittiivveeâ€â€ffaasstt â€â€â€â€rreeppeettiittiivveeâ€â€bbeesstt
- These flags are redundant in versions 0.9.5 and
- above. They provided some coarse control over the
- behaviour of the sorting algorithm in earlier ver­
- sions, which was sometimes useful. 0.9.5 and above
- have an improved algorithm which renders these
- flags irrelevant.
-
-
-MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
- _b_z_i_p_2 compresses large files in blocks. The block size
- affects both the compression ratio achieved, and the
- amount of memory needed for compression and decompression.
- The flags −1 through −9 specify the block size to be
- 100,000 bytes through 900,000 bytes (the default) respec­
- tively. At decompression time, the block size used for
- compression is read from the header of the compressed
- file, and _b_u_n_z_i_p_2 then allocates itself just enough memory
- to decompress the file. Since block sizes are stored in
- compressed files, it follows that the flags −1 to −9 are
- irrelevant to and so ignored during decompression.
-
- Compression and decompression requirements, in bytes, can
- be estimated as:
-
- Compression: 400k + ( 8 x block size )
-
- Decompression: 100k + ( 4 x block size ), or
- 100k + ( 2.5 x block size )
-
- Larger block sizes give rapidly diminishing marginal
- returns. Most of the compression comes from the first two
- or three hundred k of block size, a fact worth bearing in
- mind when using _b_z_i_p_2 on small machines. It is also
- important to appreciate that the decompression memory
- requirement is set at compression time by the choice of
- block size.
-
- For files compressed with the default 900k block size,
- _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress. To
- support decompression of any file on a 4 megabyte machine,
- _b_u_n_z_i_p_2 has an option to decompress using approximately
- half this amount of memory, about 2300 kbytes. Decompres­
- sion speed is also halved, so you should use this option
- only where necessary. The relevant flag is â€s.
-
- In general, try and use the largest block size memory con­
- straints allow, since that maximises the compression
- achieved. Compression and decompression speed are virtu­
- ally unaffected by block size.
-
- Another significant point applies to files which fit in a
- single block â€â€ that means most files you’d encounter
- using a large block size. The amount of real memory
- touched is proportional to the size of the file, since the
- file is smaller than a block. For example, compressing a
- file 20,000 bytes long with the flag â€9 will cause the
- compressor to allocate around 7600k of memory, but only
- touch 400k + 20000 * 8 = 560 kbytes of it. Similarly, the
- decompressor will allocate 3700k but only touch 100k +
- 20000 * 4 = 180 kbytes.
-
- Here is a table which summarises the maximum memory usage
- for different block sizes. Also recorded is the total
- compressed size for 14 files of the Calgary Text Compres­
- sion Corpus totalling 3,141,622 bytes. This column gives
- some feel for how compression varies with block size.
- These figures tend to understate the advantage of larger
- block sizes for larger files, since the Corpus is domi­
- nated by smaller files.
-
- Compress Decompress Decompress Corpus
- Flag usage usage â€s usage Size
-
- â€1 1200k 500k 350k 914704
- â€2 2000k 900k 600k 877703
- â€3 2800k 1300k 850k 860338
- â€4 3600k 1700k 1100k 846899
- â€5 4400k 2100k 1350k 845160
- â€6 5200k 2500k 1600k 838626
- â€7 6100k 2900k 1850k 834096
- â€8 6800k 3300k 2100k 828642
- â€9 7600k 3700k 2350k 828642
-
-
-RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
- _b_z_i_p_2 compresses files in blocks, usually 900kbytes long.
- Each block is handled independently. If a media or trans­
- mission error causes a multiâ€block .bz2 file to become
- damaged, it may be possible to recover data from the
- undamaged blocks in the file.
-
- The compressed representation of each block is delimited
- by a 48â€bit pattern, which makes it possible to find the
- block boundaries with reasonable certainty. Each block
- also carries its own 32â€bit CRC, so damaged blocks can be
- distinguished from undamaged ones.
-
- _b_z_i_p_2_r_e_c_o_v_e_r is a simple program whose purpose is to
- search for blocks in .bz2 files, and write each block out
- into its own .bz2 file. You can then use _b_z_i_p_2 −t to test
- the integrity of the resulting files, and decompress those
- which are undamaged.
-
- _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam­
- aged file, and writes a number of files
- "rec00001file.bz2", "rec00002file.bz2", etc, containing
- the extracted blocks. The output filenames are
- designed so that the use of wildcards in subsequent pro­
- cessing â€â€ for example, "bzip2 â€dc rec*file.bz2 > recov­
- ered_data" â€â€ processes the files in the correct order.
-
- _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2
- files, as these will contain many blocks. It is clearly
- futile to use it on damaged singleâ€block files, since a
- damaged block cannot be recovered. If you wish to min­
- imise any potential data loss through media or transmis­
- sion errors, you might consider compressing with a smaller
- block size.
-
-
-PPEERRFFOORRMMAANNCCEE NNOOTTEESS
- The sorting phase of compression gathers together similar
- strings in the file. Because of this, files containing
- very long runs of repeated symbols, like "aabaabaabaab
- ..." (repeated several hundred times) may compress more
- slowly than normal. Versions 0.9.5 and above fare much
- better than previous versions in this respect. The ratio
- between worstâ€case and averageâ€case compression time is in
- the region of 10:1. For previous versions, this figure
- was more like 100:1. You can use the −vvvv option to mon­
- itor progress in great detail, if you want.
-
- Decompression speed is unaffected by these phenomena.
-
- _b_z_i_p_2 usually allocates several megabytes of memory to
- operate in, and then charges all over it in a fairly ran­
- dom fashion. This means that performance, both for com­
- pressing and decompressing, is largely determined by the
- speed at which your machine can service cache misses.
- Because of this, small changes to the code to reduce the
- miss rate have been observed to give disproportionately
- large performance improvements. I imagine _b_z_i_p_2 will per­
- form best on machines with very large caches.
-
-
-CCAAVVEEAATTSS
- I/O error messages are not as helpful as they could be.
- _b_z_i_p_2 tries hard to detect I/O errors and exit cleanly,
- but the details of what the problem is sometimes seem
- rather misleading.
-
- This manual page pertains to version 1.0.3 of _b_z_i_p_2_. Com­
- pressed data created by this version is entirely forwards
- and backwards compatible with the previous public
- releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and
- 1.0.2, but with the following exception: 0.9.0 and above
- can correctly decompress multiple concatenated compressed
- files. 0.1pl2 cannot do this; it will stop after decom­
- pressing just the first file in the stream.
-
- _b_z_i_p_2_r_e_c_o_v_e_r versions prior to 1.0.2 used 32â€bit integers
- to represent bit positions in compressed files, so they
- could not handle compressed files more than 512 megabytes
- long. Versions 1.0.2 and above use 64â€bit ints on some
- platforms which support them (GNU supported targets, and
- Windows). To establish whether or not bzip2recover was
- built with such a limitation, run it without arguments.
- In any event you can build yourself an unlimited version
- if you can recompile it with MaybeUInt64 set to be an
- unsigned 64â€bit integer.
-
-
-
-
-AAUUTTHHOORR
- Julian Seward, jsewardbzip.org.
-
- http://www.bzip.org
-
- The ideas embodied in _b_z_i_p_2 are due to (at least) the fol­
- lowing people: Michael Burrows and David Wheeler (for the
- block sorting transformation), David Wheeler (again, for
- the Huffman coder), Peter Fenwick (for the structured cod­
- ing model in the original _b_z_i_p_, and many refinements), and
- Alistair Moffat, Radford Neal and Ian Witten (for the
- arithmetic coder in the original _b_z_i_p_)_. I am much
- indebted for their help, support and advice. See the man­
- ual in the source distribution for pointers to sources of
- documentation. Christian von Roques encouraged me to look
- for faster sorting algorithms, so as to speed up compres­
- sion. Bela Lubkin encouraged me to improve the worstâ€case
- compression performance. Donna Robinson XMLised the docu­
- mentation. The bz* scripts are derived from those of GNU
- gzip. Many people sent patches, helped with portability
- problems, lent machines, gave advice and were generally
- helpful.
-
-
-
- bzip2(1)
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.c b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.c
deleted file mode 100644
index 79f87a51986..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.c
+++ /dev/null
@@ -1,2107 +0,0 @@
-
-/*-----------------------------------------------------------*/
-/*--- A block-sorting, lossless compressor bzip2.c ---*/
-/*-----------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-/*----------------------------------------------------*/
-/*--- IMPORTANT ---*/
-/*----------------------------------------------------*/
-
-/*--
- WARNING:
- This program and library (attempts to) compress data by
- performing several non-trivial transformations on it.
- Unless you are 100% familiar with *all* the algorithms
- contained herein, and with the consequences of modifying them,
- you should NOT meddle with the compression or decompression
- machinery. Incorrect changes can and very likely *will*
- lead to disasterous loss of data.
-
- DISCLAIMER:
- I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
- USE OF THIS PROGRAM, HOWSOEVER CAUSED.
-
- Every compression of a file implies an assumption that the
- compressed file can be decompressed to reproduce the original.
- Great efforts in design, coding and testing have been made to
- ensure that this program works correctly. However, the
- complexity of the algorithms, and, in particular, the presence
- of various special cases in the code which occur with very low
- but non-zero probability make it impossible to rule out the
- possibility of bugs remaining in the program. DO NOT COMPRESS
- ANY DATA WITH THIS PROGRAM AND/OR LIBRARY UNLESS YOU ARE PREPARED
- TO ACCEPT THE POSSIBILITY, HOWEVER SMALL, THAT THE DATA WILL
- NOT BE RECOVERABLE.
-
- That is not to say this program is inherently unreliable.
- Indeed, I very much hope the opposite is true. bzip2/libbzip2
- has been carefully constructed and extensively tested.
-
- PATENTS:
- To the best of my knowledge, bzip2/libbzip2 does not use any
- patented algorithms. However, I do not have the resources
- available to carry out a full patent search. Therefore I cannot
- give any guarantee of the above statement.
---*/
-
-
-
-/*----------------------------------------------------*/
-/*--- and now for something much more pleasant :-) ---*/
-/*----------------------------------------------------*/
-
-/*---------------------------------------------*/
-/*--
- Place a 1 beside your platform, and 0 elsewhere.
---*/
-
-/*--
- Generic 32-bit Unix.
- Also works on 64-bit Unix boxes.
- This is the default.
---*/
-#define BZ_UNIX 1
-
-/*--
- Win32, as seen by Jacob Navia's excellent
- port of (Chris Fraser & David Hanson)'s excellent
- lcc compiler. Or with MS Visual C.
- This is selected automatically if compiled by a compiler which
- defines _WIN32, not including the Cygwin GCC.
---*/
-#define BZ_LCCWIN32 0
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#undef BZ_LCCWIN32
-#define BZ_LCCWIN32 1
-#undef BZ_UNIX
-#define BZ_UNIX 0
-#endif
-
-
-/*---------------------------------------------*/
-/*--
- Some stuff for all platforms.
---*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <math.h>
-#include <errno.h>
-#include <ctype.h>
-#include "bzlib.h"
-
-#define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
-#define ERROR_IF_NOT_ZERO(i) { if ((i) != 0) ioError(); }
-#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
-
-
-/*---------------------------------------------*/
-/*--
- Platform-specific stuff.
---*/
-
-#if BZ_UNIX
-# include <fcntl.h>
-# include <sys/types.h>
-# include <utime.h>
-# include <unistd.h>
-# include <sys/stat.h>
-# include <sys/times.h>
-
-# define PATH_SEP '/'
-# define MY_LSTAT lstat
-# define MY_STAT stat
-# define MY_S_ISREG S_ISREG
-# define MY_S_ISDIR S_ISDIR
-
-# define APPEND_FILESPEC(root, name) \
- root=snocString((root), (name))
-
-# define APPEND_FLAG(root, name) \
- root=snocString((root), (name))
-
-# define SET_BINARY_MODE(fd) /**/
-
-# ifdef __GNUC__
-# define NORETURN __attribute__ ((noreturn))
-# else
-# define NORETURN /**/
-# endif
-
-# ifdef __DJGPP__
-# include <io.h>
-# include <fcntl.h>
-# undef MY_LSTAT
-# undef MY_STAT
-# define MY_LSTAT stat
-# define MY_STAT stat
-# undef SET_BINARY_MODE
-# define SET_BINARY_MODE(fd) \
- do { \
- int retVal = setmode ( fileno ( fd ), \
- O_BINARY ); \
- ERROR_IF_MINUS_ONE ( retVal ); \
- } while ( 0 )
-# endif
-
-# ifdef __CYGWIN__
-# include <io.h>
-# include <fcntl.h>
-# undef SET_BINARY_MODE
-# define SET_BINARY_MODE(fd) \
- do { \
- int retVal = setmode ( fileno ( fd ), \
- O_BINARY ); \
- ERROR_IF_MINUS_ONE ( retVal ); \
- } while ( 0 )
-# endif
-#endif /* BZ_UNIX */
-
-
-
-#if BZ_LCCWIN32
-# include <io.h>
-# include <fcntl.h>
-# include <sys\stat.h>
-
-# define NORETURN /**/
-# define PATH_SEP '\\'
-# define MY_LSTAT _stat
-# define MY_STAT _stat
-# define MY_S_ISREG(x) ((x) & _S_IFREG)
-# define MY_S_ISDIR(x) ((x) & _S_IFDIR)
-
-# define APPEND_FLAG(root, name) \
- root=snocString((root), (name))
-
-# define APPEND_FILESPEC(root, name) \
- root = snocString ((root), (name))
-
-# define SET_BINARY_MODE(fd) \
- do { \
- int retVal = setmode ( fileno ( fd ), \
- O_BINARY ); \
- ERROR_IF_MINUS_ONE ( retVal ); \
- } while ( 0 )
-
-#endif /* BZ_LCCWIN32 */
-
-
-/*---------------------------------------------*/
-/*--
- Some more stuff for all platforms :-)
---*/
-
-typedef char Char;
-typedef unsigned char Bool;
-typedef unsigned char UChar;
-typedef int Int32;
-typedef unsigned int UInt32;
-typedef short Int16;
-typedef unsigned short UInt16;
-
-#define True ((Bool)1)
-#define False ((Bool)0)
-
-/*--
- IntNative is your platform's `native' int size.
- Only here to avoid probs with 64-bit platforms.
---*/
-typedef int IntNative;
-
-
-/*---------------------------------------------------*/
-/*--- Misc (file handling) data decls ---*/
-/*---------------------------------------------------*/
-
-Int32 verbosity;
-Bool keepInputFiles, smallMode, deleteOutputOnInterrupt;
-Bool forceOverwrite, testFailsExist, unzFailsExist, noisy;
-Int32 numFileNames, numFilesProcessed, blockSize100k;
-Int32 exitValue;
-
-/*-- source modes; F==file, I==stdin, O==stdout --*/
-#define SM_I2O 1
-#define SM_F2O 2
-#define SM_F2F 3
-
-/*-- operation modes --*/
-#define OM_Z 1
-#define OM_UNZ 2
-#define OM_TEST 3
-
-Int32 opMode;
-Int32 srcMode;
-
-#define FILE_NAME_LEN 1034
-
-Int32 longestFileName;
-Char inName [FILE_NAME_LEN];
-Char outName[FILE_NAME_LEN];
-Char tmpName[FILE_NAME_LEN];
-Char *progName;
-Char progNameReally[FILE_NAME_LEN];
-FILE *outputHandleJustInCase;
-Int32 workFactor;
-
-static void panic ( Char* ) NORETURN;
-static void ioError ( void ) NORETURN;
-static void outOfMemory ( void ) NORETURN;
-static void configError ( void ) NORETURN;
-static void crcError ( void ) NORETURN;
-static void cleanUpAndFail ( Int32 ) NORETURN;
-static void compressedStreamEOF ( void ) NORETURN;
-
-static void copyFileName ( Char*, Char* );
-static void* myMalloc ( Int32 );
-
-
-
-/*---------------------------------------------------*/
-/*--- An implementation of 64-bit ints. Sigh. ---*/
-/*--- Roll on widespread deployment of ANSI C9X ! ---*/
-/*---------------------------------------------------*/
-
-typedef
- struct { UChar b[8]; }
- UInt64;
-
-
-static
-void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
-{
- n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
- n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
- n->b[5] = (UChar)((hi32 >> 8) & 0xFF);
- n->b[4] = (UChar) (hi32 & 0xFF);
- n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
- n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
- n->b[1] = (UChar)((lo32 >> 8) & 0xFF);
- n->b[0] = (UChar) (lo32 & 0xFF);
-}
-
-
-static
-double uInt64_to_double ( UInt64* n )
-{
- Int32 i;
- double base = 1.0;
- double sum = 0.0;
- for (i = 0; i < 8; i++) {
- sum += base * (double)(n->b[i]);
- base *= 256.0;
- }
- return sum;
-}
-
-
-static
-Bool uInt64_isZero ( UInt64* n )
-{
- Int32 i;
- for (i = 0; i < 8; i++)
- if (n->b[i] != 0) return 0;
- return 1;
-}
-
-
-/* Divide *n by 10, and return the remainder. */
-static
-Int32 uInt64_qrm10 ( UInt64* n )
-{
- UInt32 rem, tmp;
- Int32 i;
- rem = 0;
- for (i = 7; i >= 0; i--) {
- tmp = rem * 256 + n->b[i];
- n->b[i] = tmp / 10;
- rem = tmp % 10;
- }
- return rem;
-}
-
-
-/* ... and the Whole Entire Point of all this UInt64 stuff is
- so that we can supply the following function.
-*/
-static
-void uInt64_toAscii ( char* outbuf, UInt64* n )
-{
- Int32 i, q;
- UChar buf[32];
- Int32 nBuf = 0;
- UInt64 n_copy = *n;
- do {
- q = uInt64_qrm10 ( &n_copy );
- buf[nBuf] = q + '0';
- nBuf++;
- } while (!uInt64_isZero(&n_copy));
- outbuf[nBuf] = 0;
- for (i = 0; i < nBuf; i++)
- outbuf[i] = buf[nBuf-i-1];
-}
-
-
-/*---------------------------------------------------*/
-/*--- Processing of complete files and streams ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-Bool myfeof ( FILE* f )
-{
- Int32 c = fgetc ( f );
- if (c == EOF) return True;
- ungetc ( c, f );
- return False;
-}
-
-
-/*---------------------------------------------*/
-static
-void compressStream ( FILE *stream, FILE *zStream )
-{
- BZFILE* bzf = NULL;
- UChar ibuf[5000];
- Int32 nIbuf;
- UInt32 nbytes_in_lo32, nbytes_in_hi32;
- UInt32 nbytes_out_lo32, nbytes_out_hi32;
- Int32 bzerr, bzerr_dummy, ret;
-
- SET_BINARY_MODE(stream);
- SET_BINARY_MODE(zStream);
-
- if (ferror(stream)) goto errhandler_io;
- if (ferror(zStream)) goto errhandler_io;
-
- bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
- blockSize100k, verbosity, workFactor );
- if (bzerr != BZ_OK) goto errhandler;
-
- if (verbosity >= 2) fprintf ( stderr, "\n" );
-
- while (True) {
-
- if (myfeof(stream)) break;
- nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
- if (ferror(stream)) goto errhandler_io;
- if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
- if (bzerr != BZ_OK) goto errhandler;
-
- }
-
- BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
- &nbytes_in_lo32, &nbytes_in_hi32,
- &nbytes_out_lo32, &nbytes_out_hi32 );
- if (bzerr != BZ_OK) goto errhandler;
-
- if (ferror(zStream)) goto errhandler_io;
- ret = fflush ( zStream );
- if (ret == EOF) goto errhandler_io;
- if (zStream != stdout) {
- ret = fclose ( zStream );
- outputHandleJustInCase = NULL;
- if (ret == EOF) goto errhandler_io;
- }
- outputHandleJustInCase = NULL;
- if (ferror(stream)) goto errhandler_io;
- ret = fclose ( stream );
- if (ret == EOF) goto errhandler_io;
-
- if (verbosity >= 1) {
- if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
- fprintf ( stderr, " no data compressed.\n");
- } else {
- Char buf_nin[32], buf_nout[32];
- UInt64 nbytes_in, nbytes_out;
- double nbytes_in_d, nbytes_out_d;
- uInt64_from_UInt32s ( &nbytes_in,
- nbytes_in_lo32, nbytes_in_hi32 );
- uInt64_from_UInt32s ( &nbytes_out,
- nbytes_out_lo32, nbytes_out_hi32 );
- nbytes_in_d = uInt64_to_double ( &nbytes_in );
- nbytes_out_d = uInt64_to_double ( &nbytes_out );
- uInt64_toAscii ( buf_nin, &nbytes_in );
- uInt64_toAscii ( buf_nout, &nbytes_out );
- fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
- "%5.2f%% saved, %s in, %s out.\n",
- nbytes_in_d / nbytes_out_d,
- (8.0 * nbytes_out_d) / nbytes_in_d,
- 100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
- buf_nin,
- buf_nout
- );
- }
- }
-
- return;
-
- errhandler:
- BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
- &nbytes_in_lo32, &nbytes_in_hi32,
- &nbytes_out_lo32, &nbytes_out_hi32 );
- switch (bzerr) {
- case BZ_CONFIG_ERROR:
- configError(); break;
- case BZ_MEM_ERROR:
- outOfMemory (); break;
- case BZ_IO_ERROR:
- errhandler_io:
- ioError(); break;
- default:
- panic ( "compress:unexpected error" );
- }
-
- panic ( "compress:end" );
- /*notreached*/
-}
-
-
-
-/*---------------------------------------------*/
-static
-Bool uncompressStream ( FILE *zStream, FILE *stream )
-{
- BZFILE* bzf = NULL;
- Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
- UChar obuf[5000];
- UChar unused[BZ_MAX_UNUSED];
- Int32 nUnused;
- void* unusedTmpV;
- UChar* unusedTmp;
-
- nUnused = 0;
- streamNo = 0;
-
- SET_BINARY_MODE(stream);
- SET_BINARY_MODE(zStream);
-
- if (ferror(stream)) goto errhandler_io;
- if (ferror(zStream)) goto errhandler_io;
-
- while (True) {
-
- bzf = BZ2_bzReadOpen (
- &bzerr, zStream, verbosity,
- (int)smallMode, unused, nUnused
- );
- if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
- streamNo++;
-
- while (bzerr == BZ_OK) {
- nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
- if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
- if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
- fwrite ( obuf, sizeof(UChar), nread, stream );
- if (ferror(stream)) goto errhandler_io;
- }
- if (bzerr != BZ_STREAM_END) goto errhandler;
-
- BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
- if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
-
- unusedTmp = (UChar*)unusedTmpV;
- for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
-
- BZ2_bzReadClose ( &bzerr, bzf );
- if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
-
- if (nUnused == 0 && myfeof(zStream)) break;
- }
-
- closeok:
- if (ferror(zStream)) goto errhandler_io;
- ret = fclose ( zStream );
- if (ret == EOF) goto errhandler_io;
-
- if (ferror(stream)) goto errhandler_io;
- ret = fflush ( stream );
- if (ret != 0) goto errhandler_io;
- if (stream != stdout) {
- ret = fclose ( stream );
- outputHandleJustInCase = NULL;
- if (ret == EOF) goto errhandler_io;
- }
- outputHandleJustInCase = NULL;
- if (verbosity >= 2) fprintf ( stderr, "\n " );
- return True;
-
- trycat:
- if (forceOverwrite) {
- rewind(zStream);
- while (True) {
- if (myfeof(zStream)) break;
- nread = fread ( obuf, sizeof(UChar), 5000, zStream );
- if (ferror(zStream)) goto errhandler_io;
- if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
- if (ferror(stream)) goto errhandler_io;
- }
- goto closeok;
- }
-
- errhandler:
- BZ2_bzReadClose ( &bzerr_dummy, bzf );
- switch (bzerr) {
- case BZ_CONFIG_ERROR:
- configError(); break;
- case BZ_IO_ERROR:
- errhandler_io:
- ioError(); break;
- case BZ_DATA_ERROR:
- crcError();
- case BZ_MEM_ERROR:
- outOfMemory();
- case BZ_UNEXPECTED_EOF:
- compressedStreamEOF();
- case BZ_DATA_ERROR_MAGIC:
- if (zStream != stdin) fclose(zStream);
- if (stream != stdout) fclose(stream);
- if (streamNo == 1) {
- return False;
- } else {
- if (noisy)
- fprintf ( stderr,
- "\n%s: %s: trailing garbage after EOF ignored\n",
- progName, inName );
- return True;
- }
- default:
- panic ( "decompress:unexpected error" );
- }
-
- panic ( "decompress:end" );
- return True; /*notreached*/
-}
-
-
-/*---------------------------------------------*/
-static
-Bool testStream ( FILE *zStream )
-{
- BZFILE* bzf = NULL;
- Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
- UChar obuf[5000];
- UChar unused[BZ_MAX_UNUSED];
- Int32 nUnused;
- void* unusedTmpV;
- UChar* unusedTmp;
-
- nUnused = 0;
- streamNo = 0;
-
- SET_BINARY_MODE(zStream);
- if (ferror(zStream)) goto errhandler_io;
-
- while (True) {
-
- bzf = BZ2_bzReadOpen (
- &bzerr, zStream, verbosity,
- (int)smallMode, unused, nUnused
- );
- if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
- streamNo++;
-
- while (bzerr == BZ_OK) {
- nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
- if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
- }
- if (bzerr != BZ_STREAM_END) goto errhandler;
-
- BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
- if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
-
- unusedTmp = (UChar*)unusedTmpV;
- for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
-
- BZ2_bzReadClose ( &bzerr, bzf );
- if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
- if (nUnused == 0 && myfeof(zStream)) break;
-
- }
-
- if (ferror(zStream)) goto errhandler_io;
- ret = fclose ( zStream );
- if (ret == EOF) goto errhandler_io;
-
- if (verbosity >= 2) fprintf ( stderr, "\n " );
- return True;
-
- errhandler:
- BZ2_bzReadClose ( &bzerr_dummy, bzf );
- if (verbosity == 0)
- fprintf ( stderr, "%s: %s: ", progName, inName );
- switch (bzerr) {
- case BZ_CONFIG_ERROR:
- configError(); break;
- case BZ_IO_ERROR:
- errhandler_io:
- ioError(); break;
- case BZ_DATA_ERROR:
- fprintf ( stderr,
- "data integrity (CRC) error in data\n" );
- return False;
- case BZ_MEM_ERROR:
- outOfMemory();
- case BZ_UNEXPECTED_EOF:
- fprintf ( stderr,
- "file ends unexpectedly\n" );
- return False;
- case BZ_DATA_ERROR_MAGIC:
- if (zStream != stdin) fclose(zStream);
- if (streamNo == 1) {
- fprintf ( stderr,
- "bad magic number (file not created by bzip2)\n" );
- return False;
- } else {
- if (noisy)
- fprintf ( stderr,
- "trailing garbage after EOF ignored\n" );
- return True;
- }
- default:
- panic ( "test:unexpected error" );
- }
-
- panic ( "test:end" );
- return True; /*notreached*/
-}
-
-
-/*---------------------------------------------------*/
-/*--- Error [non-] handling grunge ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-void setExit ( Int32 v )
-{
- if (v > exitValue) exitValue = v;
-}
-
-
-/*---------------------------------------------*/
-static
-void cadvise ( void )
-{
- if (noisy)
- fprintf (
- stderr,
- "\nIt is possible that the compressed file(s) have become corrupted.\n"
- "You can use the -tvv option to test integrity of such files.\n\n"
- "You can use the `bzip2recover' program to attempt to recover\n"
- "data from undamaged sections of corrupted files.\n\n"
- );
-}
-
-
-/*---------------------------------------------*/
-static
-void showFileNames ( void )
-{
- if (noisy)
- fprintf (
- stderr,
- "\tInput file = %s, output file = %s\n",
- inName, outName
- );
-}
-
-
-/*---------------------------------------------*/
-static
-void cleanUpAndFail ( Int32 ec )
-{
- IntNative retVal;
- struct MY_STAT statBuf;
-
- if ( srcMode == SM_F2F
- && opMode != OM_TEST
- && deleteOutputOnInterrupt ) {
-
- /* Check whether input file still exists. Delete output file
- only if input exists to avoid loss of data. Joerg Prante, 5
- January 2002. (JRS 06-Jan-2002: other changes in 1.0.2 mean
- this is less likely to happen. But to be ultra-paranoid, we
- do the check anyway.) */
- retVal = MY_STAT ( inName, &statBuf );
- if (retVal == 0) {
- if (noisy)
- fprintf ( stderr,
- "%s: Deleting output file %s, if it exists.\n",
- progName, outName );
- if (outputHandleJustInCase != NULL)
- fclose ( outputHandleJustInCase );
- retVal = remove ( outName );
- if (retVal != 0)
- fprintf ( stderr,
- "%s: WARNING: deletion of output file "
- "(apparently) failed.\n",
- progName );
- } else {
- fprintf ( stderr,
- "%s: WARNING: deletion of output file suppressed\n",
- progName );
- fprintf ( stderr,
- "%s: since input file no longer exists. Output file\n",
- progName );
- fprintf ( stderr,
- "%s: `%s' may be incomplete.\n",
- progName, outName );
- fprintf ( stderr,
- "%s: I suggest doing an integrity test (bzip2 -tv)"
- " of it.\n",
- progName );
- }
- }
-
- if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
- fprintf ( stderr,
- "%s: WARNING: some files have not been processed:\n"
- "%s: %d specified on command line, %d not processed yet.\n\n",
- progName, progName,
- numFileNames, numFileNames - numFilesProcessed );
- }
- setExit(ec);
- exit(exitValue);
-}
-
-
-/*---------------------------------------------*/
-static
-void panic ( Char* s )
-{
- fprintf ( stderr,
- "\n%s: PANIC -- internal consistency error:\n"
- "\t%s\n"
- "\tThis is a BUG. Please report it to me at:\n"
- "\tjseward@bzip.org\n",
- progName, s );
- showFileNames();
- cleanUpAndFail( 3 );
-}
-
-
-/*---------------------------------------------*/
-static
-void crcError ( void )
-{
- fprintf ( stderr,
- "\n%s: Data integrity error when decompressing.\n",
- progName );
- showFileNames();
- cadvise();
- cleanUpAndFail( 2 );
-}
-
-
-/*---------------------------------------------*/
-static
-void compressedStreamEOF ( void )
-{
- if (noisy) {
- fprintf ( stderr,
- "\n%s: Compressed file ends unexpectedly;\n\t"
- "perhaps it is corrupted? *Possible* reason follows.\n",
- progName );
- perror ( progName );
- showFileNames();
- cadvise();
- }
- cleanUpAndFail( 2 );
-}
-
-
-/*---------------------------------------------*/
-static
-void ioError ( void )
-{
- fprintf ( stderr,
- "\n%s: I/O or other error, bailing out. "
- "Possible reason follows.\n",
- progName );
- perror ( progName );
- showFileNames();
- cleanUpAndFail( 1 );
-}
-
-
-/*---------------------------------------------*/
-static
-void mySignalCatcher ( IntNative n )
-{
- fprintf ( stderr,
- "\n%s: Control-C or similar caught, quitting.\n",
- progName );
- cleanUpAndFail(1);
-}
-
-
-/*---------------------------------------------*/
-static
-void mySIGSEGVorSIGBUScatcher ( IntNative n )
-{
- if (opMode == OM_Z)
- fprintf (
- stderr,
- "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
- "\n"
- " Possible causes are (most likely first):\n"
- " (1) This computer has unreliable memory or cache hardware\n"
- " (a surprisingly common problem; try a different machine.)\n"
- " (2) A bug in the compiler used to create this executable\n"
- " (unlikely, if you didn't compile bzip2 yourself.)\n"
- " (3) A real bug in bzip2 -- I hope this should never be the case.\n"
- " The user's manual, Section 4.3, has more info on (1) and (2).\n"
- " \n"
- " If you suspect this is a bug in bzip2, or are unsure about (1)\n"
- " or (2), feel free to report it to me at: jseward@bzip.org.\n"
- " Section 4.3 of the user's manual describes the info a useful\n"
- " bug report should have. If the manual is available on your\n"
- " system, please try and read it before mailing me. If you don't\n"
- " have the manual or can't be bothered to read it, mail me anyway.\n"
- "\n",
- progName );
- else
- fprintf (
- stderr,
- "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
- "\n"
- " Possible causes are (most likely first):\n"
- " (1) The compressed data is corrupted, and bzip2's usual checks\n"
- " failed to detect this. Try bzip2 -tvv my_file.bz2.\n"
- " (2) This computer has unreliable memory or cache hardware\n"
- " (a surprisingly common problem; try a different machine.)\n"
- " (3) A bug in the compiler used to create this executable\n"
- " (unlikely, if you didn't compile bzip2 yourself.)\n"
- " (4) A real bug in bzip2 -- I hope this should never be the case.\n"
- " The user's manual, Section 4.3, has more info on (2) and (3).\n"
- " \n"
- " If you suspect this is a bug in bzip2, or are unsure about (2)\n"
- " or (3), feel free to report it to me at: jseward@bzip.org.\n"
- " Section 4.3 of the user's manual describes the info a useful\n"
- " bug report should have. If the manual is available on your\n"
- " system, please try and read it before mailing me. If you don't\n"
- " have the manual or can't be bothered to read it, mail me anyway.\n"
- "\n",
- progName );
-
- showFileNames();
- if (opMode == OM_Z)
- cleanUpAndFail( 3 ); else
- { cadvise(); cleanUpAndFail( 2 ); }
-}
-
-
-/*---------------------------------------------*/
-static
-void outOfMemory ( void )
-{
- fprintf ( stderr,
- "\n%s: couldn't allocate enough memory\n",
- progName );
- showFileNames();
- cleanUpAndFail(1);
-}
-
-
-/*---------------------------------------------*/
-static
-void configError ( void )
-{
- fprintf ( stderr,
- "bzip2: I'm not configured correctly for this platform!\n"
- "\tI require Int32, Int16 and Char to have sizes\n"
- "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
- "\tProbably you can fix this by defining them correctly,\n"
- "\tand recompiling. Bye!\n" );
- setExit(3);
- exit(exitValue);
-}
-
-
-/*---------------------------------------------------*/
-/*--- The main driver machinery ---*/
-/*---------------------------------------------------*/
-
-/* All rather crufty. The main problem is that input files
- are stat()d multiple times before use. This should be
- cleaned up.
-*/
-
-/*---------------------------------------------*/
-static
-void pad ( Char *s )
-{
- Int32 i;
- if ( (Int32)strlen(s) >= longestFileName ) return;
- for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
- fprintf ( stderr, " " );
-}
-
-
-/*---------------------------------------------*/
-static
-void copyFileName ( Char* to, Char* from )
-{
- if ( strlen(from) > FILE_NAME_LEN-10 ) {
- fprintf (
- stderr,
- "bzip2: file name\n`%s'\n"
- "is suspiciously (more than %d chars) long.\n"
- "Try using a reasonable file name instead. Sorry! :-)\n",
- from, FILE_NAME_LEN-10
- );
- setExit(1);
- exit(exitValue);
- }
-
- strncpy(to,from,FILE_NAME_LEN-10);
- to[FILE_NAME_LEN-10]='\0';
-}
-
-
-/*---------------------------------------------*/
-static
-Bool fileExists ( Char* name )
-{
- FILE *tmp = fopen ( name, "rb" );
- Bool exists = (tmp != NULL);
- if (tmp != NULL) fclose ( tmp );
- return exists;
-}
-
-
-/*---------------------------------------------*/
-/* Open an output file safely with O_EXCL and good permissions.
- This avoids a race condition in versions < 1.0.2, in which
- the file was first opened and then had its interim permissions
- set safely. We instead use open() to create the file with
- the interim permissions required. (--- --- rw-).
-
- For non-Unix platforms, if we are not worrying about
- security issues, simple this simply behaves like fopen.
-*/
-FILE* fopen_output_safely ( Char* name, const char* mode )
-{
-# if BZ_UNIX
- FILE* fp;
- IntNative fh;
- fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
- if (fh == -1) return NULL;
- fp = fdopen(fh, mode);
- if (fp == NULL) close(fh);
- return fp;
-# else
- return fopen(name, mode);
-# endif
-}
-
-
-/*---------------------------------------------*/
-/*--
- if in doubt, return True
---*/
-static
-Bool notAStandardFile ( Char* name )
-{
- IntNative i;
- struct MY_STAT statBuf;
-
- i = MY_LSTAT ( name, &statBuf );
- if (i != 0) return True;
- if (MY_S_ISREG(statBuf.st_mode)) return False;
- return True;
-}
-
-
-/*---------------------------------------------*/
-/*--
- rac 11/21/98 see if file has hard links to it
---*/
-static
-Int32 countHardLinks ( Char* name )
-{
- IntNative i;
- struct MY_STAT statBuf;
-
- i = MY_LSTAT ( name, &statBuf );
- if (i != 0) return 0;
- return (statBuf.st_nlink - 1);
-}
-
-
-/*---------------------------------------------*/
-/* Copy modification date, access date, permissions and owner from the
- source to destination file. We have to copy this meta-info off
- into fileMetaInfo before starting to compress / decompress it,
- because doing it afterwards means we get the wrong access time.
-
- To complicate matters, in compress() and decompress() below, the
- sequence of tests preceding the call to saveInputFileMetaInfo()
- involves calling fileExists(), which in turn establishes its result
- by attempting to fopen() the file, and if successful, immediately
- fclose()ing it again. So we have to assume that the fopen() call
- does not cause the access time field to be updated.
-
- Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
- to imply that merely doing open() will not affect the access time.
- Therefore we merely need to hope that the C library only does
- open() as a result of fopen(), and not any kind of read()-ahead
- cleverness.
-
- It sounds pretty fragile to me. Whether this carries across
- robustly to arbitrary Unix-like platforms (or even works robustly
- on this one, RedHat 7.2) is unknown to me. Nevertheless ...
-*/
-#if BZ_UNIX
-static
-struct MY_STAT fileMetaInfo;
-#endif
-
-static
-void saveInputFileMetaInfo ( Char *srcName )
-{
-# if BZ_UNIX
- IntNative retVal;
- /* Note use of stat here, not lstat. */
- retVal = MY_STAT( srcName, &fileMetaInfo );
- ERROR_IF_NOT_ZERO ( retVal );
-# endif
-}
-
-
-static
-void applySavedMetaInfoToOutputFile ( Char *dstName )
-{
-# if BZ_UNIX
- IntNative retVal;
- struct utimbuf uTimBuf;
-
- uTimBuf.actime = fileMetaInfo.st_atime;
- uTimBuf.modtime = fileMetaInfo.st_mtime;
-
- retVal = chmod ( dstName, fileMetaInfo.st_mode );
- ERROR_IF_NOT_ZERO ( retVal );
-
- retVal = utime ( dstName, &uTimBuf );
- ERROR_IF_NOT_ZERO ( retVal );
-
- retVal = chown ( dstName, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
- /* chown() will in many cases return with EPERM, which can
- be safely ignored.
- */
-# endif
-}
-
-
-/*---------------------------------------------*/
-static
-Bool containsDubiousChars ( Char* name )
-{
-# if BZ_UNIX
- /* On unix, files can contain any characters and the file expansion
- * is performed by the shell.
- */
- return False;
-# else /* ! BZ_UNIX */
- /* On non-unix (Win* platforms), wildcard characters are not allowed in
- * filenames.
- */
- for (; *name != '\0'; name++)
- if (*name == '?' || *name == '*') return True;
- return False;
-# endif /* BZ_UNIX */
-}
-
-
-/*---------------------------------------------*/
-#define BZ_N_SUFFIX_PAIRS 4
-
-Char* zSuffix[BZ_N_SUFFIX_PAIRS]
- = { ".bz2", ".bz", ".tbz2", ".tbz" };
-Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
- = { "", "", ".tar", ".tar" };
-
-static
-Bool hasSuffix ( Char* s, Char* suffix )
-{
- Int32 ns = strlen(s);
- Int32 nx = strlen(suffix);
- if (ns < nx) return False;
- if (strcmp(s + ns - nx, suffix) == 0) return True;
- return False;
-}
-
-static
-Bool mapSuffix ( Char* name,
- Char* oldSuffix, Char* newSuffix )
-{
- if (!hasSuffix(name,oldSuffix)) return False;
- name[strlen(name)-strlen(oldSuffix)] = 0;
- strcat ( name, newSuffix );
- return True;
-}
-
-
-/*---------------------------------------------*/
-static
-void compress ( Char *name )
-{
- FILE *inStr;
- FILE *outStr;
- Int32 n, i;
- struct MY_STAT statBuf;
-
- deleteOutputOnInterrupt = False;
-
- if (name == NULL && srcMode != SM_I2O)
- panic ( "compress: bad modes\n" );
-
- switch (srcMode) {
- case SM_I2O:
- copyFileName ( inName, "(stdin)" );
- copyFileName ( outName, "(stdout)" );
- break;
- case SM_F2F:
- copyFileName ( inName, name );
- copyFileName ( outName, name );
- strcat ( outName, ".bz2" );
- break;
- case SM_F2O:
- copyFileName ( inName, name );
- copyFileName ( outName, "(stdout)" );
- break;
- }
-
- if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
- if (noisy)
- fprintf ( stderr, "%s: There are no files matching `%s'.\n",
- progName, inName );
- setExit(1);
- return;
- }
- if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
- fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
- progName, inName, strerror(errno) );
- setExit(1);
- return;
- }
- for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
- if (hasSuffix(inName, zSuffix[i])) {
- if (noisy)
- fprintf ( stderr,
- "%s: Input file %s already has %s suffix.\n",
- progName, inName, zSuffix[i] );
- setExit(1);
- return;
- }
- }
- if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
- MY_STAT(inName, &statBuf);
- if ( MY_S_ISDIR(statBuf.st_mode) ) {
- fprintf( stderr,
- "%s: Input file %s is a directory.\n",
- progName,inName);
- setExit(1);
- return;
- }
- }
- if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
- if (noisy)
- fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
- progName, inName );
- setExit(1);
- return;
- }
- if ( srcMode == SM_F2F && fileExists ( outName ) ) {
- if (forceOverwrite) {
- remove(outName);
- } else {
- fprintf ( stderr, "%s: Output file %s already exists.\n",
- progName, outName );
- setExit(1);
- return;
- }
- }
- if ( srcMode == SM_F2F && !forceOverwrite &&
- (n=countHardLinks ( inName )) > 0) {
- fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
- progName, inName, n, n > 1 ? "s" : "" );
- setExit(1);
- return;
- }
-
- if ( srcMode == SM_F2F ) {
- /* Save the file's meta-info before we open it. Doing it later
- means we mess up the access times. */
- saveInputFileMetaInfo ( inName );
- }
-
- switch ( srcMode ) {
-
- case SM_I2O:
- inStr = stdin;
- outStr = stdout;
- if ( isatty ( fileno ( stdout ) ) ) {
- fprintf ( stderr,
- "%s: I won't write compressed data to a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- setExit(1);
- return;
- };
- break;
-
- case SM_F2O:
- inStr = fopen ( inName, "rb" );
- outStr = stdout;
- if ( isatty ( fileno ( stdout ) ) ) {
- fprintf ( stderr,
- "%s: I won't write compressed data to a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- if ( inStr != NULL ) fclose ( inStr );
- setExit(1);
- return;
- };
- if ( inStr == NULL ) {
- fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
- progName, inName, strerror(errno) );
- setExit(1);
- return;
- };
- break;
-
- case SM_F2F:
- inStr = fopen ( inName, "rb" );
- outStr = fopen_output_safely ( outName, "wb" );
- if ( outStr == NULL) {
- fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
- progName, outName, strerror(errno) );
- if ( inStr != NULL ) fclose ( inStr );
- setExit(1);
- return;
- }
- if ( inStr == NULL ) {
- fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
- progName, inName, strerror(errno) );
- if ( outStr != NULL ) fclose ( outStr );
- setExit(1);
- return;
- };
- break;
-
- default:
- panic ( "compress: bad srcMode" );
- break;
- }
-
- if (verbosity >= 1) {
- fprintf ( stderr, " %s: ", inName );
- pad ( inName );
- fflush ( stderr );
- }
-
- /*--- Now the input and output handles are sane. Do the Biz. ---*/
- outputHandleJustInCase = outStr;
- deleteOutputOnInterrupt = True;
- compressStream ( inStr, outStr );
- outputHandleJustInCase = NULL;
-
- /*--- If there was an I/O error, we won't get here. ---*/
- if ( srcMode == SM_F2F ) {
- applySavedMetaInfoToOutputFile ( outName );
- deleteOutputOnInterrupt = False;
- if ( !keepInputFiles ) {
- IntNative retVal = remove ( inName );
- ERROR_IF_NOT_ZERO ( retVal );
- }
- }
-
- deleteOutputOnInterrupt = False;
-}
-
-
-/*---------------------------------------------*/
-static
-void uncompress ( Char *name )
-{
- FILE *inStr;
- FILE *outStr;
- Int32 n, i;
- Bool magicNumberOK;
- Bool cantGuess;
- struct MY_STAT statBuf;
-
- deleteOutputOnInterrupt = False;
-
- if (name == NULL && srcMode != SM_I2O)
- panic ( "uncompress: bad modes\n" );
-
- cantGuess = False;
- switch (srcMode) {
- case SM_I2O:
- copyFileName ( inName, "(stdin)" );
- copyFileName ( outName, "(stdout)" );
- break;
- case SM_F2F:
- copyFileName ( inName, name );
- copyFileName ( outName, name );
- for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
- if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
- goto zzz;
- cantGuess = True;
- strcat ( outName, ".out" );
- break;
- case SM_F2O:
- copyFileName ( inName, name );
- copyFileName ( outName, "(stdout)" );
- break;
- }
-
- zzz:
- if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
- if (noisy)
- fprintf ( stderr, "%s: There are no files matching `%s'.\n",
- progName, inName );
- setExit(1);
- return;
- }
- if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
- fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
- progName, inName, strerror(errno) );
- setExit(1);
- return;
- }
- if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
- MY_STAT(inName, &statBuf);
- if ( MY_S_ISDIR(statBuf.st_mode) ) {
- fprintf( stderr,
- "%s: Input file %s is a directory.\n",
- progName,inName);
- setExit(1);
- return;
- }
- }
- if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
- if (noisy)
- fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
- progName, inName );
- setExit(1);
- return;
- }
- if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
- if (noisy)
- fprintf ( stderr,
- "%s: Can't guess original name for %s -- using %s\n",
- progName, inName, outName );
- /* just a warning, no return */
- }
- if ( srcMode == SM_F2F && fileExists ( outName ) ) {
- if (forceOverwrite) {
- remove(outName);
- } else {
- fprintf ( stderr, "%s: Output file %s already exists.\n",
- progName, outName );
- setExit(1);
- return;
- }
- }
- if ( srcMode == SM_F2F && !forceOverwrite &&
- (n=countHardLinks ( inName ) ) > 0) {
- fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
- progName, inName, n, n > 1 ? "s" : "" );
- setExit(1);
- return;
- }
-
- if ( srcMode == SM_F2F ) {
- /* Save the file's meta-info before we open it. Doing it later
- means we mess up the access times. */
- saveInputFileMetaInfo ( inName );
- }
-
- switch ( srcMode ) {
-
- case SM_I2O:
- inStr = stdin;
- outStr = stdout;
- if ( isatty ( fileno ( stdin ) ) ) {
- fprintf ( stderr,
- "%s: I won't read compressed data from a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- setExit(1);
- return;
- };
- break;
-
- case SM_F2O:
- inStr = fopen ( inName, "rb" );
- outStr = stdout;
- if ( inStr == NULL ) {
- fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
- progName, inName, strerror(errno) );
- if ( inStr != NULL ) fclose ( inStr );
- setExit(1);
- return;
- };
- break;
-
- case SM_F2F:
- inStr = fopen ( inName, "rb" );
- outStr = fopen_output_safely ( outName, "wb" );
- if ( outStr == NULL) {
- fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
- progName, outName, strerror(errno) );
- if ( inStr != NULL ) fclose ( inStr );
- setExit(1);
- return;
- }
- if ( inStr == NULL ) {
- fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
- progName, inName, strerror(errno) );
- if ( outStr != NULL ) fclose ( outStr );
- setExit(1);
- return;
- };
- break;
-
- default:
- panic ( "uncompress: bad srcMode" );
- break;
- }
-
- if (verbosity >= 1) {
- fprintf ( stderr, " %s: ", inName );
- pad ( inName );
- fflush ( stderr );
- }
-
- /*--- Now the input and output handles are sane. Do the Biz. ---*/
- outputHandleJustInCase = outStr;
- deleteOutputOnInterrupt = True;
- magicNumberOK = uncompressStream ( inStr, outStr );
- outputHandleJustInCase = NULL;
-
- /*--- If there was an I/O error, we won't get here. ---*/
- if ( magicNumberOK ) {
- if ( srcMode == SM_F2F ) {
- applySavedMetaInfoToOutputFile ( outName );
- deleteOutputOnInterrupt = False;
- if ( !keepInputFiles ) {
- IntNative retVal = remove ( inName );
- ERROR_IF_NOT_ZERO ( retVal );
- }
- }
- } else {
- unzFailsExist = True;
- deleteOutputOnInterrupt = False;
- if ( srcMode == SM_F2F ) {
- IntNative retVal = remove ( outName );
- ERROR_IF_NOT_ZERO ( retVal );
- }
- }
- deleteOutputOnInterrupt = False;
-
- if ( magicNumberOK ) {
- if (verbosity >= 1)
- fprintf ( stderr, "done\n" );
- } else {
- setExit(2);
- if (verbosity >= 1)
- fprintf ( stderr, "not a bzip2 file.\n" ); else
- fprintf ( stderr,
- "%s: %s is not a bzip2 file.\n",
- progName, inName );
- }
-
-}
-
-
-/*---------------------------------------------*/
-static
-void testf ( Char *name )
-{
- FILE *inStr;
- Bool allOK;
- struct MY_STAT statBuf;
-
- deleteOutputOnInterrupt = False;
-
- if (name == NULL && srcMode != SM_I2O)
- panic ( "testf: bad modes\n" );
-
- copyFileName ( outName, "(none)" );
- switch (srcMode) {
- case SM_I2O: copyFileName ( inName, "(stdin)" ); break;
- case SM_F2F: copyFileName ( inName, name ); break;
- case SM_F2O: copyFileName ( inName, name ); break;
- }
-
- if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
- if (noisy)
- fprintf ( stderr, "%s: There are no files matching `%s'.\n",
- progName, inName );
- setExit(1);
- return;
- }
- if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
- fprintf ( stderr, "%s: Can't open input %s: %s.\n",
- progName, inName, strerror(errno) );
- setExit(1);
- return;
- }
- if ( srcMode != SM_I2O ) {
- MY_STAT(inName, &statBuf);
- if ( MY_S_ISDIR(statBuf.st_mode) ) {
- fprintf( stderr,
- "%s: Input file %s is a directory.\n",
- progName,inName);
- setExit(1);
- return;
- }
- }
-
- switch ( srcMode ) {
-
- case SM_I2O:
- if ( isatty ( fileno ( stdin ) ) ) {
- fprintf ( stderr,
- "%s: I won't read compressed data from a terminal.\n",
- progName );
- fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
- progName, progName );
- setExit(1);
- return;
- };
- inStr = stdin;
- break;
-
- case SM_F2O: case SM_F2F:
- inStr = fopen ( inName, "rb" );
- if ( inStr == NULL ) {
- fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
- progName, inName, strerror(errno) );
- setExit(1);
- return;
- };
- break;
-
- default:
- panic ( "testf: bad srcMode" );
- break;
- }
-
- if (verbosity >= 1) {
- fprintf ( stderr, " %s: ", inName );
- pad ( inName );
- fflush ( stderr );
- }
-
- /*--- Now the input handle is sane. Do the Biz. ---*/
- outputHandleJustInCase = NULL;
- allOK = testStream ( inStr );
-
- if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
- if (!allOK) testFailsExist = True;
-}
-
-
-/*---------------------------------------------*/
-static
-void license ( void )
-{
- fprintf ( stderr,
-
- "bzip2, a block-sorting file compressor. "
- "Version %s.\n"
- " \n"
- " Copyright (C) 1996-2005 by Julian Seward.\n"
- " \n"
- " This program is free software; you can redistribute it and/or modify\n"
- " it under the terms set out in the LICENSE file, which is included\n"
- " in the bzip2-1.0 source distribution.\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"
- " LICENSE file for more details.\n"
- " \n",
- BZ2_bzlibVersion()
- );
-}
-
-
-/*---------------------------------------------*/
-static
-void usage ( Char *fullProgName )
-{
- fprintf (
- stderr,
- "bzip2, a block-sorting file compressor. "
- "Version %s.\n"
- "\n usage: %s [flags and input files in any order]\n"
- "\n"
- " -h --help print this message\n"
- " -d --decompress force decompression\n"
- " -z --compress force compression\n"
- " -k --keep keep (don't delete) input files\n"
- " -f --force overwrite existing output files\n"
- " -t --test test compressed file integrity\n"
- " -c --stdout output to standard out\n"
- " -q --quiet suppress noncritical error messages\n"
- " -v --verbose be verbose (a 2nd -v gives more)\n"
- " -L --license display software version & license\n"
- " -V --version display software version & license\n"
- " -s --small use less memory (at most 2500k)\n"
- " -1 .. -9 set block size to 100k .. 900k\n"
- " --fast alias for -1\n"
- " --best alias for -9\n"
- "\n"
- " If invoked as `bzip2', default action is to compress.\n"
- " as `bunzip2', default action is to decompress.\n"
- " as `bzcat', default action is to decompress to stdout.\n"
- "\n"
- " If no file names are given, bzip2 compresses or decompresses\n"
- " from standard input to standard output. You can combine\n"
- " short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
-# if BZ_UNIX
- "\n"
-# endif
- ,
-
- BZ2_bzlibVersion(),
- fullProgName
- );
-}
-
-
-/*---------------------------------------------*/
-static
-void redundant ( Char* flag )
-{
- fprintf (
- stderr,
- "%s: %s is redundant in versions 0.9.5 and above\n",
- progName, flag );
-}
-
-
-/*---------------------------------------------*/
-/*--
- All the garbage from here to main() is purely to
- implement a linked list of command-line arguments,
- into which main() copies argv[1 .. argc-1].
-
- The purpose of this exercise is to facilitate
- the expansion of wildcard characters * and ? in
- filenames for OSs which don't know how to do it
- themselves, like MSDOS, Windows 95 and NT.
-
- The actual Dirty Work is done by the platform-
- specific macro APPEND_FILESPEC.
---*/
-
-typedef
- struct zzzz {
- Char *name;
- struct zzzz *link;
- }
- Cell;
-
-
-/*---------------------------------------------*/
-static
-void *myMalloc ( Int32 n )
-{
- void* p;
-
- p = malloc ( (size_t)n );
- if (p == NULL) outOfMemory ();
- return p;
-}
-
-
-/*---------------------------------------------*/
-static
-Cell *mkCell ( void )
-{
- Cell *c;
-
- c = (Cell*) myMalloc ( sizeof ( Cell ) );
- c->name = NULL;
- c->link = NULL;
- return c;
-}
-
-
-/*---------------------------------------------*/
-static
-Cell *snocString ( Cell *root, Char *name )
-{
- if (root == NULL) {
- Cell *tmp = mkCell();
- tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
- strcpy ( tmp->name, name );
- return tmp;
- } else {
- Cell *tmp = root;
- while (tmp->link != NULL) tmp = tmp->link;
- tmp->link = snocString ( tmp->link, name );
- return root;
- }
-}
-
-
-/*---------------------------------------------*/
-static
-void addFlagsFromEnvVar ( Cell** argList, Char* varName )
-{
- Int32 i, j, k;
- Char *envbase, *p;
-
- envbase = getenv(varName);
- if (envbase != NULL) {
- p = envbase;
- i = 0;
- while (True) {
- if (p[i] == 0) break;
- p += i;
- i = 0;
- while (isspace((Int32)(p[0]))) p++;
- while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
- if (i > 0) {
- k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
- for (j = 0; j < k; j++) tmpName[j] = p[j];
- tmpName[k] = 0;
- APPEND_FLAG(*argList, tmpName);
- }
- }
- }
-}
-
-
-/*---------------------------------------------*/
-#define ISFLAG(s) (strcmp(aa->name, (s))==0)
-
-IntNative main ( IntNative argc, Char *argv[] )
-{
- Int32 i, j;
- Char *tmp;
- Cell *argList;
- Cell *aa;
- Bool decode;
-
- /*-- Be really really really paranoid :-) --*/
- if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
- sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
- sizeof(Char) != 1 || sizeof(UChar) != 1)
- configError();
-
- /*-- Initialise --*/
- outputHandleJustInCase = NULL;
- smallMode = False;
- keepInputFiles = False;
- forceOverwrite = False;
- noisy = True;
- verbosity = 0;
- blockSize100k = 9;
- testFailsExist = False;
- unzFailsExist = False;
- numFileNames = 0;
- numFilesProcessed = 0;
- workFactor = 30;
- deleteOutputOnInterrupt = False;
- exitValue = 0;
- i = j = 0; /* avoid bogus warning from egcs-1.1.X */
-
- /*-- Set up signal handlers for mem access errors --*/
- signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
-# if BZ_UNIX
-# ifndef __DJGPP__
- signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
-# endif
-# endif
-
- copyFileName ( inName, "(none)" );
- copyFileName ( outName, "(none)" );
-
- copyFileName ( progNameReally, argv[0] );
- progName = &progNameReally[0];
- for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
- if (*tmp == PATH_SEP) progName = tmp + 1;
-
-
- /*-- Copy flags from env var BZIP2, and
- expand filename wildcards in arg list.
- --*/
- argList = NULL;
- addFlagsFromEnvVar ( &argList, "BZIP2" );
- addFlagsFromEnvVar ( &argList, "BZIP" );
- for (i = 1; i <= argc-1; i++)
- APPEND_FILESPEC(argList, argv[i]);
-
-
- /*-- Find the length of the longest filename --*/
- longestFileName = 7;
- numFileNames = 0;
- decode = True;
- for (aa = argList; aa != NULL; aa = aa->link) {
- if (ISFLAG("--")) { decode = False; continue; }
- if (aa->name[0] == '-' && decode) continue;
- numFileNames++;
- if (longestFileName < (Int32)strlen(aa->name) )
- longestFileName = (Int32)strlen(aa->name);
- }
-
-
- /*-- Determine source modes; flag handling may change this too. --*/
- if (numFileNames == 0)
- srcMode = SM_I2O; else srcMode = SM_F2F;
-
-
- /*-- Determine what to do (compress/uncompress/test/cat). --*/
- /*-- Note that subsequent flag handling may change this. --*/
- opMode = OM_Z;
-
- if ( (strstr ( progName, "unzip" ) != 0) ||
- (strstr ( progName, "UNZIP" ) != 0) )
- opMode = OM_UNZ;
-
- if ( (strstr ( progName, "z2cat" ) != 0) ||
- (strstr ( progName, "Z2CAT" ) != 0) ||
- (strstr ( progName, "zcat" ) != 0) ||
- (strstr ( progName, "ZCAT" ) != 0) ) {
- opMode = OM_UNZ;
- srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
- }
-
-
- /*-- Look at the flags. --*/
- for (aa = argList; aa != NULL; aa = aa->link) {
- if (ISFLAG("--")) break;
- if (aa->name[0] == '-' && aa->name[1] != '-') {
- for (j = 1; aa->name[j] != '\0'; j++) {
- switch (aa->name[j]) {
- case 'c': srcMode = SM_F2O; break;
- case 'd': opMode = OM_UNZ; break;
- case 'z': opMode = OM_Z; break;
- case 'f': forceOverwrite = True; break;
- case 't': opMode = OM_TEST; break;
- case 'k': keepInputFiles = True; break;
- case 's': smallMode = True; break;
- case 'q': noisy = False; break;
- case '1': blockSize100k = 1; break;
- case '2': blockSize100k = 2; break;
- case '3': blockSize100k = 3; break;
- case '4': blockSize100k = 4; break;
- case '5': blockSize100k = 5; break;
- case '6': blockSize100k = 6; break;
- case '7': blockSize100k = 7; break;
- case '8': blockSize100k = 8; break;
- case '9': blockSize100k = 9; break;
- case 'V':
- case 'L': license(); break;
- case 'v': verbosity++; break;
- case 'h': usage ( progName );
- exit ( 0 );
- break;
- default: fprintf ( stderr, "%s: Bad flag `%s'\n",
- progName, aa->name );
- usage ( progName );
- exit ( 1 );
- break;
- }
- }
- }
- }
-
- /*-- And again ... --*/
- for (aa = argList; aa != NULL; aa = aa->link) {
- if (ISFLAG("--")) break;
- if (ISFLAG("--stdout")) srcMode = SM_F2O; else
- if (ISFLAG("--decompress")) opMode = OM_UNZ; else
- if (ISFLAG("--compress")) opMode = OM_Z; else
- if (ISFLAG("--force")) forceOverwrite = True; else
- if (ISFLAG("--test")) opMode = OM_TEST; else
- if (ISFLAG("--keep")) keepInputFiles = True; else
- if (ISFLAG("--small")) smallMode = True; else
- if (ISFLAG("--quiet")) noisy = False; else
- if (ISFLAG("--version")) license(); else
- if (ISFLAG("--license")) license(); else
- if (ISFLAG("--exponential")) workFactor = 1; else
- if (ISFLAG("--repetitive-best")) redundant(aa->name); else
- if (ISFLAG("--repetitive-fast")) redundant(aa->name); else
- if (ISFLAG("--fast")) blockSize100k = 1; else
- if (ISFLAG("--best")) blockSize100k = 9; else
- if (ISFLAG("--verbose")) verbosity++; else
- if (ISFLAG("--help")) { usage ( progName ); exit ( 0 ); }
- else
- if (strncmp ( aa->name, "--", 2) == 0) {
- fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
- usage ( progName );
- exit ( 1 );
- }
- }
-
- if (verbosity > 4) verbosity = 4;
- if (opMode == OM_Z && smallMode && blockSize100k > 2)
- blockSize100k = 2;
-
- if (opMode == OM_TEST && srcMode == SM_F2O) {
- fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
- progName );
- exit ( 1 );
- }
-
- if (srcMode == SM_F2O && numFileNames == 0)
- srcMode = SM_I2O;
-
- if (opMode != OM_Z) blockSize100k = 0;
-
- if (srcMode == SM_F2F) {
- signal (SIGINT, mySignalCatcher);
- signal (SIGTERM, mySignalCatcher);
-# if BZ_UNIX
- signal (SIGHUP, mySignalCatcher);
-# endif
- }
-
- if (opMode == OM_Z) {
- if (srcMode == SM_I2O) {
- compress ( NULL );
- } else {
- decode = True;
- for (aa = argList; aa != NULL; aa = aa->link) {
- if (ISFLAG("--")) { decode = False; continue; }
- if (aa->name[0] == '-' && decode) continue;
- numFilesProcessed++;
- compress ( aa->name );
- }
- }
- }
- else
-
- if (opMode == OM_UNZ) {
- unzFailsExist = False;
- if (srcMode == SM_I2O) {
- uncompress ( NULL );
- } else {
- decode = True;
- for (aa = argList; aa != NULL; aa = aa->link) {
- if (ISFLAG("--")) { decode = False; continue; }
- if (aa->name[0] == '-' && decode) continue;
- numFilesProcessed++;
- uncompress ( aa->name );
- }
- }
- if (unzFailsExist) {
- setExit(2);
- exit(exitValue);
- }
- }
-
- else {
- testFailsExist = False;
- if (srcMode == SM_I2O) {
- testf ( NULL );
- } else {
- decode = True;
- for (aa = argList; aa != NULL; aa = aa->link) {
- if (ISFLAG("--")) { decode = False; continue; }
- if (aa->name[0] == '-' && decode) continue;
- numFilesProcessed++;
- testf ( aa->name );
- }
- }
- if (testFailsExist && noisy) {
- fprintf ( stderr,
- "\n"
- "You can use the `bzip2recover' program to attempt to recover\n"
- "data from undamaged sections of corrupted files.\n\n"
- );
- setExit(2);
- exit(exitValue);
- }
- }
-
- /* Free the argument list memory to mollify leak detectors
- (eg) Purify, Checker. Serves no other useful purpose.
- */
- aa = argList;
- while (aa != NULL) {
- Cell* aa2 = aa->link;
- if (aa->name != NULL) free(aa->name);
- free(aa);
- aa = aa2;
- }
-
- return exitValue;
-}
-
-
-/*-----------------------------------------------------------*/
-/*--- end bzip2.c ---*/
-/*-----------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.txt b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.txt
deleted file mode 100644
index bf895b6cb8a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2.txt
+++ /dev/null
@@ -1,391 +0,0 @@
-
-NAME
- bzip2, bunzip2 - a block-sorting file compressor, v1.0.3
- bzcat - decompresses files to stdout
- bzip2recover - recovers data from damaged bzip2 files
-
-
-SYNOPSIS
- bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ... ]
- bunzip2 [ -fkvsVL ] [ filenames ... ]
- bzcat [ -s ] [ filenames ... ]
- bzip2recover filename
-
-
-DESCRIPTION
- bzip2 compresses files using the Burrows-Wheeler block
- sorting text compression algorithm, and Huffman coding.
- Compression is generally considerably better than that
- achieved by more conventional LZ77/LZ78-based compressors,
- and approaches the performance of the PPM family of sta-
- tistical compressors.
-
- The command-line options are deliberately very similar to
- those of GNU gzip, but they are not identical.
-
- bzip2 expects a list of file names to accompany the com-
- mand-line flags. Each file is replaced by a compressed
- version of itself, with the name "original_name.bz2".
- Each compressed file has the same modification date, per-
- missions, and, when possible, ownership as the correspond-
- ing original, so that these properties can be correctly
- restored at decompression time. File name handling is
- naive in the sense that there is no mechanism for preserv-
- ing original file names, permissions, ownerships or dates
- in filesystems which lack these concepts, or have serious
- file name length restrictions, such as MS-DOS.
-
- bzip2 and bunzip2 will by default not overwrite existing
- files. If you want this to happen, specify the -f flag.
-
- If no file names are specified, bzip2 compresses from
- standard input to standard output. In this case, bzip2
- will decline to write compressed output to a terminal, as
- this would be entirely incomprehensible and therefore
- pointless.
-
- bunzip2 (or bzip2 -d) decompresses all specified files.
- Files which were not created by bzip2 will be detected and
- ignored, and a warning issued. bzip2 attempts to guess
- the filename for the decompressed file from that of the
- compressed file as follows:
-
- filename.bz2 becomes filename
- filename.bz becomes filename
- filename.tbz2 becomes filename.tar
- filename.tbz becomes filename.tar
- anyothername becomes anyothername.out
-
- If the file does not end in one of the recognised endings,
- .bz2, .bz, .tbz2 or .tbz, bzip2 complains that it cannot
- guess the name of the original file, and uses the original
- name with .out appended.
-
- As with compression, supplying no filenames causes decom-
- pression from standard input to standard output.
-
- bunzip2 will correctly decompress a file which is the con-
- catenation of two or more compressed files. The result is
- the concatenation of the corresponding uncompressed files.
- Integrity testing (-t) of concatenated compressed files is
- also supported.
-
- You can also compress or decompress files to the standard
- output by giving the -c flag. Multiple files may be com-
- pressed and decompressed like this. The resulting outputs
- are fed sequentially to stdout. Compression of multiple
- files in this manner generates a stream containing multi-
- ple compressed file representations. Such a stream can be
- decompressed correctly only by bzip2 version 0.9.0 or
- later. Earlier versions of bzip2 will stop after decom-
- pressing the first file in the stream.
-
- bzcat (or bzip2 -dc) decompresses all specified files to
- the standard output.
-
- bzip2 will read arguments from the environment variables
- BZIP2 and BZIP, in that order, and will process them
- before any arguments read from the command line. This
- gives a convenient way to supply default arguments.
-
- Compression is always performed, even if the compressed
- file is slightly larger than the original. Files of less
- than about one hundred bytes tend to get larger, since the
- compression mechanism has a constant overhead in the
- region of 50 bytes. Random data (including the output of
- most file compressors) is coded at about 8.05 bits per
- byte, giving an expansion of around 0.5%.
-
- As a self-check for your protection, bzip2 uses 32-bit
- CRCs to make sure that the decompressed version of a file
- is identical to the original. This guards against corrup-
- tion of the compressed data, and against undetected bugs
- in bzip2 (hopefully very unlikely). The chances of data
- corruption going undetected is microscopic, about one
- chance in four billion for each file processed. Be aware,
- though, that the check occurs upon decompression, so it
- can only tell you that something is wrong. It can't help
- you recover the original uncompressed data. You can use
- bzip2recover to try to recover data from damaged files.
-
- Return values: 0 for a normal exit, 1 for environmental
- problems (file not found, invalid flags, I/O errors, &c),
- 2 to indicate a corrupt compressed file, 3 for an internal
- consistency error (eg, bug) which caused bzip2 to panic.
-
-
-OPTIONS
- -c --stdout
- Compress or decompress to standard output.
-
- -d --decompress
- Force decompression. bzip2, bunzip2 and bzcat are
- really the same program, and the decision about
- what actions to take is done on the basis of which
- name is used. This flag overrides that mechanism,
- and forces bzip2 to decompress.
-
- -z --compress
- The complement to -d: forces compression,
- regardless of the invocation name.
-
- -t --test
- Check integrity of the specified file(s), but don't
- decompress them. This really performs a trial
- decompression and throws away the result.
-
- -f --force
- Force overwrite of output files. Normally, bzip2
- will not overwrite existing output files. Also
- forces bzip2 to break hard links to files, which it
- otherwise wouldn't do.
-
- bzip2 normally declines to decompress files which
- don't have the correct magic header bytes. If
- forced (-f), however, it will pass such files
- through unmodified. This is how GNU gzip behaves.
-
- -k --keep
- Keep (don't delete) input files during compression
- or decompression.
-
- -s --small
- Reduce memory usage, for compression, decompression
- and testing. Files are decompressed and tested
- using a modified algorithm which only requires 2.5
- bytes per block byte. This means any file can be
- decompressed in 2300k of memory, albeit at about
- half the normal speed.
-
- During compression, -s selects a block size of
- 200k, which limits memory use to around the same
- figure, at the expense of your compression ratio.
- In short, if your machine is low on memory (8
- megabytes or less), use -s for everything. See
- MEMORY MANAGEMENT below.
-
- -q --quiet
- Suppress non-essential warning messages. Messages
- pertaining to I/O errors and other critical events
- will not be suppressed.
-
- -v --verbose
- Verbose mode -- show the compression ratio for each
- file processed. Further -v's increase the ver-
- bosity level, spewing out lots of information which
- is primarily of interest for diagnostic purposes.
-
- -L --license -V --version
- Display the software version, license terms and
- conditions.
-
- -1 (or --fast) to -9 (or --best)
- Set the block size to 100 k, 200 k .. 900 k when
- compressing. Has no effect when decompressing.
- See MEMORY MANAGEMENT below. The --fast and --best
- aliases are primarily for GNU gzip compatibility.
- In particular, --fast doesn't make things signifi-
- cantly faster. And --best merely selects the
- default behaviour.
-
- -- Treats all subsequent arguments as file names, even
- if they start with a dash. This is so you can han-
- dle files with names beginning with a dash, for
- example: bzip2 -- -myfilename.
-
- --repetitive-fast --repetitive-best
- These flags are redundant in versions 0.9.5 and
- above. They provided some coarse control over the
- behaviour of the sorting algorithm in earlier ver-
- sions, which was sometimes useful. 0.9.5 and above
- have an improved algorithm which renders these
- flags irrelevant.
-
-
-MEMORY MANAGEMENT
- bzip2 compresses large files in blocks. The block size
- affects both the compression ratio achieved, and the
- amount of memory needed for compression and decompression.
- The flags -1 through -9 specify the block size to be
- 100,000 bytes through 900,000 bytes (the default) respec-
- tively. At decompression time, the block size used for
- compression is read from the header of the compressed
- file, and bunzip2 then allocates itself just enough memory
- to decompress the file. Since block sizes are stored in
- compressed files, it follows that the flags -1 to -9 are
- irrelevant to and so ignored during decompression.
-
- Compression and decompression requirements, in bytes, can
- be estimated as:
-
- Compression: 400k + ( 8 x block size )
-
- Decompression: 100k + ( 4 x block size ), or
- 100k + ( 2.5 x block size )
-
- Larger block sizes give rapidly diminishing marginal
- returns. Most of the compression comes from the first two
- or three hundred k of block size, a fact worth bearing in
- mind when using bzip2 on small machines. It is also
- important to appreciate that the decompression memory
- requirement is set at compression time by the choice of
- block size.
-
- For files compressed with the default 900k block size,
- bunzip2 will require about 3700 kbytes to decompress. To
- support decompression of any file on a 4 megabyte machine,
- bunzip2 has an option to decompress using approximately
- half this amount of memory, about 2300 kbytes. Decompres-
- sion speed is also halved, so you should use this option
- only where necessary. The relevant flag is -s.
-
- In general, try and use the largest block size memory con-
- straints allow, since that maximises the compression
- achieved. Compression and decompression speed are virtu-
- ally unaffected by block size.
-
- Another significant point applies to files which fit in a
- single block -- that means most files you'd encounter
- using a large block size. The amount of real memory
- touched is proportional to the size of the file, since the
- file is smaller than a block. For example, compressing a
- file 20,000 bytes long with the flag -9 will cause the
- compressor to allocate around 7600k of memory, but only
- touch 400k + 20000 * 8 = 560 kbytes of it. Similarly, the
- decompressor will allocate 3700k but only touch 100k +
- 20000 * 4 = 180 kbytes.
-
- Here is a table which summarises the maximum memory usage
- for different block sizes. Also recorded is the total
- compressed size for 14 files of the Calgary Text Compres-
- sion Corpus totalling 3,141,622 bytes. This column gives
- some feel for how compression varies with block size.
- These figures tend to understate the advantage of larger
- block sizes for larger files, since the Corpus is domi-
- nated by smaller files.
-
- Compress Decompress Decompress Corpus
- Flag usage usage -s usage Size
-
- -1 1200k 500k 350k 914704
- -2 2000k 900k 600k 877703
- -3 2800k 1300k 850k 860338
- -4 3600k 1700k 1100k 846899
- -5 4400k 2100k 1350k 845160
- -6 5200k 2500k 1600k 838626
- -7 6100k 2900k 1850k 834096
- -8 6800k 3300k 2100k 828642
- -9 7600k 3700k 2350k 828642
-
-
-RECOVERING DATA FROM DAMAGED FILES
- bzip2 compresses files in blocks, usually 900kbytes long.
- Each block is handled independently. If a media or trans-
- mission error causes a multi-block .bz2 file to become
- damaged, it may be possible to recover data from the
- undamaged blocks in the file.
-
- The compressed representation of each block is delimited
- by a 48-bit pattern, which makes it possible to find the
- block boundaries with reasonable certainty. Each block
- also carries its own 32-bit CRC, so damaged blocks can be
- distinguished from undamaged ones.
-
- bzip2recover is a simple program whose purpose is to
- search for blocks in .bz2 files, and write each block out
- into its own .bz2 file. You can then use bzip2 -t to test
- the integrity of the resulting files, and decompress those
- which are undamaged.
-
- bzip2recover takes a single argument, the name of the dam-
- aged file, and writes a number of files
- "rec00001file.bz2", "rec00002file.bz2", etc, containing
- the extracted blocks. The output filenames are
- designed so that the use of wildcards in subsequent pro-
- cessing -- for example, "bzip2 -dc rec*file.bz2 > recov-
- ered_data" -- processes the files in the correct order.
-
- bzip2recover should be of most use dealing with large .bz2
- files, as these will contain many blocks. It is clearly
- futile to use it on damaged single-block files, since a
- damaged block cannot be recovered. If you wish to min-
- imise any potential data loss through media or transmis-
- sion errors, you might consider compressing with a smaller
- block size.
-
-
-PERFORMANCE NOTES
- The sorting phase of compression gathers together similar
- strings in the file. Because of this, files containing
- very long runs of repeated symbols, like "aabaabaabaab
- ..." (repeated several hundred times) may compress more
- slowly than normal. Versions 0.9.5 and above fare much
- better than previous versions in this respect. The ratio
- between worst-case and average-case compression time is in
- the region of 10:1. For previous versions, this figure
- was more like 100:1. You can use the -vvvv option to mon-
- itor progress in great detail, if you want.
-
- Decompression speed is unaffected by these phenomena.
-
- bzip2 usually allocates several megabytes of memory to
- operate in, and then charges all over it in a fairly ran-
- dom fashion. This means that performance, both for com-
- pressing and decompressing, is largely determined by the
- speed at which your machine can service cache misses.
- Because of this, small changes to the code to reduce the
- miss rate have been observed to give disproportionately
- large performance improvements. I imagine bzip2 will per-
- form best on machines with very large caches.
-
-
-CAVEATS
- I/O error messages are not as helpful as they could be.
- bzip2 tries hard to detect I/O errors and exit cleanly,
- but the details of what the problem is sometimes seem
- rather misleading.
-
- This manual page pertains to version 1.0.3 of bzip2. Com-
- pressed data created by this version is entirely forwards
- and backwards compatible with the previous public
- releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 and
- 1.0.2, but with the following exception: 0.9.0 and above
- can correctly decompress multiple concatenated compressed
- files. 0.1pl2 cannot do this; it will stop after decom-
- pressing just the first file in the stream.
-
- bzip2recover versions prior to 1.0.2 used 32-bit integers
- to represent bit positions in compressed files, so they
- could not handle compressed files more than 512 megabytes
- long. Versions 1.0.2 and above use 64-bit ints on some
- platforms which support them (GNU supported targets, and
- Windows). To establish whether or not bzip2recover was
- built with such a limitation, run it without arguments.
- In any event you can build yourself an unlimited version
- if you can recompile it with MaybeUInt64 set to be an
- unsigned 64-bit integer.
-
-
-AUTHOR
- Julian Seward, jsewardbzip.org.
-
- http://www.bzip.org
-
- The ideas embodied in bzip2 are due to (at least) the fol-
- lowing people: Michael Burrows and David Wheeler (for the
- block sorting transformation), David Wheeler (again, for
- the Huffman coder), Peter Fenwick (for the structured cod-
- ing model in the original bzip, and many refinements), and
- Alistair Moffat, Radford Neal and Ian Witten (for the
- arithmetic coder in the original bzip). I am much
- indebted for their help, support and advice. See the man-
- ual in the source distribution for pointers to sources of
- documentation. Christian von Roques encouraged me to look
- for faster sorting algorithms, so as to speed up compres-
- sion. Bela Lubkin encouraged me to improve the worst-case
- compression performance. Donna Robinson XMLised the docu-
- mentation. The bz* scripts are derived from those of GNU
- gzip. Many people sent patches, helped with portability
- problems, lent machines, gave advice and were generally
- helpful.
-
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2recover.c b/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2recover.c
deleted file mode 100644
index 5cd405dd4cb..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzip2recover.c
+++ /dev/null
@@ -1,546 +0,0 @@
-
-/*-----------------------------------------------------------*/
-/*--- Block recoverer program for bzip2 ---*/
-/*--- bzip2recover.c ---*/
-/*-----------------------------------------------------------*/
-
-/*--
- This program is bzip2recover, a program to attempt data
- salvage from damaged files created by the accompanying
- bzip2-1.0.3 program.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0.3 of 15 February 2005
---*/
-
-/*--
- This program is a complete hack and should be rewritten
- properly. It isn't very complicated.
---*/
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* This program records bit locations in the file to be recovered.
- That means that if 64-bit ints are not supported, we will not
- be able to recover .bz2 files over 512MB (2^32 bits) long.
- On GNU supported platforms, we take advantage of the 64-bit
- int support to circumvent this problem. Ditto MSVC.
-
- This change occurred in version 1.0.2; all prior versions have
- the 512MB limitation.
-*/
-#ifdef __GNUC__
- typedef unsigned long long int MaybeUInt64;
-# define MaybeUInt64_FMT "%Lu"
-#else
-#ifdef _MSC_VER
- typedef unsigned __int64 MaybeUInt64;
-# define MaybeUInt64_FMT "%I64u"
-#else
- typedef unsigned int MaybeUInt64;
-# define MaybeUInt64_FMT "%u"
-#endif
-#endif
-
-typedef unsigned int UInt32;
-typedef int Int32;
-typedef unsigned char UChar;
-typedef char Char;
-typedef unsigned char Bool;
-#define True ((Bool)1)
-#define False ((Bool)0)
-
-
-#define BZ_MAX_FILENAME 2000
-
-Char inFileName[BZ_MAX_FILENAME];
-Char outFileName[BZ_MAX_FILENAME];
-Char progName[BZ_MAX_FILENAME];
-
-MaybeUInt64 bytesOut = 0;
-MaybeUInt64 bytesIn = 0;
-
-
-/*---------------------------------------------------*/
-/*--- Header bytes ---*/
-/*---------------------------------------------------*/
-
-#define BZ_HDR_B 0x42 /* 'B' */
-#define BZ_HDR_Z 0x5a /* 'Z' */
-#define BZ_HDR_h 0x68 /* 'h' */
-#define BZ_HDR_0 0x30 /* '0' */
-
-
-/*---------------------------------------------------*/
-/*--- I/O errors ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------*/
-void readError ( void )
-{
- fprintf ( stderr,
- "%s: I/O error reading `%s', possible reason follows.\n",
- progName, inFileName );
- perror ( progName );
- fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
- progName );
- exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-void writeError ( void )
-{
- fprintf ( stderr,
- "%s: I/O error reading `%s', possible reason follows.\n",
- progName, inFileName );
- perror ( progName );
- fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
- progName );
- exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-void mallocFail ( Int32 n )
-{
- fprintf ( stderr,
- "%s: malloc failed on request for %d bytes.\n",
- progName, n );
- fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
- progName );
- exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-void tooManyBlocks ( Int32 max_handled_blocks )
-{
- fprintf ( stderr,
- "%s: `%s' appears to contain more than %d blocks\n",
- progName, inFileName, max_handled_blocks );
- fprintf ( stderr,
- "%s: and cannot be handled. To fix, increase\n",
- progName );
- fprintf ( stderr,
- "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
- progName );
- exit ( 1 );
-}
-
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O ---*/
-/*---------------------------------------------------*/
-
-typedef
- struct {
- FILE* handle;
- Int32 buffer;
- Int32 buffLive;
- Char mode;
- }
- BitStream;
-
-
-/*---------------------------------------------*/
-BitStream* bsOpenReadStream ( FILE* stream )
-{
- BitStream *bs = malloc ( sizeof(BitStream) );
- if (bs == NULL) mallocFail ( sizeof(BitStream) );
- bs->handle = stream;
- bs->buffer = 0;
- bs->buffLive = 0;
- bs->mode = 'r';
- return bs;
-}
-
-
-/*---------------------------------------------*/
-BitStream* bsOpenWriteStream ( FILE* stream )
-{
- BitStream *bs = malloc ( sizeof(BitStream) );
- if (bs == NULL) mallocFail ( sizeof(BitStream) );
- bs->handle = stream;
- bs->buffer = 0;
- bs->buffLive = 0;
- bs->mode = 'w';
- return bs;
-}
-
-
-/*---------------------------------------------*/
-void bsPutBit ( BitStream* bs, Int32 bit )
-{
- if (bs->buffLive == 8) {
- Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
- if (retVal == EOF) writeError();
- bytesOut++;
- bs->buffLive = 1;
- bs->buffer = bit & 0x1;
- } else {
- bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
- bs->buffLive++;
- };
-}
-
-
-/*---------------------------------------------*/
-/*--
- Returns 0 or 1, or 2 to indicate EOF.
---*/
-Int32 bsGetBit ( BitStream* bs )
-{
- if (bs->buffLive > 0) {
- bs->buffLive --;
- return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
- } else {
- Int32 retVal = getc ( bs->handle );
- if ( retVal == EOF ) {
- if (errno != 0) readError();
- return 2;
- }
- bs->buffLive = 7;
- bs->buffer = retVal;
- return ( ((bs->buffer) >> 7) & 0x1 );
- }
-}
-
-
-/*---------------------------------------------*/
-void bsClose ( BitStream* bs )
-{
- Int32 retVal;
-
- if ( bs->mode == 'w' ) {
- while ( bs->buffLive < 8 ) {
- bs->buffLive++;
- bs->buffer <<= 1;
- };
- retVal = putc ( (UChar) (bs->buffer), bs->handle );
- if (retVal == EOF) writeError();
- bytesOut++;
- retVal = fflush ( bs->handle );
- if (retVal == EOF) writeError();
- }
- retVal = fclose ( bs->handle );
- if (retVal == EOF) {
- if (bs->mode == 'w') writeError(); else readError();
- }
- free ( bs );
-}
-
-
-/*---------------------------------------------*/
-void bsPutUChar ( BitStream* bs, UChar c )
-{
- Int32 i;
- for (i = 7; i >= 0; i--)
- bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
-}
-
-
-/*---------------------------------------------*/
-void bsPutUInt32 ( BitStream* bs, UInt32 c )
-{
- Int32 i;
-
- for (i = 31; i >= 0; i--)
- bsPutBit ( bs, (c >> i) & 0x1 );
-}
-
-
-/*---------------------------------------------*/
-Bool endsInBz2 ( Char* name )
-{
- Int32 n = strlen ( name );
- if (n <= 4) return False;
- return
- (name[n-4] == '.' &&
- name[n-3] == 'b' &&
- name[n-2] == 'z' &&
- name[n-1] == '2');
-}
-
-
-/*---------------------------------------------------*/
-/*--- ---*/
-/*---------------------------------------------------*/
-
-/* This logic isn't really right when it comes to Cygwin. */
-#ifdef _WIN32
-# define BZ_SPLIT_SYM '\\' /* path splitter on Windows platform */
-#else
-# define BZ_SPLIT_SYM '/' /* path splitter on Unix platform */
-#endif
-
-#define BLOCK_HEADER_HI 0x00003141UL
-#define BLOCK_HEADER_LO 0x59265359UL
-
-#define BLOCK_ENDMARK_HI 0x00001772UL
-#define BLOCK_ENDMARK_LO 0x45385090UL
-
-/* Increase if necessary. However, a .bz2 file with > 50000 blocks
- would have an uncompressed size of at least 40GB, so the chances
- are low you'll need to up this.
-*/
-#define BZ_MAX_HANDLED_BLOCKS 50000
-
-MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 bEnd [BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 rbEnd [BZ_MAX_HANDLED_BLOCKS];
-
-Int32 main ( Int32 argc, Char** argv )
-{
- FILE* inFile;
- FILE* outFile;
- BitStream* bsIn, *bsWr;
- Int32 b, wrBlock, currBlock, rbCtr;
- MaybeUInt64 bitsRead;
-
- UInt32 buffHi, buffLo, blockCRC;
- Char* p;
-
- strcpy ( progName, argv[0] );
- inFileName[0] = outFileName[0] = 0;
-
- fprintf ( stderr,
- "bzip2recover 1.0.3: extracts blocks from damaged .bz2 files.\n" );
-
- if (argc != 2) {
- fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
- progName, progName );
- switch (sizeof(MaybeUInt64)) {
- case 8:
- fprintf(stderr,
- "\trestrictions on size of recovered file: None\n");
- break;
- case 4:
- fprintf(stderr,
- "\trestrictions on size of recovered file: 512 MB\n");
- fprintf(stderr,
- "\tto circumvent, recompile with MaybeUInt64 as an\n"
- "\tunsigned 64-bit int.\n");
- break;
- default:
- fprintf(stderr,
- "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
- "configuration error.\n");
- break;
- }
- exit(1);
- }
-
- if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
- fprintf ( stderr,
- "%s: supplied filename is suspiciously (>= %d chars) long. Bye!\n",
- progName, (int)strlen(argv[1]) );
- exit(1);
- }
-
- strcpy ( inFileName, argv[1] );
-
- inFile = fopen ( inFileName, "rb" );
- if (inFile == NULL) {
- fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
- exit(1);
- }
-
- bsIn = bsOpenReadStream ( inFile );
- fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
-
- bitsRead = 0;
- buffHi = buffLo = 0;
- currBlock = 0;
- bStart[currBlock] = 0;
-
- rbCtr = 0;
-
- while (True) {
- b = bsGetBit ( bsIn );
- bitsRead++;
- if (b == 2) {
- if (bitsRead >= bStart[currBlock] &&
- (bitsRead - bStart[currBlock]) >= 40) {
- bEnd[currBlock] = bitsRead-1;
- if (currBlock > 0)
- fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
- " to " MaybeUInt64_FMT " (incomplete)\n",
- currBlock, bStart[currBlock], bEnd[currBlock] );
- } else
- currBlock--;
- break;
- }
- buffHi = (buffHi << 1) | (buffLo >> 31);
- buffLo = (buffLo << 1) | (b & 1);
- if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI
- && buffLo == BLOCK_HEADER_LO)
- ||
- ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI
- && buffLo == BLOCK_ENDMARK_LO)
- ) {
- if (bitsRead > 49) {
- bEnd[currBlock] = bitsRead-49;
- } else {
- bEnd[currBlock] = 0;
- }
- if (currBlock > 0 &&
- (bEnd[currBlock] - bStart[currBlock]) >= 130) {
- fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
- " to " MaybeUInt64_FMT "\n",
- rbCtr+1, bStart[currBlock], bEnd[currBlock] );
- rbStart[rbCtr] = bStart[currBlock];
- rbEnd[rbCtr] = bEnd[currBlock];
- rbCtr++;
- }
- if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
- tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
- currBlock++;
-
- bStart[currBlock] = bitsRead;
- }
- }
-
- bsClose ( bsIn );
-
- /*-- identified blocks run from 1 to rbCtr inclusive. --*/
-
- if (rbCtr < 1) {
- fprintf ( stderr,
- "%s: sorry, I couldn't find any block boundaries.\n",
- progName );
- exit(1);
- };
-
- fprintf ( stderr, "%s: splitting into blocks\n", progName );
-
- inFile = fopen ( inFileName, "rb" );
- if (inFile == NULL) {
- fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
- exit(1);
- }
- bsIn = bsOpenReadStream ( inFile );
-
- /*-- placate gcc's dataflow analyser --*/
- blockCRC = 0; bsWr = 0;
-
- bitsRead = 0;
- outFile = NULL;
- wrBlock = 0;
- while (True) {
- b = bsGetBit(bsIn);
- if (b == 2) break;
- buffHi = (buffHi << 1) | (buffLo >> 31);
- buffLo = (buffLo << 1) | (b & 1);
- if (bitsRead == 47+rbStart[wrBlock])
- blockCRC = (buffHi << 16) | (buffLo >> 16);
-
- if (outFile != NULL && bitsRead >= rbStart[wrBlock]
- && bitsRead <= rbEnd[wrBlock]) {
- bsPutBit ( bsWr, b );
- }
-
- bitsRead++;
-
- if (bitsRead == rbEnd[wrBlock]+1) {
- if (outFile != NULL) {
- bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
- bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
- bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
- bsPutUInt32 ( bsWr, blockCRC );
- bsClose ( bsWr );
- }
- if (wrBlock >= rbCtr) break;
- wrBlock++;
- } else
- if (bitsRead == rbStart[wrBlock]) {
- /* Create the output file name, correctly handling leading paths.
- (31.10.2001 by Sergey E. Kusikov) */
- Char* split;
- Int32 ofs, k;
- for (k = 0; k < BZ_MAX_FILENAME; k++)
- outFileName[k] = 0;
- strcpy (outFileName, inFileName);
- split = strrchr (outFileName, BZ_SPLIT_SYM);
- if (split == NULL) {
- split = outFileName;
- } else {
- ++split;
- }
- /* Now split points to the start of the basename. */
- ofs = split - outFileName;
- sprintf (split, "rec%5d", wrBlock+1);
- for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
- strcat (outFileName, inFileName + ofs);
-
- if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
-
- fprintf ( stderr, " writing block %d to `%s' ...\n",
- wrBlock+1, outFileName );
-
- outFile = fopen ( outFileName, "wb" );
- if (outFile == NULL) {
- fprintf ( stderr, "%s: can't write `%s'\n",
- progName, outFileName );
- exit(1);
- }
- bsWr = bsOpenWriteStream ( outFile );
- bsPutUChar ( bsWr, BZ_HDR_B );
- bsPutUChar ( bsWr, BZ_HDR_Z );
- bsPutUChar ( bsWr, BZ_HDR_h );
- bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
- bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
- bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
- bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
- }
- }
-
- fprintf ( stderr, "%s: finished\n", progName );
- return 0;
-}
-
-
-
-/*-----------------------------------------------------------*/
-/*--- end bzip2recover.c ---*/
-/*-----------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore b/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore
deleted file mode 100644
index d3140434049..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/sh
-
-# Bzmore wrapped for bzip2,
-# adapted from zmore by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
-
-PATH="/usr/bin:$PATH"; export PATH
-
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
- *less) more=less ;;
- *) more=more ;;
-esac
-
-if test "`echo -n a`" = "-n a"; then
- # looks like a SysV system:
- n1=''; n2='\c'
-else
- n1='-n'; n2=''
-fi
-oldtty=`stty -g 2>/dev/null`
-if stty -cbreak 2>/dev/null; then
- cb='cbreak'; ncb='-cbreak'
-else
- # 'stty min 1' resets eof to ^a on both SunOS and SysV!
- cb='min 1 -icanon'; ncb='icanon eof ^d'
-fi
-if test $? -eq 0 -a -n "$oldtty"; then
- trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
-else
- trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
-fi
-
-if test $# = 0; then
- if test -t 0; then
- echo usage: $prog files...
- else
- bzip2 -cdfq | eval $more
- fi
-else
- FIRST=1
- for FILE
- do
- if test $FIRST -eq 0; then
- echo $n1 "--More--(Next file: $FILE)$n2"
- stty $cb -echo 2>/dev/null
- ANS=`dd bs=1 count=1 2>/dev/null`
- stty $ncb echo 2>/dev/null
- echo " "
- if test "$ANS" = 'e' -o "$ANS" = 'q'; then
- exit
- fi
- fi
- if test "$ANS" != 's'; then
- echo "------> $FILE <------"
- bzip2 -cdfq "$FILE" | eval $more
- fi
- if test -t; then
- FIRST=0
- fi
- done
-fi
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore.1 b/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore.1
deleted file mode 100644
index b437d3b031f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzmore.1
+++ /dev/null
@@ -1,152 +0,0 @@
-.\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
-.\"for Debian GNU/Linux
-.TH BZMORE 1
-.SH NAME
-bzmore, bzless \- file perusal filter for crt viewing of bzip2 compressed text
-.SH SYNOPSIS
-.B bzmore
-[ name ... ]
-.br
-.B bzless
-[ name ... ]
-.SH NOTE
-In the following description,
-.I bzless
-and
-.I less
-can be used interchangeably with
-.I bzmore
-and
-.I more.
-.SH DESCRIPTION
-.I Bzmore
-is a filter which allows examination of compressed or plain text files
-one screenful at a time on a soft-copy terminal.
-.I bzmore
-works on files compressed with
-.I bzip2
-and also on uncompressed files.
-If a file does not exist,
-.I bzmore
-looks for a file of the same name with the addition of a .bz2 suffix.
-.PP
-.I Bzmore
-normally pauses after each screenful, printing --More--
-at the bottom of the screen.
-If the user then types a carriage return, one more line is displayed.
-If the user hits a space,
-another screenful is displayed. Other possibilities are enumerated later.
-.PP
-.I Bzmore
-looks in the file
-.I /etc/termcap
-to determine terminal characteristics,
-and to determine the default window size.
-On a terminal capable of displaying 24 lines,
-the default window size is 22 lines.
-Other sequences which may be typed when
-.I bzmore
-pauses, and their effects, are as follows (\fIi\fP is an optional integer
-argument, defaulting to 1) :
-.PP
-.IP \fIi\|\fP<space>
-display
-.I i
-more lines, (or another screenful if no argument is given)
-.PP
-.IP ^D
-display 11 more lines (a ``scroll'').
-If
-.I i
-is given, then the scroll size is set to \fIi\|\fP.
-.PP
-.IP d
-same as ^D (control-D)
-.PP
-.IP \fIi\|\fPz
-same as typing a space except that \fIi\|\fP, if present, becomes the new
-window size. Note that the window size reverts back to the default at the
-end of the current file.
-.PP
-.IP \fIi\|\fPs
-skip \fIi\|\fP lines and print a screenful of lines
-.PP
-.IP \fIi\|\fPf
-skip \fIi\fP screenfuls and print a screenful of lines
-.PP
-.IP "q or Q"
-quit reading the current file; go on to the next (if any)
-.PP
-.IP "e or q"
-When the prompt --More--(Next file:
-.IR file )
-is printed, this command causes bzmore to exit.
-.PP
-.IP s
-When the prompt --More--(Next file:
-.IR file )
-is printed, this command causes bzmore to skip the next file and continue.
-.PP
-.IP =
-Display the current line number.
-.PP
-.IP \fIi\|\fP/expr
-search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
-If the pattern is not found,
-.I bzmore
-goes on to the next file (if any).
-Otherwise, a screenful is displayed, starting two lines before the place
-where the expression was found.
-The user's erase and kill characters may be used to edit the regular
-expression.
-Erasing back past the first column cancels the search command.
-.PP
-.IP \fIi\|\fPn
-search for the \fIi\|\fP-th occurrence of the last regular expression entered.
-.PP
-.IP !command
-invoke a shell with \fIcommand\|\fP.
-The character `!' in "command" are replaced with the
-previous shell command. The sequence "\\!" is replaced by "!".
-.PP
-.IP ":q or :Q"
-quit reading the current file; go on to the next (if any)
-(same as q or Q).
-.PP
-.IP .
-(dot) repeat the previous command.
-.PP
-The commands take effect immediately, i.e., it is not necessary to
-type a carriage return.
-Up to the time when the command character itself is given,
-the user may hit the line kill character to cancel the numerical
-argument being formed.
-In addition, the user may hit the erase character to redisplay the
---More-- message.
-.PP
-At any time when output is being sent to the terminal, the user can
-hit the quit key (normally control\-\\).
-.I Bzmore
-will stop sending output, and will display the usual --More--
-prompt.
-The user may then enter one of the above commands in the normal manner.
-Unfortunately, some output is lost when this is done, due to the
-fact that any characters waiting in the terminal's output queue
-are flushed when the quit signal occurs.
-.PP
-The terminal is set to
-.I noecho
-mode by this program so that the output can be continuous.
-What you type will thus not show on your terminal, except for the / and !
-commands.
-.PP
-If the standard output is not a teletype, then
-.I bzmore
-acts just like
-.I bzcat,
-except that a header is printed before each file.
-.SH FILES
-.DT
-/etc/termcap Terminal data base
-.SH "SEE ALSO"
-more(1), less(1), bzip2(1), bzdiff(1), bzgrep(1)
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.c b/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.c
deleted file mode 100644
index eb86bb61a59..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- minibz2
- libbz2.dll test program.
- by Yoshioka Tsuneo(QWF00133@nifty.ne.jp/tsuneo-y@is.aist-nara.ac.jp)
- This file is Public Domain.
- welcome any email to me.
-
- usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
-*/
-
-#define BZ_IMPORT
-#include <stdio.h>
-#include <stdlib.h>
-#include "bzlib.h"
-#ifdef _WIN32
-#include <io.h>
-#endif
-
-
-#ifdef _WIN32
-
-#define BZ2_LIBNAME "libbz2-1.0.2.DLL"
-
-#include <windows.h>
-static int BZ2DLLLoaded = 0;
-static HINSTANCE BZ2DLLhLib;
-int BZ2DLLLoadLibrary(void)
-{
- HINSTANCE hLib;
-
- if(BZ2DLLLoaded==1){return 0;}
- hLib=LoadLibrary(BZ2_LIBNAME);
- if(hLib == NULL){
- fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
- return -1;
- }
- BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
- BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
- BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
- BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
- BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
- BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
- BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
- BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
-
- if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
- || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
- || !BZ2_bzclose || !BZ2_bzerror) {
- fprintf(stderr,"GetProcAddress failed.\n");
- return -1;
- }
- BZ2DLLLoaded=1;
- BZ2DLLhLib=hLib;
- return 0;
-
-}
-int BZ2DLLFreeLibrary(void)
-{
- if(BZ2DLLLoaded==0){return 0;}
- FreeLibrary(BZ2DLLhLib);
- BZ2DLLLoaded=0;
-}
-#endif /* WIN32 */
-
-void usage(void)
-{
- puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
-}
-
-int main(int argc,char *argv[])
-{
- int decompress = 0;
- int level = 9;
- char *fn_r = NULL;
- char *fn_w = NULL;
-
-#ifdef _WIN32
- if(BZ2DLLLoadLibrary()<0){
- fprintf(stderr,"Loading of %s failed. Giving up.\n", BZ2_LIBNAME);
- exit(1);
- }
- printf("Loading of %s succeeded. Library version is %s.\n",
- BZ2_LIBNAME, BZ2_bzlibVersion() );
-#endif
- while(++argv,--argc){
- if(**argv =='-' || **argv=='/'){
- char *p;
-
- for(p=*argv+1;*p;p++){
- if(*p=='d'){
- decompress = 1;
- }else if('1'<=*p && *p<='9'){
- level = *p - '0';
- }else{
- usage();
- exit(1);
- }
- }
- }else{
- break;
- }
- }
- if(argc>=1){
- fn_r = *argv;
- argc--;argv++;
- }else{
- fn_r = NULL;
- }
- if(argc>=1){
- fn_w = *argv;
- argc--;argv++;
- }else{
- fn_w = NULL;
- }
- {
- int len;
- char buff[0x1000];
- char mode[10];
-
- if(decompress){
- BZFILE *BZ2fp_r = NULL;
- FILE *fp_w = NULL;
-
- if(fn_w){
- if((fp_w = fopen(fn_w,"wb"))==NULL){
- printf("can't open [%s]\n",fn_w);
- perror("reason:");
- exit(1);
- }
- }else{
- fp_w = stdout;
- }
- if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
- || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
- printf("can't bz2openstream\n");
- exit(1);
- }
- while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
- fwrite(buff,1,len,fp_w);
- }
- BZ2_bzclose(BZ2fp_r);
- if(fp_w != stdout) fclose(fp_w);
- }else{
- BZFILE *BZ2fp_w = NULL;
- FILE *fp_r = NULL;
-
- if(fn_r){
- if((fp_r = fopen(fn_r,"rb"))==NULL){
- printf("can't open [%s]\n",fn_r);
- perror("reason:");
- exit(1);
- }
- }else{
- fp_r = stdin;
- }
- mode[0]='w';
- mode[1] = '0' + level;
- mode[2] = '\0';
-
- if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
- || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
- printf("can't bz2openstream\n");
- exit(1);
- }
- while((len=fread(buff,1,0x1000,fp_r))>0){
- BZ2_bzwrite(BZ2fp_w,buff,len);
- }
- BZ2_bzclose(BZ2fp_w);
- if(fp_r!=stdin)fclose(fp_r);
- }
- }
-#ifdef _WIN32
- BZ2DLLFreeLibrary();
-#endif
- return 0;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.dsp b/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.dsp
deleted file mode 100644
index 04819a49563..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/dlltest.dsp
+++ /dev/null
@@ -1,93 +0,0 @@
-# Microsoft Developer Studio Project File - Name="dlltest" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 5.00
-# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=dlltest - Win32 Debug
-!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚ł͂ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
-!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
-!MESSAGE
-!MESSAGE NMAKE /f "dlltest.mak".
-!MESSAGE
-!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
-!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
-!MESSAGE
-!MESSAGE NMAKE /f "dlltest.mak" CFG="dlltest - Win32 Debug"
-!MESSAGE
-!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
-!MESSAGE
-!MESSAGE "dlltest - Win32 Release" ("Win32 (x86) Console Application" —p)
-!MESSAGE "dlltest - Win32 Debug" ("Win32 (x86) Console Application" —p)
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "dlltest - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x411 /d "NDEBUG"
-# ADD RSC /l 0x411 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"minibz2.exe"
-
-!ELSEIF "$(CFG)" == "dlltest - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "dlltest_"
-# PROP BASE Intermediate_Dir "dlltest_"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "dlltest_"
-# PROP Intermediate_Dir "dlltest_"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x411 /d "_DEBUG"
-# ADD RSC /l 0x411 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"minibz2.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "dlltest - Win32 Release"
-# Name "dlltest - Win32 Debug"
-# Begin Source File
-
-SOURCE=.\bzlib.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\dlltest.c
-# End Source File
-# End Target
-# End Project
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/entities.xml b/contrib/vmap_extractor_v2/stormlib/bzip2/entities.xml
deleted file mode 100644
index 6d0975fdbf6..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/entities.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<!-- misc. strings -->
-<!ENTITY bz-url "http://www.bzip.org">
-<!ENTITY bz-email "jseward@bzip.org">
-<!ENTITY bz-lifespan "1996-2005">
-
-<!ENTITY bz-version "1.0.3">
-<!ENTITY bz-date "15 February 2005">
-
-<!ENTITY manual-title "bzip2 Manual">
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/format.pl b/contrib/vmap_extractor_v2/stormlib/bzip2/format.pl
deleted file mode 100644
index 8ab47acd384..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/format.pl
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/perl -w
-use strict;
-
-# get command line values:
-if ( $#ARGV !=1 ) {
- die "Usage: $0 xml_infile xml_outfile\n";
-}
-
-my $infile = shift;
-# check infile exists
-die "Can't find file \"$infile\""
- unless -f $infile;
-# check we can read infile
-if (! -r $infile) {
- die "Can't read input $infile\n";
-}
-# check we can open infile
-open( INFILE,"<$infile" ) or
- die "Can't input $infile $!";
-
-#my $outfile = 'fmt-manual.xml';
-my $outfile = shift;
-#print "Infile: $infile, Outfile: $outfile\n";
-# check we can write to outfile
-open( OUTFILE,">$outfile" ) or
- die "Can't output $outfile $! for writing";
-
-my ($prev, $curr, $str);
-$prev = ''; $curr = '';
-while ( <INFILE> ) {
-
- print OUTFILE $prev;
- $prev = $curr;
- $curr = $_;
- $str = '';
-
- if ( $prev =~ /<programlisting>$|<screen>$/ ) {
- chomp $prev;
- $curr = join( '', $prev, "<![CDATA[", $curr );
- $prev = '';
- next;
- }
- elsif ( $curr =~ /<\/programlisting>|<\/screen>/ ) {
- chomp $prev;
- $curr = join( '', $prev, "]]>", $curr );
- $prev = '';
- next;
- }
-}
-print OUTFILE $curr;
-close INFILE;
-close OUTFILE;
-exit;
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.def b/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.def
deleted file mode 100644
index 4f83fcc6102..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.def
+++ /dev/null
@@ -1,27 +0,0 @@
-LIBRARY LIBBZ2
-DESCRIPTION "libbzip2: library for data compression"
-EXPORTS
- BZ2_bzCompressInit
- BZ2_bzCompress
- BZ2_bzCompressEnd
- BZ2_bzDecompressInit
- BZ2_bzDecompress
- BZ2_bzDecompressEnd
- BZ2_bzReadOpen
- BZ2_bzReadClose
- BZ2_bzReadGetUnused
- BZ2_bzRead
- BZ2_bzWriteOpen
- BZ2_bzWrite
- BZ2_bzWriteClose
- BZ2_bzWriteClose64
- BZ2_bzBuffToBuffCompress
- BZ2_bzBuffToBuffDecompress
- BZ2_bzlibVersion
- BZ2_bzopen
- BZ2_bzdopen
- BZ2_bzread
- BZ2_bzwrite
- BZ2_bzflush
- BZ2_bzclose
- BZ2_bzerror
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.dsp b/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.dsp
deleted file mode 100644
index 06c1d376251..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/libbz2.dsp
+++ /dev/null
@@ -1,130 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libbz2" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 5.00
-# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=libbz2 - Win32 Debug
-!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚ł͂ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
-!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
-!MESSAGE
-!MESSAGE NMAKE /f "libbz2.mak".
-!MESSAGE
-!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
-!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
-!MESSAGE
-!MESSAGE NMAKE /f "libbz2.mak" CFG="libbz2 - Win32 Debug"
-!MESSAGE
-!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
-!MESSAGE
-!MESSAGE "libbz2 - Win32 Release" ("Win32 (x86) Dynamic-Link Library" —p)
-!MESSAGE "libbz2 - Win32 Debug" ("Win32 (x86) Dynamic-Link Library" —p)
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libbz2 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
-# ADD BASE RSC /l 0x411 /d "NDEBUG"
-# ADD RSC /l 0x411 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"libbz2.dll"
-
-!ELSEIF "$(CFG)" == "libbz2 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
-# ADD BASE RSC /l 0x411 /d "_DEBUG"
-# ADD RSC /l 0x411 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"libbz2.dll" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "libbz2 - Win32 Release"
-# Name "libbz2 - Win32 Debug"
-# Begin Source File
-
-SOURCE=.\blocksort.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\bzlib.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\bzlib.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\bzlib_private.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\compress.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\crctable.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\decompress.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\huffman.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\libbz2.def
-# End Source File
-# Begin Source File
-
-SOURCE=.\randtable.c
-# End Source File
-# End Target
-# End Project
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/makefile.msc b/contrib/vmap_extractor_v2/stormlib/bzip2/makefile.msc
deleted file mode 100644
index 6a628a753a0..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/makefile.msc
+++ /dev/null
@@ -1,63 +0,0 @@
-# Makefile for Microsoft Visual C++ 6.0
-# usage: nmake -f makefile.msc
-# K.M. Syring (syring@gsf.de)
-# Fixed up by JRS for bzip2-0.9.5d release.
-
-CC=cl
-CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64 -nologo
-
-OBJS= blocksort.obj \
- huffman.obj \
- crctable.obj \
- randtable.obj \
- compress.obj \
- decompress.obj \
- bzlib.obj
-
-all: lib bzip2 test
-
-bzip2: lib
- $(CC) $(CFLAGS) -o bzip2 bzip2.c libbz2.lib setargv.obj
- $(CC) $(CFLAGS) -o bzip2recover bzip2recover.c
-
-lib: $(OBJS)
- lib /out:libbz2.lib $(OBJS)
-
-test: bzip2
- type words1
- .\\bzip2 -1 < sample1.ref > sample1.rb2
- .\\bzip2 -2 < sample2.ref > sample2.rb2
- .\\bzip2 -3 < sample3.ref > sample3.rb2
- .\\bzip2 -d < sample1.bz2 > sample1.tst
- .\\bzip2 -d < sample2.bz2 > sample2.tst
- .\\bzip2 -ds < sample3.bz2 > sample3.tst
- @echo All six of the fc's should find no differences.
- @echo If fc finds an error on sample3.bz2, this could be
- @echo because WinZip's 'TAR file smart CR/LF conversion'
- @echo is too clever for its own good. Disable this option.
- @echo The correct size for sample3.ref is 120,244. If it
- @echo is 150,251, WinZip has messed it up.
- fc sample1.bz2 sample1.rb2
- fc sample2.bz2 sample2.rb2
- fc sample3.bz2 sample3.rb2
- fc sample1.tst sample1.ref
- fc sample2.tst sample2.ref
- fc sample3.tst sample3.ref
-
-
-
-clean:
- del *.obj
- del libbz2.lib
- del bzip2.exe
- del bzip2recover.exe
- del sample1.rb2
- del sample2.rb2
- del sample3.rb2
- del sample1.tst
- del sample2.tst
- del sample3.tst
-
-.c.obj:
- $(CC) $(CFLAGS) -c $*.c -o $*.obj
-
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.html b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.html
deleted file mode 100644
index b28cc79a8c6..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.html
+++ /dev/null
@@ -1,2687 +0,0 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<title>bzip2 and libbzip2, version 1.0.3</title>
-<meta name="generator" content="DocBook XSL Stylesheets V1.64.1">
-<style type="text/css" media="screen">/* Colours:
-#74240f dark brown h1, h2, h3, h4
-#336699 medium blue links
-#339999 turquoise link hover colour
-#202020 almost black general text
-#761596 purple md5sum text
-#626262 dark gray pre border
-#eeeeee very light gray pre background
-#f2f2f9 very light blue nav table background
-#3366cc medium blue nav table border
-*/
-
-a, a:link, a:visited, a:active { color: #336699; }
-a:hover { color: #339999; }
-
-body { font: 80%/126% sans-serif; }
-h1, h2, h3, h4 { color: #74240f; }
-
-dt { color: #336699; font-weight: bold }
-dd {
- margin-left: 1.5em;
- padding-bottom: 0.8em;
-}
-
-/* -- ruler -- */
-div.hr_blue {
- height: 3px;
- background:#ffffff url("/images/hr_blue.png") repeat-x; }
-div.hr_blue hr { display:none; }
-
-/* release styles */
-#release p { margin-top: 0.4em; }
-#release .md5sum { color: #761596; }
-
-
-/* ------ styles for docs|manuals|howto ------ */
-/* -- lists -- */
-ul {
- margin: 0px 4px 16px 16px;
- padding: 0px;
- list-style: url("/images/li-blue.png");
-}
-ul li {
- margin-bottom: 10px;
-}
-ul ul {
- list-style-type: none;
- list-style-image: none;
- margin-left: 0px;
-}
-
-/* header / footer nav tables */
-table.nav {
- border: solid 1px #3366cc;
- background: #f2f2f9;
- background-color: #f2f2f9;
- margin-bottom: 0.5em;
-}
-/* don't have underlined links in chunked nav menus */
-table.nav a { text-decoration: none; }
-table.nav a:hover { text-decoration: underline; }
-table.nav td { font-size: 85%; }
-
-code, tt, pre { font-size: 120%; }
-code, tt { color: #761596; }
-
-div.literallayout, pre.programlisting, pre.screen {
- color: #000000;
- padding: 0.5em;
- background: #eeeeee;
- border: 1px solid #626262;
- background-color: #eeeeee;
- margin: 4px 0px 4px 0px;
-}
-</style>
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" lang="en">
-<div class="titlepage">
-<div>
-<div><h1 class="title">
-<a name="userman"></a>bzip2 and libbzip2, version 1.0.3</h1></div>
-<div><h2 class="subtitle">A program and library for data compression</h2></div>
-<div><div class="authorgroup"><div class="author">
-<h3 class="author">
-<span class="firstname">Julian</span> <span class="surname">Seward</span>
-</h3>
-<div class="affiliation"><span class="orgname">http://www.bzip.org<br></span></div>
-</div></div></div>
-<div><p class="releaseinfo">Version 1.0.3 of 15 February 2005</p></div>
-<div><p class="copyright">Copyright © 1996-2005 Julian Seward</p></div>
-<div><div class="legalnotice">
-<p>This program, <tt class="computeroutput">bzip2</tt>, the
- associated library <tt class="computeroutput">libbzip2</tt>, and
- all documentation, are copyright © 1996-2005 Julian Seward.
- All rights reserved.</p>
-<p>Redistribution and use in source and binary forms, with
- or without modification, are permitted provided that the
- following conditions are met:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>Redistributions of source code must retain the
- above copyright notice, this list of conditions and the
- following disclaimer.</p></li>
-<li style="list-style-type: disc"><p>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.</p></li>
-<li style="list-style-type: disc"><p>Altered source versions must be plainly marked
- as such, and must not be misrepresented as being the original
- software.</p></li>
-<li style="list-style-type: disc"><p>The name of the author may not be used to
- endorse or promote products derived from this software without
- specific prior written permission.</p></li>
-</ul></div>
-<p>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 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.</p>
-<p>PATENTS: To the best of my knowledge,
- <tt class="computeroutput">bzip2</tt> and
- <tt class="computeroutput">libbzip2</tt> do not use any patented
- algorithms. However, I do not have the resources to carry
- out a patent search. Therefore I cannot give any guarantee of
- the above statement.
- </p>
-</div></div>
-</div>
-<div></div>
-<hr>
-</div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt>
-<dt><span class="chapter"><a href="#using">2. How to use bzip2</a></span></dt>
-<dd><dl>
-<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
-<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
-<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
-<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
-<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
-<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
-<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
-<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
-<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
-</dl></dd>
-<dt><span class="chapter"><a href="#libprog">3.
-Programming with libbzip2
-</a></span></dt>
-<dd><dl>
-<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
-<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. BZ2_bzCompressInit</a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress">3.3.2. BZ2_bzCompress</a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. BZ2_bzCompressEnd</a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. BZ2_bzDecompressInit</a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress">3.3.5. BZ2_bzDecompress</a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. BZ2_bzDecompressEnd</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzreadopen">3.4.1. BZ2_bzReadOpen</a></span></dt>
-<dt><span class="sect2"><a href="#bzread">3.4.2. BZ2_bzRead</a></span></dt>
-<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. BZ2_bzReadGetUnused</a></span></dt>
-<dt><span class="sect2"><a href="#bzreadclose">3.4.4. BZ2_bzReadClose</a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. BZ2_bzWriteOpen</a></span></dt>
-<dt><span class="sect2"><a href="#bzwrite">3.4.6. BZ2_bzWrite</a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. BZ2_bzWriteClose</a></span></dt>
-<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
-<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. BZ2_bzBuffToBuffCompress</a></span></dt>
-<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. BZ2_bzBuffToBuffDecompress</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#zlib-compat">3.6. zlib compatibility functions</a></span></dt>
-<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a stdio-free environment</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of stdio</a></span></dt>
-<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
-</dl></dd>
-<dt><span class="chapter"><a href="#misc">4. Miscellanea</a></span></dt>
-<dd><dl>
-<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
-<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
-<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
-<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
-<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
-</dl></dd>
-</dl>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title">
-<a name="intro"></a>1. Introduction</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">bzip2</tt> compresses files
-using the Burrows-Wheeler block-sorting text compression
-algorithm, and Huffman coding. Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</p>
-<p><tt class="computeroutput">bzip2</tt> is built on top of
-<tt class="computeroutput">libbzip2</tt>, a flexible library for
-handling compressed data in the
-<tt class="computeroutput">bzip2</tt> format. This manual
-describes both how to use the program and how to work with the
-library interface. Most of the manual is devoted to this
-library, not the program, which is good news if your interest is
-only in the program.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><a href="#using">How to use bzip2</a> describes how to use
- <tt class="computeroutput">bzip2</tt>; this is the only part
- you need to read if you just want to know how to operate the
- program.</p></li>
-<li style="list-style-type: disc"><p><a href="#libprog">Programming with libbzip2</a> describes the
- programming interfaces in detail, and</p></li>
-<li style="list-style-type: disc"><p><a href="#misc">Miscellanea</a> records some
- miscellaneous notes which I thought ought to be recorded
- somewhere.</p></li>
-</ul></div>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title">
-<a name="using"></a>2. How to use bzip2</h2></div></div>
-<div></div>
-</div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
-<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
-<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
-<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
-<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
-<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
-<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
-<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
-<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
-</dl>
-</div>
-<p>This chapter contains a copy of the
-<tt class="computeroutput">bzip2</tt> man page, and nothing
-else.</p>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="name"></a>2.1. NAME</h2></div></div>
-<div></div>
-</div>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><tt class="computeroutput">bzip2</tt>,
- <tt class="computeroutput">bunzip2</tt> - a block-sorting file
- compressor, v1.0.3</p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">bzcat</tt> -
- decompresses files to stdout</p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">bzip2recover</tt> -
- recovers data from damaged bzip2 files</p></li>
-</ul></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="synopsis"></a>2.2. SYNOPSIS</h2></div></div>
-<div></div>
-</div>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><tt class="computeroutput">bzip2</tt> [
- -cdfkqstvzVL123456789 ] [ filenames ... ]</p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">bunzip2</tt> [
- -fkvsVL ] [ filenames ... ]</p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">bzcat</tt> [ -s ] [
- filenames ... ]</p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">bzip2recover</tt>
- filename</p></li>
-</ul></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="description"></a>2.3. DESCRIPTION</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">bzip2</tt> compresses files
-using the Burrows-Wheeler block sorting text compression
-algorithm, and Huffman coding. Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</p>
-<p>The command-line options are deliberately very similar to
-those of GNU <tt class="computeroutput">gzip</tt>, but they are
-not identical.</p>
-<p><tt class="computeroutput">bzip2</tt> expects a list of
-file names to accompany the command-line flags. Each file is
-replaced by a compressed version of itself, with the name
-<tt class="computeroutput">original_name.bz2</tt>. Each
-compressed file has the same modification date, permissions, and,
-when possible, ownership as the corresponding original, so that
-these properties can be correctly restored at decompression time.
-File name handling is naive in the sense that there is no
-mechanism for preserving original file names, permissions,
-ownerships or dates in filesystems which lack these concepts, or
-have serious file name length restrictions, such as
-MS-DOS.</p>
-<p><tt class="computeroutput">bzip2</tt> and
-<tt class="computeroutput">bunzip2</tt> will by default not
-overwrite existing files. If you want this to happen, specify
-the <tt class="computeroutput">-f</tt> flag.</p>
-<p>If no file names are specified,
-<tt class="computeroutput">bzip2</tt> compresses from standard
-input to standard output. In this case,
-<tt class="computeroutput">bzip2</tt> will decline to write
-compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.</p>
-<p><tt class="computeroutput">bunzip2</tt> (or
-<tt class="computeroutput">bzip2 -d</tt>) decompresses all
-specified files. Files which were not created by
-<tt class="computeroutput">bzip2</tt> will be detected and
-ignored, and a warning issued.
-<tt class="computeroutput">bzip2</tt> attempts to guess the
-filename for the decompressed file from that of the compressed
-file as follows:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><tt class="computeroutput">filename.bz2 </tt>
- becomes
- <tt class="computeroutput">filename</tt></p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">filename.bz </tt>
- becomes
- <tt class="computeroutput">filename</tt></p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">filename.tbz2</tt>
- becomes
- <tt class="computeroutput">filename.tar</tt></p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">filename.tbz </tt>
- becomes
- <tt class="computeroutput">filename.tar</tt></p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">anyothername </tt>
- becomes
- <tt class="computeroutput">anyothername.out</tt></p></li>
-</ul></div>
-<p>If the file does not end in one of the recognised endings,
-<tt class="computeroutput">.bz2</tt>,
-<tt class="computeroutput">.bz</tt>,
-<tt class="computeroutput">.tbz2</tt> or
-<tt class="computeroutput">.tbz</tt>,
-<tt class="computeroutput">bzip2</tt> complains that it cannot
-guess the name of the original file, and uses the original name
-with <tt class="computeroutput">.out</tt> appended.</p>
-<p>As with compression, supplying no filenames causes
-decompression from standard input to standard output.</p>
-<p><tt class="computeroutput">bunzip2</tt> will correctly
-decompress a file which is the concatenation of two or more
-compressed files. The result is the concatenation of the
-corresponding uncompressed files. Integrity testing
-(<tt class="computeroutput">-t</tt>) of concatenated compressed
-files is also supported.</p>
-<p>You can also compress or decompress files to the standard
-output by giving the <tt class="computeroutput">-c</tt> flag.
-Multiple files may be compressed and decompressed like this. The
-resulting outputs are fed sequentially to stdout. Compression of
-multiple files in this manner generates a stream containing
-multiple compressed file representations. Such a stream can be
-decompressed correctly only by
-<tt class="computeroutput">bzip2</tt> version 0.9.0 or later.
-Earlier versions of <tt class="computeroutput">bzip2</tt> will
-stop after decompressing the first file in the stream.</p>
-<p><tt class="computeroutput">bzcat</tt> (or
-<tt class="computeroutput">bzip2 -dc</tt>) decompresses all
-specified files to the standard output.</p>
-<p><tt class="computeroutput">bzip2</tt> will read arguments
-from the environment variables
-<tt class="computeroutput">BZIP2</tt> and
-<tt class="computeroutput">BZIP</tt>, in that order, and will
-process them before any arguments read from the command line.
-This gives a convenient way to supply default arguments.</p>
-<p>Compression is always performed, even if the compressed
-file is slightly larger than the original. Files of less than
-about one hundred bytes tend to get larger, since the compression
-mechanism has a constant overhead in the region of 50 bytes.
-Random data (including the output of most file compressors) is
-coded at about 8.05 bits per byte, giving an expansion of around
-0.5%.</p>
-<p>As a self-check for your protection,
-<tt class="computeroutput">bzip2</tt> uses 32-bit CRCs to make
-sure that the decompressed version of a file is identical to the
-original. This guards against corruption of the compressed data,
-and against undetected bugs in
-<tt class="computeroutput">bzip2</tt> (hopefully very unlikely).
-The chances of data corruption going undetected is microscopic,
-about one chance in four billion for each file processed. Be
-aware, though, that the check occurs upon decompression, so it
-can only tell you that something is wrong. It can't help you
-recover the original uncompressed data. You can use
-<tt class="computeroutput">bzip2recover</tt> to try to recover
-data from damaged files.</p>
-<p>Return values: 0 for a normal exit, 1 for environmental
-problems (file not found, invalid flags, I/O errors, etc.), 2
-to indicate a corrupt compressed file, 3 for an internal
-consistency error (eg, bug) which caused
-<tt class="computeroutput">bzip2</tt> to panic.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="options"></a>2.4. OPTIONS</h2></div></div>
-<div></div>
-</div>
-<div class="variablelist"><dl>
-<dt><span class="term"><tt class="computeroutput">-c --stdout</tt></span></dt>
-<dd><p>Compress or decompress to standard
- output.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-d --decompress</tt></span></dt>
-<dd><p>Force decompression.
- <tt class="computeroutput">bzip2</tt>,
- <tt class="computeroutput">bunzip2</tt> and
- <tt class="computeroutput">bzcat</tt> are really the same
- program, and the decision about what actions to take is done on
- the basis of which name is used. This flag overrides that
- mechanism, and forces bzip2 to decompress.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-z --compress</tt></span></dt>
-<dd><p>The complement to
- <tt class="computeroutput">-d</tt>: forces compression,
- regardless of the invokation name.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-t --test</tt></span></dt>
-<dd><p>Check integrity of the specified file(s), but
- don't decompress them. This really performs a trial
- decompression and throws away the result.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-f --force</tt></span></dt>
-<dd>
-<p>Force overwrite of output files. Normally,
- <tt class="computeroutput">bzip2</tt> will not overwrite
- existing output files. Also forces
- <tt class="computeroutput">bzip2</tt> to break hard links to
- files, which it otherwise wouldn't do.</p>
-<p><tt class="computeroutput">bzip2</tt> normally declines
- to decompress files which don't have the correct magic header
- bytes. If forced (<tt class="computeroutput">-f</tt>),
- however, it will pass such files through unmodified. This is
- how GNU <tt class="computeroutput">gzip</tt> behaves.</p>
-</dd>
-<dt><span class="term"><tt class="computeroutput">-k --keep</tt></span></dt>
-<dd><p>Keep (don't delete) input files during
- compression or decompression.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-s --small</tt></span></dt>
-<dd>
-<p>Reduce memory usage, for compression,
- decompression and testing. Files are decompressed and tested
- using a modified algorithm which only requires 2.5 bytes per
- block byte. This means any file can be decompressed in 2300k
- of memory, albeit at about half the normal speed.</p>
-<p>During compression, <tt class="computeroutput">-s</tt>
- selects a block size of 200k, which limits memory use to around
- the same figure, at the expense of your compression ratio. In
- short, if your machine is low on memory (8 megabytes or less),
- use <tt class="computeroutput">-s</tt> for everything. See
- <a href="#memory-management">MEMORY MANAGEMENT</a> below.</p>
-</dd>
-<dt><span class="term"><tt class="computeroutput">-q --quiet</tt></span></dt>
-<dd><p>Suppress non-essential warning messages.
- Messages pertaining to I/O errors and other critical events
- will not be suppressed.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-v --verbose</tt></span></dt>
-<dd><p>Verbose mode -- show the compression ratio for
- each file processed. Further
- <tt class="computeroutput">-v</tt>'s increase the verbosity
- level, spewing out lots of information which is primarily of
- interest for diagnostic purposes.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-L --license -V --version</tt></span></dt>
-<dd><p>Display the software version, license terms and
- conditions.</p></dd>
-<dt><span class="term"><tt class="computeroutput">-1</tt> (or
- <tt class="computeroutput">--fast</tt>) to
- <tt class="computeroutput">-9</tt> (or
- <tt class="computeroutput">-best</tt>)</span></dt>
-<dd><p>Set the block size to 100 k, 200 k ... 900 k
- when compressing. Has no effect when decompressing. See <a href="#memory-management">MEMORY MANAGEMENT</a> below. The
- <tt class="computeroutput">--fast</tt> and
- <tt class="computeroutput">--best</tt> aliases are primarily
- for GNU <tt class="computeroutput">gzip</tt> compatibility.
- In particular, <tt class="computeroutput">--fast</tt> doesn't
- make things significantly faster. And
- <tt class="computeroutput">--best</tt> merely selects the
- default behaviour.</p></dd>
-<dt><span class="term"><tt class="computeroutput">--</tt></span></dt>
-<dd><p>Treats all subsequent arguments as file names,
- even if they start with a dash. This is so you can handle
- files with names beginning with a dash, for example:
- <tt class="computeroutput">bzip2 --
- -myfilename</tt>.</p></dd>
-<dt>
-<span class="term"><tt class="computeroutput">--repetitive-fast</tt>, </span><span class="term"><tt class="computeroutput">--repetitive-best</tt>, </span>
-</dt>
-<dd><p>These flags are redundant in versions 0.9.5 and
- above. They provided some coarse control over the behaviour of
- the sorting algorithm in earlier versions, which was sometimes
- useful. 0.9.5 and above have an improved algorithm which
- renders these flags irrelevant.</p></dd>
-</dl></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="memory-management"></a>2.5. MEMORY MANAGEMENT</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">bzip2</tt> compresses large
-files in blocks. The block size affects both the compression
-ratio achieved, and the amount of memory needed for compression
-and decompression. The flags <tt class="computeroutput">-1</tt>
-through <tt class="computeroutput">-9</tt> specify the block
-size to be 100,000 bytes through 900,000 bytes (the default)
-respectively. At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-<tt class="computeroutput">bunzip2</tt> then allocates itself
-just enough memory to decompress the file. Since block sizes are
-stored in compressed files, it follows that the flags
-<tt class="computeroutput">-1</tt> to
-<tt class="computeroutput">-9</tt> are irrelevant to and so
-ignored during decompression.</p>
-<p>Compression and decompression requirements, in bytes, can be
-estimated as:</p>
-<pre class="programlisting">Compression: 400k + ( 8 x block size )
-
-Decompression: 100k + ( 4 x block size ), or
- 100k + ( 2.5 x block size )</pre>
-<p>Larger block sizes give rapidly diminishing marginal
-returns. Most of the compression comes from the first two or
-three hundred k of block size, a fact worth bearing in mind when
-using <tt class="computeroutput">bzip2</tt> on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block
-size.</p>
-<p>For files compressed with the default 900k block size,
-<tt class="computeroutput">bunzip2</tt> will require about 3700
-kbytes to decompress. To support decompression of any file on a
-4 megabyte machine, <tt class="computeroutput">bunzip2</tt> has
-an option to decompress using approximately half this amount of
-memory, about 2300 kbytes. Decompression speed is also halved,
-so you should use this option only where necessary. The relevant
-flag is <tt class="computeroutput">-s</tt>.</p>
-<p>In general, try and use the largest block size memory
-constraints allow, since that maximises the compression achieved.
-Compression and decompression speed are virtually unaffected by
-block size.</p>
-<p>Another significant point applies to files which fit in a
-single block -- that means most files you'd encounter using a
-large block size. The amount of real memory touched is
-proportional to the size of the file, since the file is smaller
-than a block. For example, compressing a file 20,000 bytes long
-with the flag <tt class="computeroutput">-9</tt> will cause the
-compressor to allocate around 7600k of memory, but only touch
-400k + 20000 * 8 = 560 kbytes of it. Similarly, the decompressor
-will allocate 3700k but only touch 100k + 20000 * 4 = 180
-kbytes.</p>
-<p>Here is a table which summarises the maximum memory usage
-for different block sizes. Also recorded is the total compressed
-size for 14 files of the Calgary Text Compression Corpus
-totalling 3,141,622 bytes. This column gives some feel for how
-compression varies with block size. These figures tend to
-understate the advantage of larger block sizes for larger files,
-since the Corpus is dominated by smaller files.</p>
-<pre class="programlisting"> Compress Decompress Decompress Corpus
-Flag usage usage -s usage Size
-
- -1 1200k 500k 350k 914704
- -2 2000k 900k 600k 877703
- -3 2800k 1300k 850k 860338
- -4 3600k 1700k 1100k 846899
- -5 4400k 2100k 1350k 845160
- -6 5200k 2500k 1600k 838626
- -7 6100k 2900k 1850k 834096
- -8 6800k 3300k 2100k 828642
- -9 7600k 3700k 2350k 828642</pre>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="recovering"></a>2.6. RECOVERING DATA FROM DAMAGED FILES</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">bzip2</tt> compresses files in
-blocks, usually 900kbytes long. Each block is handled
-independently. If a media or transmission error causes a
-multi-block <tt class="computeroutput">.bz2</tt> file to become
-damaged, it may be possible to recover data from the undamaged
-blocks in the file.</p>
-<p>The compressed representation of each block is delimited by
-a 48-bit pattern, which makes it possible to find the block
-boundaries with reasonable certainty. Each block also carries
-its own 32-bit CRC, so damaged blocks can be distinguished from
-undamaged ones.</p>
-<p><tt class="computeroutput">bzip2recover</tt> is a simple
-program whose purpose is to search for blocks in
-<tt class="computeroutput">.bz2</tt> files, and write each block
-out into its own <tt class="computeroutput">.bz2</tt> file. You
-can then use <tt class="computeroutput">bzip2 -t</tt> to test
-the integrity of the resulting files, and decompress those which
-are undamaged.</p>
-<p><tt class="computeroutput">bzip2recover</tt> takes a
-single argument, the name of the damaged file, and writes a
-number of files <tt class="computeroutput">rec0001file.bz2</tt>,
-<tt class="computeroutput">rec0002file.bz2</tt>, etc, containing
-the extracted blocks. The output filenames are designed so that
-the use of wildcards in subsequent processing -- for example,
-<tt class="computeroutput">bzip2 -dc rec*file.bz2 &gt;
-recovered_data</tt> -- lists the files in the correct
-order.</p>
-<p><tt class="computeroutput">bzip2recover</tt> should be of
-most use dealing with large <tt class="computeroutput">.bz2</tt>
-files, as these will contain many blocks. It is clearly futile
-to use it on damaged single-block files, since a damaged block
-cannot be recovered. If you wish to minimise any potential data
-loss through media or transmission errors, you might consider
-compressing with a smaller block size.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="performance"></a>2.7. PERFORMANCE NOTES</h2></div></div>
-<div></div>
-</div>
-<p>The sorting phase of compression gathers together similar
-strings in the file. Because of this, files containing very long
-runs of repeated symbols, like "aabaabaabaab ..." (repeated
-several hundred times) may compress more slowly than normal.
-Versions 0.9.5 and above fare much better than previous versions
-in this respect. The ratio between worst-case and average-case
-compression time is in the region of 10:1. For previous
-versions, this figure was more like 100:1. You can use the
-<tt class="computeroutput">-vvvv</tt> option to monitor progress
-in great detail, if you want.</p>
-<p>Decompression speed is unaffected by these
-phenomena.</p>
-<p><tt class="computeroutput">bzip2</tt> usually allocates
-several megabytes of memory to operate in, and then charges all
-over it in a fairly random fashion. This means that performance,
-both for compressing and decompressing, is largely determined by
-the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss
-rate have been observed to give disproportionately large
-performance improvements. I imagine
-<tt class="computeroutput">bzip2</tt> will perform best on
-machines with very large caches.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="caveats"></a>2.8. CAVEATS</h2></div></div>
-<div></div>
-</div>
-<p>I/O error messages are not as helpful as they could be.
-<tt class="computeroutput">bzip2</tt> tries hard to detect I/O
-errors and exit cleanly, but the details of what the problem is
-sometimes seem rather misleading.</p>
-<p>This manual page pertains to version 1.0.3 of
-<tt class="computeroutput">bzip2</tt>. Compressed data created
-by this version is entirely forwards and backwards compatible
-with the previous public releases, versions 0.1pl2, 0.9.0 and
-0.9.5, 1.0.0, 1.0.1 and 1.0.2, but with the following exception: 0.9.0
-and above can correctly decompress multiple concatenated
-compressed files. 0.1pl2 cannot do this; it will stop after
-decompressing just the first file in the stream.</p>
-<p><tt class="computeroutput">bzip2recover</tt> versions
-prior to 1.0.2 used 32-bit integers to represent bit positions in
-compressed files, so it could not handle compressed files more
-than 512 megabytes long. Versions 1.0.2 and above use 64-bit ints
-on some platforms which support them (GNU supported targets, and
-Windows). To establish whether or not
-<tt class="computeroutput">bzip2recover</tt> was built with such
-a limitation, run it without arguments. In any event you can
-build yourself an unlimited version if you can recompile it with
-<tt class="computeroutput">MaybeUInt64</tt> set to be an
-unsigned 64-bit integer.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="author"></a>2.9. AUTHOR</h2></div></div>
-<div></div>
-</div>
-<p>Julian Seward,
-<tt class="computeroutput">jseward@bzip.org</tt></p>
-<p>The ideas embodied in
-<tt class="computeroutput">bzip2</tt> are due to (at least) the
-following people: Michael Burrows and David Wheeler (for the
-block sorting transformation), David Wheeler (again, for the
-Huffman coder), Peter Fenwick (for the structured coding model in
-the original <tt class="computeroutput">bzip</tt>, and many
-refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-<tt class="computeroutput">bzip</tt>). I am much indebted for
-their help, support and advice. See the manual in the source
-distribution for pointers to sources of documentation. Christian
-von Roques encouraged me to look for faster sorting algorithms,
-so as to speed up compression. Bela Lubkin encouraged me to
-improve the worst-case compression performance.
-Donna Robinson XMLised the documentation.
-Many people sent
-patches, helped with portability problems, lent machines, gave
-advice and were generally helpful.</p>
-</div>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title">
-<a name="libprog"></a>3. 
-Programming with <tt class="computeroutput">libbzip2</tt>
-</h2></div></div>
-<div></div>
-</div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
-<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. BZ2_bzCompressInit</a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress">3.3.2. BZ2_bzCompress</a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. BZ2_bzCompressEnd</a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. BZ2_bzDecompressInit</a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress">3.3.5. BZ2_bzDecompress</a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. BZ2_bzDecompressEnd</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzreadopen">3.4.1. BZ2_bzReadOpen</a></span></dt>
-<dt><span class="sect2"><a href="#bzread">3.4.2. BZ2_bzRead</a></span></dt>
-<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. BZ2_bzReadGetUnused</a></span></dt>
-<dt><span class="sect2"><a href="#bzreadclose">3.4.4. BZ2_bzReadClose</a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. BZ2_bzWriteOpen</a></span></dt>
-<dt><span class="sect2"><a href="#bzwrite">3.4.6. BZ2_bzWrite</a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. BZ2_bzWriteClose</a></span></dt>
-<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
-<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. BZ2_bzBuffToBuffCompress</a></span></dt>
-<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. BZ2_bzBuffToBuffDecompress</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#zlib-compat">3.6. zlib compatibility functions</a></span></dt>
-<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a stdio-free environment</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of stdio</a></span></dt>
-<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
-</dl>
-</div>
-<p>This chapter describes the programming interface to
-<tt class="computeroutput">libbzip2</tt>.</p>
-<p>For general background information, particularly about
-memory use and performance aspects, you'd be well advised to read
-<a href="#using">How to use bzip2</a> as well.</p>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="top-level"></a>3.1. Top-level structure</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">libbzip2</tt> is a flexible
-library for compressing and decompressing data in the
-<tt class="computeroutput">bzip2</tt> data format. Although
-packaged as a single entity, it helps to regard the library as
-three separate parts: the low level interface, and the high level
-interface, and some utility functions.</p>
-<p>The structure of
-<tt class="computeroutput">libbzip2</tt>'s interfaces is similar
-to that of Jean-loup Gailly's and Mark Adler's excellent
-<tt class="computeroutput">zlib</tt> library.</p>
-<p>All externally visible symbols have names beginning
-<tt class="computeroutput">BZ2_</tt>. This is new in version
-1.0. The intention is to minimise pollution of the namespaces of
-library clients.</p>
-<p>To use any part of the library, you need to
-<tt class="computeroutput">#include &lt;bzlib.h&gt;</tt>
-into your sources.</p>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="ll-summary"></a>3.1.1. Low-level summary</h3></div></div>
-<div></div>
-</div>
-<p>This interface provides services for compressing and
-decompressing data in memory. There's no provision for dealing
-with files, streams or any other I/O mechanisms, just straight
-memory-to-memory work. In fact, this part of the library can be
-compiled without inclusion of
-<tt class="computeroutput">stdio.h</tt>, which may be helpful
-for embedded applications.</p>
-<p>The low-level part of the library has no global variables
-and is therefore thread-safe.</p>
-<p>Six routines make up the low level interface:
-<tt class="computeroutput">BZ2_bzCompressInit</tt>,
-<tt class="computeroutput">BZ2_bzCompress</tt>, and
-<tt class="computeroutput">BZ2_bzCompressEnd</tt> for
-compression, and a corresponding trio
-<tt class="computeroutput">BZ2_bzDecompressInit</tt>,
-<tt class="computeroutput">BZ2_bzDecompress</tt> and
-<tt class="computeroutput">BZ2_bzDecompressEnd</tt> for
-decompression. The <tt class="computeroutput">*Init</tt>
-functions allocate memory for compression/decompression and do
-other initialisations, whilst the
-<tt class="computeroutput">*End</tt> functions close down
-operations and release memory.</p>
-<p>The real work is done by
-<tt class="computeroutput">BZ2_bzCompress</tt> and
-<tt class="computeroutput">BZ2_bzDecompress</tt>. These
-compress and decompress data from a user-supplied input buffer to
-a user-supplied output buffer. These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions. This is a flexible mechanism allowing a
-consumer-pull style of activity, or producer-push, or a mixture
-of both.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="hl-summary"></a>3.1.2. High-level summary</h3></div></div>
-<div></div>
-</div>
-<p>This interface provides some handy wrappers around the
-low-level interface to facilitate reading and writing
-<tt class="computeroutput">bzip2</tt> format files
-(<tt class="computeroutput">.bz2</tt> files). The routines
-provide hooks to facilitate reading files in which the
-<tt class="computeroutput">bzip2</tt> data stream is embedded
-within some larger-scale file structure, or where there are
-multiple <tt class="computeroutput">bzip2</tt> data streams
-concatenated end-to-end.</p>
-<p>For reading files,
-<tt class="computeroutput">BZ2_bzReadOpen</tt>,
-<tt class="computeroutput">BZ2_bzRead</tt>,
-<tt class="computeroutput">BZ2_bzReadClose</tt> and
-<tt class="computeroutput">BZ2_bzReadGetUnused</tt> are
-supplied. For writing files,
-<tt class="computeroutput">BZ2_bzWriteOpen</tt>,
-<tt class="computeroutput">BZ2_bzWrite</tt> and
-<tt class="computeroutput">BZ2_bzWriteFinish</tt> are
-available.</p>
-<p>As with the low-level library, no global variables are used
-so the library is per se thread-safe. However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult <tt class="computeroutput">errno</tt> to
-determine the cause of the error. In that case, you'd need a C
-library which correctly supports
-<tt class="computeroutput">errno</tt> in a multithreaded
-environment.</p>
-<p>To make the library a little simpler and more portable,
-<tt class="computeroutput">BZ2_bzReadOpen</tt> and
-<tt class="computeroutput">BZ2_bzWriteOpen</tt> require you to
-pass them file handles (<tt class="computeroutput">FILE*</tt>s)
-which have previously been opened for reading or writing
-respectively. That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="util-fns-summary"></a>3.1.3. Utility functions summary</h3></div></div>
-<div></div>
-</div>
-<p>For very simple needs,
-<tt class="computeroutput">BZ2_bzBuffToBuffCompress</tt> and
-<tt class="computeroutput">BZ2_bzBuffToBuffDecompress</tt> are
-provided. These compress data in memory from one buffer to
-another buffer in a single function call. You should assess
-whether these functions fulfill your memory-to-memory
-compression/decompression requirements before investing effort in
-understanding the more general but more complex low-level
-interface.</p>
-<p>Yoshioka Tsuneo
-(<tt class="computeroutput">QWF00133@niftyserve.or.jp</tt> /
-<tt class="computeroutput">tsuneo-y@is.aist-nara.ac.jp</tt>) has
-contributed some functions to give better
-<tt class="computeroutput">zlib</tt> compatibility. These
-functions are <tt class="computeroutput">BZ2_bzopen</tt>,
-<tt class="computeroutput">BZ2_bzread</tt>,
-<tt class="computeroutput">BZ2_bzwrite</tt>,
-<tt class="computeroutput">BZ2_bzflush</tt>,
-<tt class="computeroutput">BZ2_bzclose</tt>,
-<tt class="computeroutput">BZ2_bzerror</tt> and
-<tt class="computeroutput">BZ2_bzlibVersion</tt>. You may find
-these functions more convenient for simple file reading and
-writing, than those in the high-level interface. These functions
-are not (yet) officially part of the library, and are minimally
-documented here. If they break, you get to keep all the pieces.
-I hope to document them properly when time permits.</p>
-<p>Yoshioka also contributed modifications to allow the
-library to be built as a Windows DLL.</p>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="err-handling"></a>3.2. Error handling</h2></div></div>
-<div></div>
-</div>
-<p>The library is designed to recover cleanly in all
-situations, including the worst-case situation of decompressing
-random data. I'm not 100% sure that it can always do this, so
-you might want to add a signal handler to catch segmentation
-violations during decompression if you are feeling especially
-paranoid. I would be interested in hearing more about the
-robustness of the library to corrupted compressed data.</p>
-<p>Version 1.0.3 more robust in this respect than any
-previous version. Investigations with Valgrind (a tool for detecting
-problems with memory management) indicate
-that, at least for the few files I tested, all single-bit errors
-in the decompressed data are caught properly, with no
-segmentation faults, no uses of uninitialised data, no out of
-range reads or writes, and no infinite looping in the decompressor.
-So it's certainly pretty robust, although
-I wouldn't claim it to be totally bombproof.</p>
-<p>The file <tt class="computeroutput">bzlib.h</tt> contains
-all definitions needed to use the library. In particular, you
-should definitely not include
-<tt class="computeroutput">bzlib_private.h</tt>.</p>
-<p>In <tt class="computeroutput">bzlib.h</tt>, the various
-return values are defined. The following list is not intended as
-an exhaustive description of the circumstances in which a given
-value may be returned -- those descriptions are given later.
-Rather, it is intended to convey the rough meaning of each return
-value. The first five actions are normal and not intended to
-denote an error situation.</p>
-<div class="variablelist"><dl>
-<dt><span class="term"><tt class="computeroutput">BZ_OK</tt></span></dt>
-<dd><p>The requested action was completed
- successfully.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_RUN_OK, BZ_FLUSH_OK,
- BZ_FINISH_OK</tt></span></dt>
-<dd><p>In
- <tt class="computeroutput">BZ2_bzCompress</tt>, the requested
- flush/finish/nothing-special action was completed
- successfully.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_STREAM_END</tt></span></dt>
-<dd><p>Compression of data was completed, or the
- logical stream end was detected during
- decompression.</p></dd>
-</dl></div>
-<p>The following return values indicate an error of some
-kind.</p>
-<div class="variablelist"><dl>
-<dt><span class="term"><tt class="computeroutput">BZ_CONFIG_ERROR</tt></span></dt>
-<dd><p>Indicates that the library has been improperly
- compiled on your platform -- a major configuration error.
- Specifically, it means that
- <tt class="computeroutput">sizeof(char)</tt>,
- <tt class="computeroutput">sizeof(short)</tt> and
- <tt class="computeroutput">sizeof(int)</tt> are not 1, 2 and
- 4 respectively, as they should be. Note that the library
- should still work properly on 64-bit platforms which follow
- the LP64 programming model -- that is, where
- <tt class="computeroutput">sizeof(long)</tt> and
- <tt class="computeroutput">sizeof(void*)</tt> are 8. Under
- LP64, <tt class="computeroutput">sizeof(int)</tt> is still 4,
- so <tt class="computeroutput">libbzip2</tt>, which doesn't
- use the <tt class="computeroutput">long</tt> type, is
- OK.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_SEQUENCE_ERROR</tt></span></dt>
-<dd><p>When using the library, it is important to call
- the functions in the correct sequence and with data structures
- (buffers etc) in the correct states.
- <tt class="computeroutput">libbzip2</tt> checks as much as it
- can to ensure this is happening, and returns
- <tt class="computeroutput">BZ_SEQUENCE_ERROR</tt> if not.
- Code which complies precisely with the function semantics, as
- detailed below, should never receive this value; such an event
- denotes buggy code which you should
- investigate.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_PARAM_ERROR</tt></span></dt>
-<dd><p>Returned when a parameter to a function call is
- out of range or otherwise manifestly incorrect. As with
- <tt class="computeroutput">BZ_SEQUENCE_ERROR</tt>, this
- denotes a bug in the client code. The distinction between
- <tt class="computeroutput">BZ_PARAM_ERROR</tt> and
- <tt class="computeroutput">BZ_SEQUENCE_ERROR</tt> is a bit
- hazy, but still worth making.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_MEM_ERROR</tt></span></dt>
-<dd><p>Returned when a request to allocate memory
- failed. Note that the quantity of memory needed to decompress
- a stream cannot be determined until the stream's header has
- been read. So
- <tt class="computeroutput">BZ2_bzDecompress</tt> and
- <tt class="computeroutput">BZ2_bzRead</tt> may return
- <tt class="computeroutput">BZ_MEM_ERROR</tt> even though some
- of the compressed data has been read. The same is not true
- for compression; once
- <tt class="computeroutput">BZ2_bzCompressInit</tt> or
- <tt class="computeroutput">BZ2_bzWriteOpen</tt> have
- successfully completed,
- <tt class="computeroutput">BZ_MEM_ERROR</tt> cannot
- occur.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_DATA_ERROR</tt></span></dt>
-<dd><p>Returned when a data integrity error is
- detected during decompression. Most importantly, this means
- when stored and computed CRCs for the data do not match. This
- value is also returned upon detection of any other anomaly in
- the compressed data.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_DATA_ERROR_MAGIC</tt></span></dt>
-<dd><p>As a special case of
- <tt class="computeroutput">BZ_DATA_ERROR</tt>, it is
- sometimes useful to know when the compressed stream does not
- start with the correct magic bytes (<tt class="computeroutput">'B' 'Z'
- 'h'</tt>).</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_IO_ERROR</tt></span></dt>
-<dd><p>Returned by
- <tt class="computeroutput">BZ2_bzRead</tt> and
- <tt class="computeroutput">BZ2_bzWrite</tt> when there is an
- error reading or writing in the compressed file, and by
- <tt class="computeroutput">BZ2_bzReadOpen</tt> and
- <tt class="computeroutput">BZ2_bzWriteOpen</tt> for attempts
- to use a file for which the error indicator (viz,
- <tt class="computeroutput">ferror(f)</tt>) is set. On
- receipt of <tt class="computeroutput">BZ_IO_ERROR</tt>, the
- caller should consult <tt class="computeroutput">errno</tt>
- and/or <tt class="computeroutput">perror</tt> to acquire
- operating-system specific information about the
- problem.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_UNEXPECTED_EOF</tt></span></dt>
-<dd><p>Returned by
- <tt class="computeroutput">BZ2_bzRead</tt> when the
- compressed file finishes before the logical end of stream is
- detected.</p></dd>
-<dt><span class="term"><tt class="computeroutput">BZ_OUTBUFF_FULL</tt></span></dt>
-<dd><p>Returned by
- <tt class="computeroutput">BZ2_bzBuffToBuffCompress</tt> and
- <tt class="computeroutput">BZ2_bzBuffToBuffDecompress</tt> to
- indicate that the output data will not fit into the output
- buffer provided.</p></dd>
-</dl></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="low-level"></a>3.3. Low-level interface</h2></div></div>
-<div></div>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzcompress-init"></a>3.3.1. <tt class="computeroutput">BZ2_bzCompressInit</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">typedef struct {
- char *next_in;
- unsigned int avail_in;
- unsigned int total_in_lo32;
- unsigned int total_in_hi32;
-
- char *next_out;
- unsigned int avail_out;
- unsigned int total_out_lo32;
- unsigned int total_out_hi32;
-
- void *state;
-
- void *(*bzalloc)(void *,int,int);
- void (*bzfree)(void *,void *);
- void *opaque;
-} bz_stream;
-
-int BZ2_bzCompressInit ( bz_stream *strm,
- int blockSize100k,
- int verbosity,
- int workFactor );</pre>
-<p>Prepares for compression. The
-<tt class="computeroutput">bz_stream</tt> structure holds all
-data pertaining to the compression activity. A
-<tt class="computeroutput">bz_stream</tt> structure should be
-allocated and initialised prior to the call. The fields of
-<tt class="computeroutput">bz_stream</tt> comprise the entirety
-of the user-visible data. <tt class="computeroutput">state</tt>
-is a pointer to the private data structures required for
-compression.</p>
-<p>Custom memory allocators are supported, via fields
-<tt class="computeroutput">bzalloc</tt>,
-<tt class="computeroutput">bzfree</tt>, and
-<tt class="computeroutput">opaque</tt>. The value
-<tt class="computeroutput">opaque</tt> is passed to as the first
-argument to all calls to <tt class="computeroutput">bzalloc</tt>
-and <tt class="computeroutput">bzfree</tt>, but is otherwise
-ignored by the library. The call <tt class="computeroutput">bzalloc (
-opaque, n, m )</tt> is expected to return a pointer
-<tt class="computeroutput">p</tt> to <tt class="computeroutput">n *
-m</tt> bytes of memory, and <tt class="computeroutput">bzfree (
-opaque, p )</tt> should free that memory.</p>
-<p>If you don't want to use a custom memory allocator, set
-<tt class="computeroutput">bzalloc</tt>,
-<tt class="computeroutput">bzfree</tt> and
-<tt class="computeroutput">opaque</tt> to
-<tt class="computeroutput">NULL</tt>, and the library will then
-use the standard <tt class="computeroutput">malloc</tt> /
-<tt class="computeroutput">free</tt> routines.</p>
-<p>Before calling
-<tt class="computeroutput">BZ2_bzCompressInit</tt>, fields
-<tt class="computeroutput">bzalloc</tt>,
-<tt class="computeroutput">bzfree</tt> and
-<tt class="computeroutput">opaque</tt> should be filled
-appropriately, as just described. Upon return, the internal
-state will have been allocated and initialised, and
-<tt class="computeroutput">total_in_lo32</tt>,
-<tt class="computeroutput">total_in_hi32</tt>,
-<tt class="computeroutput">total_out_lo32</tt> and
-<tt class="computeroutput">total_out_hi32</tt> will have been
-set to zero. These four fields are used by the library to inform
-the caller of the total amount of data passed into and out of the
-library, respectively. You should not try to change them. As of
-version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the <tt class="computeroutput">_hi32</tt>
-fields to store the upper 32 bits of the count. So, for example,
-the total amount of data in is <tt class="computeroutput">(total_in_hi32
-&lt;&lt; 32) + total_in_lo32</tt>.</p>
-<p>Parameter <tt class="computeroutput">blockSize100k</tt>
-specifies the block size to be used for compression. It should
-be a value between 1 and 9 inclusive, and the actual block size
-used is 100000 x this figure. 9 gives the best compression but
-takes most memory.</p>
-<p>Parameter <tt class="computeroutput">verbosity</tt> should
-be set to a number between 0 and 4 inclusive. 0 is silent, and
-greater numbers give increasingly verbose monitoring/debugging
-output. If the library has been compiled with
-<tt class="computeroutput">-DBZ_NO_STDIO</tt>, no such output
-will appear for any verbosity setting.</p>
-<p>Parameter <tt class="computeroutput">workFactor</tt>
-controls how the compression phase behaves when presented with
-worst case, highly repetitive, input data. If compression runs
-into difficulties caused by repetitive data, the library switches
-from the standard sorting algorithm to a fallback algorithm. The
-fallback is slower than the standard algorithm by perhaps a
-factor of three, but always behaves reasonably, no matter how bad
-the input.</p>
-<p>Lower values of <tt class="computeroutput">workFactor</tt>
-reduce the amount of effort the standard algorithm will expend
-before resorting to the fallback. You should set this parameter
-carefully; too low, and many inputs will be handled by the
-fallback algorithm and so compress rather slowly, too high, and
-your average-to-worst case compression times can become very
-large. The default value of 30 gives reasonable behaviour over a
-wide range of circumstances.</p>
-<p>Allowable values range from 0 to 250 inclusive. 0 is a
-special case, equivalent to using the default value of 30.</p>
-<p>Note that the compressed output generated is the same
-regardless of whether or not the fallback algorithm is
-used.</p>
-<p>Be aware also that this parameter may disappear entirely in
-future versions of the library. In principle it should be
-possible to devise a good way to automatically choose which
-algorithm to use. Such a mechanism would render the parameter
-obsolete.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if strm is NULL
- or blockSize &lt; 1 or blockSize &gt; 9
- or verbosity &lt; 0 or verbosity &gt; 4
- or workFactor &lt; 0 or workFactor &gt; 250
-BZ_MEM_ERROR
- if not enough memory is available
-BZ_OK
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzCompress
- if BZ_OK is returned
- no specific action needed in case of error</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzCompress"></a>3.3.2. <tt class="computeroutput">BZ2_bzCompress</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzCompress ( bz_stream *strm, int action );</pre>
-<p>Provides more input and/or output buffer space for the
-library. The caller maintains input and output buffers, and
-calls <tt class="computeroutput">BZ2_bzCompress</tt> to transfer
-data between them.</p>
-<p>Before each call to
-<tt class="computeroutput">BZ2_bzCompress</tt>,
-<tt class="computeroutput">next_in</tt> should point at the data
-to be compressed, and <tt class="computeroutput">avail_in</tt>
-should indicate how many bytes the library may read.
-<tt class="computeroutput">BZ2_bzCompress</tt> updates
-<tt class="computeroutput">next_in</tt>,
-<tt class="computeroutput">avail_in</tt> and
-<tt class="computeroutput">total_in</tt> to reflect the number
-of bytes it has read.</p>
-<p>Similarly, <tt class="computeroutput">next_out</tt> should
-point to a buffer in which the compressed data is to be placed,
-with <tt class="computeroutput">avail_out</tt> indicating how
-much output space is available.
-<tt class="computeroutput">BZ2_bzCompress</tt> updates
-<tt class="computeroutput">next_out</tt>,
-<tt class="computeroutput">avail_out</tt> and
-<tt class="computeroutput">total_out</tt> to reflect the number
-of bytes output.</p>
-<p>You may provide and remove as little or as much data as you
-like on each call of
-<tt class="computeroutput">BZ2_bzCompress</tt>. In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient. You should always
-ensure that at least one byte of output space is available at
-each call.</p>
-<p>A second purpose of
-<tt class="computeroutput">BZ2_bzCompress</tt> is to request a
-change of mode of the compressed stream.</p>
-<p>Conceptually, a compressed stream can be in one of four
-states: IDLE, RUNNING, FLUSHING and FINISHING. Before
-initialisation
-(<tt class="computeroutput">BZ2_bzCompressInit</tt>) and after
-termination (<tt class="computeroutput">BZ2_bzCompressEnd</tt>),
-a stream is regarded as IDLE.</p>
-<p>Upon initialisation
-(<tt class="computeroutput">BZ2_bzCompressInit</tt>), the stream
-is placed in the RUNNING state. Subsequent calls to
-<tt class="computeroutput">BZ2_bzCompress</tt> should pass
-<tt class="computeroutput">BZ_RUN</tt> as the requested action;
-other actions are illegal and will result in
-<tt class="computeroutput">BZ_SEQUENCE_ERROR</tt>.</p>
-<p>At some point, the calling program will have provided all
-the input data it wants to. It will then want to finish up -- in
-effect, asking the library to process any data it might have
-buffered internally. In this state,
-<tt class="computeroutput">BZ2_bzCompress</tt> will no longer
-attempt to read data from
-<tt class="computeroutput">next_in</tt>, but it will want to
-write data to <tt class="computeroutput">next_out</tt>. Because
-the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a
-single call of
-<tt class="computeroutput">BZ2_bzCompress</tt>.</p>
-<p>Instead, the calling program passes
-<tt class="computeroutput">BZ_FINISH</tt> as an action to
-<tt class="computeroutput">BZ2_bzCompress</tt>. This changes
-the stream's state to FINISHING. Any remaining input (ie,
-<tt class="computeroutput">next_in[0 .. avail_in-1]</tt>) is
-compressed and transferred to the output buffer. To do this,
-<tt class="computeroutput">BZ2_bzCompress</tt> must be called
-repeatedly until all the output has been consumed. At that
-point, <tt class="computeroutput">BZ2_bzCompress</tt> returns
-<tt class="computeroutput">BZ_STREAM_END</tt>, and the stream's
-state is set back to IDLE.
-<tt class="computeroutput">BZ2_bzCompressEnd</tt> should then be
-called.</p>
-<p>Just to make sure the calling program does not cheat, the
-library makes a note of <tt class="computeroutput">avail_in</tt>
-at the time of the first call to
-<tt class="computeroutput">BZ2_bzCompress</tt> which has
-<tt class="computeroutput">BZ_FINISH</tt> as an action (ie, at
-the time the program has announced its intention to not supply
-any more input). By comparing this value with that of
-<tt class="computeroutput">avail_in</tt> over subsequent calls
-to <tt class="computeroutput">BZ2_bzCompress</tt>, the library
-can detect any attempts to slip in more data to compress. Any
-calls for which this is detected will return
-<tt class="computeroutput">BZ_SEQUENCE_ERROR</tt>. This
-indicates a programming mistake which should be corrected.</p>
-<p>Instead of asking to finish, the calling program may ask
-<tt class="computeroutput">BZ2_bzCompress</tt> to take all the
-remaining input, compress it and terminate the current
-(Burrows-Wheeler) compression block. This could be useful for
-error control purposes. The mechanism is analogous to that for
-finishing: call <tt class="computeroutput">BZ2_bzCompress</tt>
-with an action of <tt class="computeroutput">BZ_FLUSH</tt>,
-remove output data, and persist with the
-<tt class="computeroutput">BZ_FLUSH</tt> action until the value
-<tt class="computeroutput">BZ_RUN</tt> is returned. As with
-finishing, <tt class="computeroutput">BZ2_bzCompress</tt>
-detects any attempt to provide more input data once the flush has
-begun.</p>
-<p>Once the flush is complete, the stream returns to the
-normal RUNNING state.</p>
-<p>This all sounds pretty complex, but isn't really. Here's a
-table which shows which actions are allowable in each state, what
-action will be taken, what the next state is, and what the
-non-error return values are. Note that you can't explicitly ask
-what state the stream is in, but nor do you need to -- it can be
-inferred from the values returned by
-<tt class="computeroutput">BZ2_bzCompress</tt>.</p>
-<pre class="programlisting">IDLE/any
- Illegal. IDLE state only exists after BZ2_bzCompressEnd or
- before BZ2_bzCompressInit.
- Return value = BZ_SEQUENCE_ERROR
-
-RUNNING/BZ_RUN
- Compress from next_in to next_out as much as possible.
- Next state = RUNNING
- Return value = BZ_RUN_OK
-
-RUNNING/BZ_FLUSH
- Remember current value of next_in. Compress from next_in
- to next_out as much as possible, but do not accept any more input.
- Next state = FLUSHING
- Return value = BZ_FLUSH_OK
-
-RUNNING/BZ_FINISH
- Remember current value of next_in. Compress from next_in
- to next_out as much as possible, but do not accept any more input.
- Next state = FINISHING
- Return value = BZ_FINISH_OK
-
-FLUSHING/BZ_FLUSH
- Compress from next_in to next_out as much as possible,
- but do not accept any more input.
- If all the existing input has been used up and all compressed
- output has been removed
- Next state = RUNNING; Return value = BZ_RUN_OK
- else
- Next state = FLUSHING; Return value = BZ_FLUSH_OK
-
-FLUSHING/other
- Illegal.
- Return value = BZ_SEQUENCE_ERROR
-
-FINISHING/BZ_FINISH
- Compress from next_in to next_out as much as possible,
- but to not accept any more input.
- If all the existing input has been used up and all compressed
- output has been removed
- Next state = IDLE; Return value = BZ_STREAM_END
- else
- Next state = FINISHING; Return value = BZ_FINISHING
-
-FINISHING/other
- Illegal.
- Return value = BZ_SEQUENCE_ERROR</pre>
-<p>That still looks complicated? Well, fair enough. The
-usual sequence of calls for compressing a load of data is:</p>
-<div class="orderedlist"><ol type="1">
-<li><p>Get started with
- <tt class="computeroutput">BZ2_bzCompressInit</tt>.</p></li>
-<li><p>Shovel data in and shlurp out its compressed form
- using zero or more calls of
- <tt class="computeroutput">BZ2_bzCompress</tt> with action =
- <tt class="computeroutput">BZ_RUN</tt>.</p></li>
-<li><p>Finish up. Repeatedly call
- <tt class="computeroutput">BZ2_bzCompress</tt> with action =
- <tt class="computeroutput">BZ_FINISH</tt>, copying out the
- compressed output, until
- <tt class="computeroutput">BZ_STREAM_END</tt> is
- returned.</p></li>
-<li><p>Close up and go home. Call
- <tt class="computeroutput">BZ2_bzCompressEnd</tt>.</p></li>
-</ol></div>
-<p>If the data you want to compress fits into your input
-buffer all at once, you can skip the calls of
-<tt class="computeroutput">BZ2_bzCompress ( ..., BZ_RUN )</tt>
-and just do the <tt class="computeroutput">BZ2_bzCompress ( ..., BZ_FINISH
-)</tt> calls.</p>
-<p>All required memory is allocated by
-<tt class="computeroutput">BZ2_bzCompressInit</tt>. The
-compression library can accept any data at all (obviously). So
-you shouldn't get any error return values from the
-<tt class="computeroutput">BZ2_bzCompress</tt> calls. If you
-do, they will be
-<tt class="computeroutput">BZ_SEQUENCE_ERROR</tt>, and indicate
-a bug in your programming.</p>
-<p>Trivial other possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
- if strm is NULL, or strm-&gt;s is NULL</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzCompress-end"></a>3.3.3. <tt class="computeroutput">BZ2_bzCompressEnd</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzCompressEnd ( bz_stream *strm );</pre>
-<p>Releases all memory associated with a compression
-stream.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR if strm is NULL or strm-&gt;s is NULL
-BZ_OK otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzDecompress-init"></a>3.3.4. <tt class="computeroutput">BZ2_bzDecompressInit</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );</pre>
-<p>Prepares for decompression. As with
-<tt class="computeroutput">BZ2_bzCompressInit</tt>, a
-<tt class="computeroutput">bz_stream</tt> record should be
-allocated and initialised before the call. Fields
-<tt class="computeroutput">bzalloc</tt>,
-<tt class="computeroutput">bzfree</tt> and
-<tt class="computeroutput">opaque</tt> should be set if a custom
-memory allocator is required, or made
-<tt class="computeroutput">NULL</tt> for the normal
-<tt class="computeroutput">malloc</tt> /
-<tt class="computeroutput">free</tt> routines. Upon return, the
-internal state will have been initialised, and
-<tt class="computeroutput">total_in</tt> and
-<tt class="computeroutput">total_out</tt> will be zero.</p>
-<p>For the meaning of parameter
-<tt class="computeroutput">verbosity</tt>, see
-<tt class="computeroutput">BZ2_bzCompressInit</tt>.</p>
-<p>If <tt class="computeroutput">small</tt> is nonzero, the
-library will use an alternative decompression algorithm which
-uses less memory but at the cost of decompressing more slowly
-(roughly speaking, half the speed, but the maximum memory
-requirement drops to around 2300k). See <a href="#using">How to use bzip2</a>
-for more information on memory management.</p>
-<p>Note that the amount of memory needed to decompress a
-stream cannot be determined until the stream's header has been
-read, so even if
-<tt class="computeroutput">BZ2_bzDecompressInit</tt> succeeds, a
-subsequent <tt class="computeroutput">BZ2_bzDecompress</tt>
-could fail with
-<tt class="computeroutput">BZ_MEM_ERROR</tt>.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if ( small != 0 &amp;&amp; small != 1 )
- or (verbosity &lt;; 0 || verbosity &gt; 4)
-BZ_MEM_ERROR
- if insufficient memory is available</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzDecompress
- if BZ_OK was returned
- no specific action required in case of error</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzDecompress"></a>3.3.5. <tt class="computeroutput">BZ2_bzDecompress</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzDecompress ( bz_stream *strm );</pre>
-<p>Provides more input and/out output buffer space for the
-library. The caller maintains input and output buffers, and uses
-<tt class="computeroutput">BZ2_bzDecompress</tt> to transfer
-data between them.</p>
-<p>Before each call to
-<tt class="computeroutput">BZ2_bzDecompress</tt>,
-<tt class="computeroutput">next_in</tt> should point at the
-compressed data, and <tt class="computeroutput">avail_in</tt>
-should indicate how many bytes the library may read.
-<tt class="computeroutput">BZ2_bzDecompress</tt> updates
-<tt class="computeroutput">next_in</tt>,
-<tt class="computeroutput">avail_in</tt> and
-<tt class="computeroutput">total_in</tt> to reflect the number
-of bytes it has read.</p>
-<p>Similarly, <tt class="computeroutput">next_out</tt> should
-point to a buffer in which the uncompressed output is to be
-placed, with <tt class="computeroutput">avail_out</tt>
-indicating how much output space is available.
-<tt class="computeroutput">BZ2_bzCompress</tt> updates
-<tt class="computeroutput">next_out</tt>,
-<tt class="computeroutput">avail_out</tt> and
-<tt class="computeroutput">total_out</tt> to reflect the number
-of bytes output.</p>
-<p>You may provide and remove as little or as much data as you
-like on each call of
-<tt class="computeroutput">BZ2_bzDecompress</tt>. In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient. You should always
-ensure that at least one byte of output space is available at
-each call.</p>
-<p>Use of <tt class="computeroutput">BZ2_bzDecompress</tt> is
-simpler than
-<tt class="computeroutput">BZ2_bzCompress</tt>.</p>
-<p>You should provide input and remove output as described
-above, and repeatedly call
-<tt class="computeroutput">BZ2_bzDecompress</tt> until
-<tt class="computeroutput">BZ_STREAM_END</tt> is returned.
-Appearance of <tt class="computeroutput">BZ_STREAM_END</tt>
-denotes that <tt class="computeroutput">BZ2_bzDecompress</tt>
-has detected the logical end of the compressed stream.
-<tt class="computeroutput">BZ2_bzDecompress</tt> will not
-produce <tt class="computeroutput">BZ_STREAM_END</tt> until all
-output data has been placed into the output buffer, so once
-<tt class="computeroutput">BZ_STREAM_END</tt> appears, you are
-guaranteed to have available all the decompressed output, and
-<tt class="computeroutput">BZ2_bzDecompressEnd</tt> can safely
-be called.</p>
-<p>If case of an error return value, you should call
-<tt class="computeroutput">BZ2_bzDecompressEnd</tt> to clean up
-and release memory.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
- if strm is NULL or strm-&gt;s is NULL
- or strm-&gt;avail_out &lt; 1
-BZ_DATA_ERROR
- if a data integrity error is detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
- if the compressed stream doesn't begin with the right magic bytes
-BZ_MEM_ERROR
- if there wasn't enough memory available
-BZ_STREAM_END
- if the logical end of the data stream was detected and all
- output in has been consumed, eg s--&gt;avail_out &gt; 0
-BZ_OK
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzDecompress
- if BZ_OK was returned
-BZ2_bzDecompressEnd
- otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzDecompress-end"></a>3.3.6. <tt class="computeroutput">BZ2_bzDecompressEnd</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzDecompressEnd ( bz_stream *strm );</pre>
-<p>Releases all memory associated with a decompression
-stream.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
- if strm is NULL or strm-&gt;s is NULL
-BZ_OK
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting"> None.</pre>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="hl-interface"></a>3.4. High-level interface</h2></div></div>
-<div></div>
-</div>
-<p>This interface provides functions for reading and writing
-<tt class="computeroutput">bzip2</tt> format files. First, some
-general points.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>All of the functions take an
- <tt class="computeroutput">int*</tt> first argument,
- <tt class="computeroutput">bzerror</tt>. After each call,
- <tt class="computeroutput">bzerror</tt> should be consulted
- first to determine the outcome of the call. If
- <tt class="computeroutput">bzerror</tt> is
- <tt class="computeroutput">BZ_OK</tt>, the call completed
- successfully, and only then should the return value of the
- function (if any) be consulted. If
- <tt class="computeroutput">bzerror</tt> is
- <tt class="computeroutput">BZ_IO_ERROR</tt>, there was an
- error reading/writing the underlying compressed file, and you
- should then consult <tt class="computeroutput">errno</tt> /
- <tt class="computeroutput">perror</tt> to determine the cause
- of the difficulty. <tt class="computeroutput">bzerror</tt>
- may also be set to various other values; precise details are
- given on a per-function basis below.</p></li>
-<li style="list-style-type: disc"><p>If <tt class="computeroutput">bzerror</tt> indicates
- an error (ie, anything except
- <tt class="computeroutput">BZ_OK</tt> and
- <tt class="computeroutput">BZ_STREAM_END</tt>), you should
- immediately call
- <tt class="computeroutput">BZ2_bzReadClose</tt> (or
- <tt class="computeroutput">BZ2_bzWriteClose</tt>, depending on
- whether you are attempting to read or to write) to free up all
- resources associated with the stream. Once an error has been
- indicated, behaviour of all calls except
- <tt class="computeroutput">BZ2_bzReadClose</tt>
- (<tt class="computeroutput">BZ2_bzWriteClose</tt>) is
- undefined. The implication is that (1)
- <tt class="computeroutput">bzerror</tt> should be checked
- after each call, and (2) if
- <tt class="computeroutput">bzerror</tt> indicates an error,
- <tt class="computeroutput">BZ2_bzReadClose</tt>
- (<tt class="computeroutput">BZ2_bzWriteClose</tt>) should then
- be called to clean up.</p></li>
-<li style="list-style-type: disc"><p>The <tt class="computeroutput">FILE*</tt> arguments
- passed to <tt class="computeroutput">BZ2_bzReadOpen</tt> /
- <tt class="computeroutput">BZ2_bzWriteOpen</tt> should be set
- to binary mode. Most Unix systems will do this by default, but
- other platforms, including Windows and Mac, will not. If you
- omit this, you may encounter problems when moving code to new
- platforms.</p></li>
-<li style="list-style-type: disc"><p>Memory allocation requests are handled by
- <tt class="computeroutput">malloc</tt> /
- <tt class="computeroutput">free</tt>. At present there is no
- facility for user-defined memory allocators in the file I/O
- functions (could easily be added, though).</p></li>
-</ul></div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzreadopen"></a>3.4.1. <tt class="computeroutput">BZ2_bzReadOpen</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">typedef void BZFILE;
-
-BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f,
- int verbosity, int small,
- void *unused, int nUnused );</pre>
-<p>Prepare to read compressed data from file handle
-<tt class="computeroutput">f</tt>.
-<tt class="computeroutput">f</tt> should refer to a file which
-has been opened for reading, and for which the error indicator
-(<tt class="computeroutput">ferror(f)</tt>)is not set. If
-<tt class="computeroutput">small</tt> is 1, the library will try
-to decompress using less memory, at the expense of speed.</p>
-<p>For reasons explained below,
-<tt class="computeroutput">BZ2_bzRead</tt> will decompress the
-<tt class="computeroutput">nUnused</tt> bytes starting at
-<tt class="computeroutput">unused</tt>, before starting to read
-from the file <tt class="computeroutput">f</tt>. At most
-<tt class="computeroutput">BZ_MAX_UNUSED</tt> bytes may be
-supplied like this. If this facility is not required, you should
-pass <tt class="computeroutput">NULL</tt> and
-<tt class="computeroutput">0</tt> for
-<tt class="computeroutput">unused</tt> and
-n<tt class="computeroutput">Unused</tt> respectively.</p>
-<p>For the meaning of parameters
-<tt class="computeroutput">small</tt> and
-<tt class="computeroutput">verbosity</tt>, see
-<tt class="computeroutput">BZ2_bzDecompressInit</tt>.</p>
-<p>The amount of memory needed to decompress a file cannot be
-determined until the file's header has been read. So it is
-possible that <tt class="computeroutput">BZ2_bzReadOpen</tt>
-returns <tt class="computeroutput">BZ_OK</tt> but a subsequent
-call of <tt class="computeroutput">BZ2_bzRead</tt> will return
-<tt class="computeroutput">BZ_MEM_ERROR</tt>.</p>
-<p>Possible assignments to
-<tt class="computeroutput">bzerror</tt>:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if f is NULL
- or small is neither 0 nor 1
- or ( unused == NULL &amp;&amp; nUnused != 0 )
- or ( unused != NULL &amp;&amp; !(0 &lt;= nUnused &lt;= BZ_MAX_UNUSED) )
-BZ_IO_ERROR
- if ferror(f) is nonzero
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OK
- otherwise.</pre>
-<p>Possible return values:</p>
-<pre class="programlisting">Pointer to an abstract BZFILE
- if bzerror is BZ_OK
-NULL
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzRead
- if bzerror is BZ_OK
-BZ2_bzClose
- otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzread"></a>3.4.2. <tt class="computeroutput">BZ2_bzRead</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
-<p>Reads up to <tt class="computeroutput">len</tt>
-(uncompressed) bytes from the compressed file
-<tt class="computeroutput">b</tt> into the buffer
-<tt class="computeroutput">buf</tt>. If the read was
-successful, <tt class="computeroutput">bzerror</tt> is set to
-<tt class="computeroutput">BZ_OK</tt> and the number of bytes
-read is returned. If the logical end-of-stream was detected,
-<tt class="computeroutput">bzerror</tt> will be set to
-<tt class="computeroutput">BZ_STREAM_END</tt>, and the number of
-bytes read is returned. All other
-<tt class="computeroutput">bzerror</tt> values denote an
-error.</p>
-<p><tt class="computeroutput">BZ2_bzRead</tt> will supply
-<tt class="computeroutput">len</tt> bytes, unless the logical
-stream end is detected or an error occurs. Because of this, it
-is possible to detect the stream end by observing when the number
-of bytes returned is less than the number requested.
-Nevertheless, this is regarded as inadvisable; you should instead
-check <tt class="computeroutput">bzerror</tt> after every call
-and watch out for
-<tt class="computeroutput">BZ_STREAM_END</tt>.</p>
-<p>Internally, <tt class="computeroutput">BZ2_bzRead</tt>
-copies data from the compressed file in chunks of size
-<tt class="computeroutput">BZ_MAX_UNUSED</tt> bytes before
-decompressing it. If the file contains more bytes than strictly
-needed to reach the logical end-of-stream,
-<tt class="computeroutput">BZ2_bzRead</tt> will almost certainly
-read some of the trailing data before signalling
-<tt class="computeroutput">BZ_SEQUENCE_END</tt>. To collect the
-read but unused data once
-<tt class="computeroutput">BZ_SEQUENCE_END</tt> has appeared,
-call <tt class="computeroutput">BZ2_bzReadGetUnused</tt>
-immediately before
-<tt class="computeroutput">BZ2_bzReadClose</tt>.</p>
-<p>Possible assignments to
-<tt class="computeroutput">bzerror</tt>:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
- if b is NULL or buf is NULL or len &lt; 0
-BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzWriteOpen
-BZ_IO_ERROR
- if there is an error reading from the compressed file
-BZ_UNEXPECTED_EOF
- if the compressed file ended before
- the logical end-of-stream was detected
-BZ_DATA_ERROR
- if a data integrity error was detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
- if the stream does not begin with the requisite header bytes
- (ie, is not a bzip2 data file). This is really
- a special case of BZ_DATA_ERROR.
-BZ_MEM_ERROR
- if insufficient memory was available
-BZ_STREAM_END
- if the logical end of stream was detected.
-BZ_OK
- otherwise.</pre>
-<p>Possible return values:</p>
-<pre class="programlisting">number of bytes read
- if bzerror is BZ_OK or BZ_STREAM_END
-undefined
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
- if bzerror is BZ_OK
-collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
- if bzerror is BZ_SEQUENCE_END
-BZ2_bzReadClose
- otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzreadgetunused"></a>3.4.3. <tt class="computeroutput">BZ2_bzReadGetUnused</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b,
- void** unused, int* nUnused );</pre>
-<p>Returns data which was read from the compressed file but
-was not needed to get to the logical end-of-stream.
-<tt class="computeroutput">*unused</tt> is set to the address of
-the data, and <tt class="computeroutput">*nUnused</tt> to the
-number of bytes. <tt class="computeroutput">*nUnused</tt> will
-be set to a value between <tt class="computeroutput">0</tt> and
-<tt class="computeroutput">BZ_MAX_UNUSED</tt> inclusive.</p>
-<p>This function may only be called once
-<tt class="computeroutput">BZ2_bzRead</tt> has signalled
-<tt class="computeroutput">BZ_STREAM_END</tt> but before
-<tt class="computeroutput">BZ2_bzReadClose</tt>.</p>
-<p>Possible assignments to
-<tt class="computeroutput">bzerror</tt>:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
- if b is NULL
- or unused is NULL or nUnused is NULL
-BZ_SEQUENCE_ERROR
- if BZ_STREAM_END has not been signalled
- or if b was opened with BZ2_bzWriteOpen
-BZ_OK
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzReadClose</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzreadclose"></a>3.4.4. <tt class="computeroutput">BZ2_bzReadClose</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">void BZ2_bzReadClose ( int *bzerror, BZFILE *b );</pre>
-<p>Releases all memory pertaining to the compressed file
-<tt class="computeroutput">b</tt>.
-<tt class="computeroutput">BZ2_bzReadClose</tt> does not call
-<tt class="computeroutput">fclose</tt> on the underlying file
-handle, so you should do that yourself if appropriate.
-<tt class="computeroutput">BZ2_bzReadClose</tt> should be called
-to clean up after all error situations.</p>
-<p>Possible assignments to
-<tt class="computeroutput">bzerror</tt>:</p>
-<pre class="programlisting">BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzOpenWrite
-BZ_OK
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">none</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzwriteopen"></a>3.4.5. <tt class="computeroutput">BZ2_bzWriteOpen</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f,
- int blockSize100k, int verbosity,
- int workFactor );</pre>
-<p>Prepare to write compressed data to file handle
-<tt class="computeroutput">f</tt>.
-<tt class="computeroutput">f</tt> should refer to a file which
-has been opened for writing, and for which the error indicator
-(<tt class="computeroutput">ferror(f)</tt>)is not set.</p>
-<p>For the meaning of parameters
-<tt class="computeroutput">blockSize100k</tt>,
-<tt class="computeroutput">verbosity</tt> and
-<tt class="computeroutput">workFactor</tt>, see
-<tt class="computeroutput">BZ2_bzCompressInit</tt>.</p>
-<p>All required memory is allocated at this stage, so if the
-call completes successfully,
-<tt class="computeroutput">BZ_MEM_ERROR</tt> cannot be signalled
-by a subsequent call to
-<tt class="computeroutput">BZ2_bzWrite</tt>.</p>
-<p>Possible assignments to
-<tt class="computeroutput">bzerror</tt>:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if f is NULL
- or blockSize100k &lt; 1 or blockSize100k &gt; 9
-BZ_IO_ERROR
- if ferror(f) is nonzero
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OK
- otherwise</pre>
-<p>Possible return values:</p>
-<pre class="programlisting">Pointer to an abstract BZFILE
- if bzerror is BZ_OK
-NULL
- otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzWrite
- if bzerror is BZ_OK
- (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
-BZ2_bzWriteClose
- otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzwrite"></a>3.4.6. <tt class="computeroutput">BZ2_bzWrite</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
-<p>Absorbs <tt class="computeroutput">len</tt> bytes from the
-buffer <tt class="computeroutput">buf</tt>, eventually to be
-compressed and written to the file.</p>
-<p>Possible assignments to
-<tt class="computeroutput">bzerror</tt>:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
- if b is NULL or buf is NULL or len &lt; 0
-BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
- if there is an error writing the compressed file.
-BZ_OK
- otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzwriteclose"></a>3.4.7. <tt class="computeroutput">BZ2_bzWriteClose</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out );
-
-void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32 );</pre>
-<p>Compresses and flushes to the compressed file all data so
-far supplied by <tt class="computeroutput">BZ2_bzWrite</tt>.
-The logical end-of-stream markers are also written, so subsequent
-calls to <tt class="computeroutput">BZ2_bzWrite</tt> are
-illegal. All memory associated with the compressed file
-<tt class="computeroutput">b</tt> is released.
-<tt class="computeroutput">fflush</tt> is called on the
-compressed file, but it is not
-<tt class="computeroutput">fclose</tt>'d.</p>
-<p>If <tt class="computeroutput">BZ2_bzWriteClose</tt> is
-called to clean up after an error, the only action is to release
-the memory. The library records the error codes issued by
-previous calls, so this situation will be detected automatically.
-There is no attempt to complete the compression operation, nor to
-<tt class="computeroutput">fflush</tt> the compressed file. You
-can force this behaviour to happen even in the case of no error,
-by passing a nonzero value to
-<tt class="computeroutput">abandon</tt>.</p>
-<p>If <tt class="computeroutput">nbytes_in</tt> is non-null,
-<tt class="computeroutput">*nbytes_in</tt> will be set to be the
-total volume of uncompressed data handled. Similarly,
-<tt class="computeroutput">nbytes_out</tt> will be set to the
-total volume of compressed data written. For compatibility with
-older versions of the library,
-<tt class="computeroutput">BZ2_bzWriteClose</tt> only yields the
-lower 32 bits of these counts. Use
-<tt class="computeroutput">BZ2_bzWriteClose64</tt> if you want
-the full 64 bit counts. These two functions are otherwise
-absolutely identical.</p>
-<p>Possible assignments to
-<tt class="computeroutput">bzerror</tt>:</p>
-<pre class="programlisting">BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
- if there is an error writing the compressed file
-BZ_OK
- otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="embed"></a>3.4.8. Handling embedded compressed data streams</h3></div></div>
-<div></div>
-</div>
-<p>The high-level library facilitates use of
-<tt class="computeroutput">bzip2</tt> data streams which form
-some part of a surrounding, larger data stream.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>For writing, the library takes an open file handle,
- writes compressed data to it,
- <tt class="computeroutput">fflush</tt>es it but does not
- <tt class="computeroutput">fclose</tt> it. The calling
- application can write its own data before and after the
- compressed data stream, using that same file handle.</p></li>
-<li style="list-style-type: disc"><p>Reading is more complex, and the facilities are not as
- general as they could be since generality is hard to reconcile
- with efficiency. <tt class="computeroutput">BZ2_bzRead</tt>
- reads from the compressed file in blocks of size
- <tt class="computeroutput">BZ_MAX_UNUSED</tt> bytes, and in
- doing so probably will overshoot the logical end of compressed
- stream. To recover this data once decompression has ended,
- call <tt class="computeroutput">BZ2_bzReadGetUnused</tt> after
- the last call of <tt class="computeroutput">BZ2_bzRead</tt>
- (the one returning
- <tt class="computeroutput">BZ_STREAM_END</tt>) but before
- calling
- <tt class="computeroutput">BZ2_bzReadClose</tt>.</p></li>
-</ul></div>
-<p>This mechanism makes it easy to decompress multiple
-<tt class="computeroutput">bzip2</tt> streams placed end-to-end.
-As the end of one stream, when
-<tt class="computeroutput">BZ2_bzRead</tt> returns
-<tt class="computeroutput">BZ_STREAM_END</tt>, call
-<tt class="computeroutput">BZ2_bzReadGetUnused</tt> to collect
-the unused data (copy it into your own buffer somewhere). That
-data forms the start of the next compressed stream. To start
-uncompressing that next stream, call
-<tt class="computeroutput">BZ2_bzReadOpen</tt> again, feeding in
-the unused data via the <tt class="computeroutput">unused</tt> /
-<tt class="computeroutput">nUnused</tt> parameters. Keep doing
-this until <tt class="computeroutput">BZ_STREAM_END</tt> return
-coincides with the physical end of file
-(<tt class="computeroutput">feof(f)</tt>). In this situation
-<tt class="computeroutput">BZ2_bzReadGetUnused</tt> will of
-course return no data.</p>
-<p>This should give some feel for how the high-level interface
-can be used. If you require extra flexibility, you'll have to
-bite the bullet and get to grips with the low-level
-interface.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="std-rdwr"></a>3.4.9. Standard file-reading/writing code</h3></div></div>
-<div></div>
-</div>
-<p>Here's how you'd write data to a compressed file:</p>
-<pre class="programlisting">FILE* f;
-BZFILE* b;
-int nBuf;
-char buf[ /* whatever size you like */ ];
-int bzerror;
-int nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzWriteOpen( &amp;bzerror, f, 9 );
-if (bzerror != BZ_OK) {
- BZ2_bzWriteClose ( b );
- /* handle error */
-}
-
-while ( /* condition */ ) {
- /* get data to write into buf, and set nBuf appropriately */
- nWritten = BZ2_bzWrite ( &amp;bzerror, b, buf, nBuf );
- if (bzerror == BZ_IO_ERROR) {
- BZ2_bzWriteClose ( &amp;bzerror, b );
- /* handle error */
- }
-}
-
-BZ2_bzWriteClose( &amp;bzerror, b );
-if (bzerror == BZ_IO_ERROR) {
- /* handle error */
-}</pre>
-<p>And to read from a compressed file:</p>
-<pre class="programlisting">FILE* f;
-BZFILE* b;
-int nBuf;
-char buf[ /* whatever size you like */ ];
-int bzerror;
-int nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzReadOpen ( &amp;bzerror, f, 0, NULL, 0 );
-if ( bzerror != BZ_OK ) {
- BZ2_bzReadClose ( &amp;bzerror, b );
- /* handle error */
-}
-
-bzerror = BZ_OK;
-while ( bzerror == BZ_OK &amp;&amp; /* arbitrary other conditions */) {
- nBuf = BZ2_bzRead ( &amp;bzerror, b, buf, /* size of buf */ );
- if ( bzerror == BZ_OK ) {
- /* do something with buf[0 .. nBuf-1] */
- }
-}
-if ( bzerror != BZ_STREAM_END ) {
- BZ2_bzReadClose ( &amp;bzerror, b );
- /* handle error */
-} else {
- BZ2_bzReadClose ( &amp;bzerror );
-}</pre>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="util-fns"></a>3.5. Utility functions</h2></div></div>
-<div></div>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzbufftobuffcompress"></a>3.5.1. <tt class="computeroutput">BZ2_bzBuffToBuffCompress</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzBuffToBuffCompress( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor );</pre>
-<p>Attempts to compress the data in <tt class="computeroutput">source[0
-.. sourceLen-1]</tt> into the destination buffer,
-<tt class="computeroutput">dest[0 .. *destLen-1]</tt>. If the
-destination buffer is big enough,
-<tt class="computeroutput">*destLen</tt> is set to the size of
-the compressed data, and <tt class="computeroutput">BZ_OK</tt>
-is returned. If the compressed data won't fit,
-<tt class="computeroutput">*destLen</tt> is unchanged, and
-<tt class="computeroutput">BZ_OUTBUFF_FULL</tt> is
-returned.</p>
-<p>Compression in this manner is a one-shot event, done with a
-single call to this function. The resulting compressed data is a
-complete <tt class="computeroutput">bzip2</tt> format data
-stream. There is no mechanism for making additional calls to
-provide extra input data. If you want that kind of mechanism,
-use the low-level interface.</p>
-<p>For the meaning of parameters
-<tt class="computeroutput">blockSize100k</tt>,
-<tt class="computeroutput">verbosity</tt> and
-<tt class="computeroutput">workFactor</tt>, see
-<tt class="computeroutput">BZ2_bzCompressInit</tt>.</p>
-<p>To guarantee that the compressed data will fit in its
-buffer, allocate an output buffer of size 1% larger than the
-uncompressed data, plus six hundred extra bytes.</p>
-<p><tt class="computeroutput">BZ2_bzBuffToBuffDecompress</tt>
-will not write data at or beyond
-<tt class="computeroutput">dest[*destLen]</tt>, even in case of
-buffer overflow.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if dest is NULL or destLen is NULL
- or blockSize100k &lt; 1 or blockSize100k &gt; 9
- or verbosity &lt; 0 or verbosity &gt; 4
- or workFactor &lt; 0 or workFactor &gt; 250
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OUTBUFF_FULL
- if the size of the compressed data exceeds *destLen
-BZ_OK
- otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="bzbufftobuffdecompress"></a>3.5.2. <tt class="computeroutput">BZ2_bzBuffToBuffDecompress</tt></h3></div></div>
-<div></div>
-</div>
-<pre class="programlisting">int BZ2_bzBuffToBuffDecompress( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity );</pre>
-<p>Attempts to decompress the data in <tt class="computeroutput">source[0
-.. sourceLen-1]</tt> into the destination buffer,
-<tt class="computeroutput">dest[0 .. *destLen-1]</tt>. If the
-destination buffer is big enough,
-<tt class="computeroutput">*destLen</tt> is set to the size of
-the uncompressed data, and <tt class="computeroutput">BZ_OK</tt>
-is returned. If the compressed data won't fit,
-<tt class="computeroutput">*destLen</tt> is unchanged, and
-<tt class="computeroutput">BZ_OUTBUFF_FULL</tt> is
-returned.</p>
-<p><tt class="computeroutput">source</tt> is assumed to hold
-a complete <tt class="computeroutput">bzip2</tt> format data
-stream.
-<tt class="computeroutput">BZ2_bzBuffToBuffDecompress</tt> tries
-to decompress the entirety of the stream into the output
-buffer.</p>
-<p>For the meaning of parameters
-<tt class="computeroutput">small</tt> and
-<tt class="computeroutput">verbosity</tt>, see
-<tt class="computeroutput">BZ2_bzDecompressInit</tt>.</p>
-<p>Because the compression ratio of the compressed data cannot
-be known in advance, there is no easy way to guarantee that the
-output buffer will be big enough. You may of course make
-arrangements in your code to record the size of the uncompressed
-data, but such a mechanism is beyond the scope of this
-library.</p>
-<p><tt class="computeroutput">BZ2_bzBuffToBuffDecompress</tt>
-will not write data at or beyond
-<tt class="computeroutput">dest[*destLen]</tt>, even in case of
-buffer overflow.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if dest is NULL or destLen is NULL
- or small != 0 &amp;&amp; small != 1
- or verbosity &lt; 0 or verbosity &gt; 4
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OUTBUFF_FULL
- if the size of the compressed data exceeds *destLen
-BZ_DATA_ERROR
- if a data integrity error was detected in the compressed data
-BZ_DATA_ERROR_MAGIC
- if the compressed data doesn't begin with the right magic bytes
-BZ_UNEXPECTED_EOF
- if the compressed data ends unexpectedly
-BZ_OK
- otherwise</pre>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="zlib-compat"></a>3.6. <tt class="computeroutput">zlib</tt> compatibility functions</h2></div></div>
-<div></div>
-</div>
-<p>Yoshioka Tsuneo has contributed some functions to give
-better <tt class="computeroutput">zlib</tt> compatibility.
-These functions are <tt class="computeroutput">BZ2_bzopen</tt>,
-<tt class="computeroutput">BZ2_bzread</tt>,
-<tt class="computeroutput">BZ2_bzwrite</tt>,
-<tt class="computeroutput">BZ2_bzflush</tt>,
-<tt class="computeroutput">BZ2_bzclose</tt>,
-<tt class="computeroutput">BZ2_bzerror</tt> and
-<tt class="computeroutput">BZ2_bzlibVersion</tt>. These
-functions are not (yet) officially part of the library. If they
-break, you get to keep all the pieces. Nevertheless, I think
-they work ok.</p>
-<pre class="programlisting">typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );</pre>
-<p>Returns a string indicating the library version.</p>
-<pre class="programlisting">BZFILE * BZ2_bzopen ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int fd, const char *mode );</pre>
-<p>Opens a <tt class="computeroutput">.bz2</tt> file for
-reading or writing, using either its name or a pre-existing file
-descriptor. Analogous to <tt class="computeroutput">fopen</tt>
-and <tt class="computeroutput">fdopen</tt>.</p>
-<pre class="programlisting">int BZ2_bzread ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );</pre>
-<p>Reads/writes data from/to a previously opened
-<tt class="computeroutput">BZFILE</tt>. Analogous to
-<tt class="computeroutput">fread</tt> and
-<tt class="computeroutput">fwrite</tt>.</p>
-<pre class="programlisting">int BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );</pre>
-<p>Flushes/closes a <tt class="computeroutput">BZFILE</tt>.
-<tt class="computeroutput">BZ2_bzflush</tt> doesn't actually do
-anything. Analogous to <tt class="computeroutput">fflush</tt>
-and <tt class="computeroutput">fclose</tt>.</p>
-<pre class="programlisting">const char * BZ2_bzerror ( BZFILE *b, int *errnum )</pre>
-<p>Returns a string describing the more recent error status of
-<tt class="computeroutput">b</tt>, and also sets
-<tt class="computeroutput">*errnum</tt> to its numerical
-value.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="stdio-free"></a>3.7. Using the library in a <tt class="computeroutput">stdio</tt>-free environment</h2></div></div>
-<div></div>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="stdio-bye"></a>3.7.1. Getting rid of <tt class="computeroutput">stdio</tt></h3></div></div>
-<div></div>
-</div>
-<p>In a deeply embedded application, you might want to use
-just the memory-to-memory functions. You can do this
-conveniently by compiling the library with preprocessor symbol
-<tt class="computeroutput">BZ_NO_STDIO</tt> defined. Doing this
-gives you a library containing only the following eight
-functions:</p>
-<p><tt class="computeroutput">BZ2_bzCompressInit</tt>,
-<tt class="computeroutput">BZ2_bzCompress</tt>,
-<tt class="computeroutput">BZ2_bzCompressEnd</tt>
-<tt class="computeroutput">BZ2_bzDecompressInit</tt>,
-<tt class="computeroutput">BZ2_bzDecompress</tt>,
-<tt class="computeroutput">BZ2_bzDecompressEnd</tt>
-<tt class="computeroutput">BZ2_bzBuffToBuffCompress</tt>,
-<tt class="computeroutput">BZ2_bzBuffToBuffDecompress</tt></p>
-<p>When compiled like this, all functions will ignore
-<tt class="computeroutput">verbosity</tt> settings.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage">
-<div><div><h3 class="title">
-<a name="critical-error"></a>3.7.2. Critical error handling</h3></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">libbzip2</tt> contains a number
-of internal assertion checks which should, needless to say, never
-be activated. Nevertheless, if an assertion should fail,
-behaviour depends on whether or not the library was compiled with
-<tt class="computeroutput">BZ_NO_STDIO</tt> set.</p>
-<p>For a normal compile, an assertion failure yields the
-message:</p>
-<div class="blockquote"><blockquote class="blockquote">
-<p>bzip2/libbzip2: internal error number N.</p>
-<p>This is a bug in bzip2/libbzip2, 1.0.3 of 15 February 2005.
-Please report it to me at: jseward@bzip.org. If this happened
-when you were using some program which uses libbzip2 as a
-component, you should also report this bug to the author(s)
-of that program. Please make an effort to report this bug;
-timely and accurate bug reports eventually lead to higher
-quality software. Thanks. Julian Seward, 15 February 2005.
-</p>
-</blockquote></div>
-<p>where <tt class="computeroutput">N</tt> is some error code
-number. If <tt class="computeroutput">N == 1007</tt>, it also
-prints some extra text advising the reader that unreliable memory
-is often associated with internal error 1007. (This is a
-frequently-observed-phenomenon with versions 1.0.0/1.0.1).</p>
-<p><tt class="computeroutput">exit(3)</tt> is then
-called.</p>
-<p>For a <tt class="computeroutput">stdio</tt>-free library,
-assertion failures result in a call to a function declared
-as:</p>
-<pre class="programlisting">extern void bz_internal_error ( int errcode );</pre>
-<p>The relevant code is passed as a parameter. You should
-supply such a function.</p>
-<p>In either case, once an assertion failure has occurred, any
-<tt class="computeroutput">bz_stream</tt> records involved can
-be regarded as invalid. You should not attempt to resume normal
-operation with them.</p>
-<p>You may, of course, change critical error handling to suit
-your needs. As I said above, critical errors indicate bugs in
-the library and should not occur. All "normal" error situations
-are indicated via error return codes from functions, and can be
-recovered from.</p>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="win-dll"></a>3.8. Making a Windows DLL</h2></div></div>
-<div></div>
-</div>
-<p>Everything related to Windows has been contributed by
-Yoshioka Tsuneo
-(<tt class="computeroutput">QWF00133@niftyserve.or.jp</tt> /
-<tt class="computeroutput">tsuneo-y@is.aist-nara.ac.jp</tt>), so
-you should send your queries to him (but perhaps Cc: me,
-<tt class="computeroutput">jseward@bzip.org</tt>).</p>
-<p>My vague understanding of what to do is: using Visual C++
-5.0, open the project file
-<tt class="computeroutput">libbz2.dsp</tt>, and build. That's
-all.</p>
-<p>If you can't open the project file for some reason, make a
-new one, naming these files:
-<tt class="computeroutput">blocksort.c</tt>,
-<tt class="computeroutput">bzlib.c</tt>,
-<tt class="computeroutput">compress.c</tt>,
-<tt class="computeroutput">crctable.c</tt>,
-<tt class="computeroutput">decompress.c</tt>,
-<tt class="computeroutput">huffman.c</tt>,
-<tt class="computeroutput">randtable.c</tt> and
-<tt class="computeroutput">libbz2.def</tt>. You will also need
-to name the header files <tt class="computeroutput">bzlib.h</tt>
-and <tt class="computeroutput">bzlib_private.h</tt>.</p>
-<p>If you don't use VC++, you may need to define the
-proprocessor symbol
-<tt class="computeroutput">_WIN32</tt>.</p>
-<p>Finally, <tt class="computeroutput">dlltest.c</tt> is a
-sample program using the DLL. It has a project file,
-<tt class="computeroutput">dlltest.dsp</tt>.</p>
-<p>If you just want a makefile for Visual C, have a look at
-<tt class="computeroutput">makefile.msc</tt>.</p>
-<p>Be aware that if you compile
-<tt class="computeroutput">bzip2</tt> itself on Win32, you must
-set <tt class="computeroutput">BZ_UNIX</tt> to 0 and
-<tt class="computeroutput">BZ_LCCWIN32</tt> to 1, in the file
-<tt class="computeroutput">bzip2.c</tt>, before compiling.
-Otherwise the resulting binary won't work correctly.</p>
-<p>I haven't tried any of this stuff myself, but it all looks
-plausible.</p>
-</div>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title">
-<a name="misc"></a>4. Miscellanea</h2></div></div>
-<div></div>
-</div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
-<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
-<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
-<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
-<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
-</dl>
-</div>
-<p>These are just some random thoughts of mine. Your mileage
-may vary.</p>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="limits"></a>4.1. Limitations of the compressed file format</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">bzip2-1.0.X</tt>,
-<tt class="computeroutput">0.9.5</tt> and
-<tt class="computeroutput">0.9.0</tt> use exactly the same file
-format as the original version,
-<tt class="computeroutput">bzip2-0.1</tt>. This decision was
-made in the interests of stability. Creating yet another
-incompatible compressed file format would create further
-confusion and disruption for users.</p>
-<p>Nevertheless, this is not a painless decision. Development
-work since the release of
-<tt class="computeroutput">bzip2-0.1</tt> in August 1997 has
-shown complexities in the file format which slow down
-decompression and, in retrospect, are unnecessary. These
-are:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>The run-length encoder, which is the first of the
- compression transformations, is entirely irrelevant. The
- original purpose was to protect the sorting algorithm from the
- very worst case input: a string of repeated symbols. But
- algorithm steps Q6a and Q6b in the original Burrows-Wheeler
- technical report (SRC-124) show how repeats can be handled
- without difficulty in block sorting.</p></li>
-<li style="list-style-type: disc">
-<p>The randomisation mechanism doesn't really need to be
- there. Udi Manber and Gene Myers published a suffix array
- construction algorithm a few years back, which can be employed
- to sort any block, no matter how repetitive, in O(N log N)
- time. Subsequent work by Kunihiko Sadakane has produced a
- derivative O(N (log N)^2) algorithm which usually outperforms
- the Manber-Myers algorithm.</p>
-<p>I could have changed to Sadakane's algorithm, but I find
- it to be slower than <tt class="computeroutput">bzip2</tt>'s
- existing algorithm for most inputs, and the randomisation
- mechanism protects adequately against bad cases. I didn't
- think it was a good tradeoff to make. Partly this is due to
- the fact that I was not flooded with email complaints about
- <tt class="computeroutput">bzip2-0.1</tt>'s performance on
- repetitive data, so perhaps it isn't a problem for real
- inputs.</p>
-<p>Probably the best long-term solution, and the one I have
- incorporated into 0.9.5 and above, is to use the existing
- sorting algorithm initially, and fall back to a O(N (log N)^2)
- algorithm if the standard algorithm gets into
- difficulties.</p>
-</li>
-<li style="list-style-type: disc"><p>The compressed file format was never designed to be
- handled by a library, and I have had to jump though some hoops
- to produce an efficient implementation of decompression. It's
- a bit hairy. Try passing
- <tt class="computeroutput">decompress.c</tt> through the C
- preprocessor and you'll see what I mean. Much of this
- complexity could have been avoided if the compressed size of
- each block of data was recorded in the data stream.</p></li>
-<li style="list-style-type: disc"><p>An Adler-32 checksum, rather than a CRC32 checksum,
- would be faster to compute.</p></li>
-</ul></div>
-<p>It would be fair to say that the
-<tt class="computeroutput">bzip2</tt> format was frozen before I
-properly and fully understood the performance consequences of
-doing so.</p>
-<p>Improvements which I was able to incorporate into 0.9.0,
-despite using the same file format, are:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>Single array implementation of the inverse BWT. This
- significantly speeds up decompression, presumably because it
- reduces the number of cache misses.</p></li>
-<li style="list-style-type: disc"><p>Faster inverse MTF transform for large MTF values.
- The new implementation is based on the notion of sliding blocks
- of values.</p></li>
-<li style="list-style-type: disc"><p><tt class="computeroutput">bzip2-0.9.0</tt> now reads
- and writes files with <tt class="computeroutput">fread</tt>
- and <tt class="computeroutput">fwrite</tt>; version 0.1 used
- <tt class="computeroutput">putc</tt> and
- <tt class="computeroutput">getc</tt>. Duh! Well, you live
- and learn.</p></li>
-</ul></div>
-<p>Further ahead, it would be nice to be able to do random
-access into files. This will require some careful design of
-compressed file formats.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="port-issues"></a>4.2. Portability issues</h2></div></div>
-<div></div>
-</div>
-<p>After some consideration, I have decided not to use GNU
-<tt class="computeroutput">autoconf</tt> to configure 0.9.5 or
-1.0.</p>
-<p><tt class="computeroutput">autoconf</tt>, admirable and
-wonderful though it is, mainly assists with portability problems
-between Unix-like platforms. But
-<tt class="computeroutput">bzip2</tt> doesn't have much in the
-way of portability problems on Unix; most of the difficulties
-appear when porting to the Mac, or to Microsoft's operating
-systems. <tt class="computeroutput">autoconf</tt> doesn't help
-in those cases, and brings in a whole load of new
-complexity.</p>
-<p>Most people should be able to compile the library and
-program under Unix straight out-of-the-box, so to speak,
-especially if you have a version of GNU C available.</p>
-<p>There are a couple of
-<tt class="computeroutput">__inline__</tt> directives in the
-code. GNU C (<tt class="computeroutput">gcc</tt>) should be
-able to handle them. If you're not using GNU C, your C compiler
-shouldn't see them at all. If your compiler does, for some
-reason, see them and doesn't like them, just
-<tt class="computeroutput">#define</tt>
-<tt class="computeroutput">__inline__</tt> to be
-<tt class="computeroutput">/* */</tt>. One easy way to do this
-is to compile with the flag
-<tt class="computeroutput">-D__inline__=</tt>, which should be
-understood by most Unix compilers.</p>
-<p>If you still have difficulties, try compiling with the
-macro <tt class="computeroutput">BZ_STRICT_ANSI</tt> defined.
-This should enable you to build the library in a strictly ANSI
-compliant environment. Building the program itself like this is
-dangerous and not supported, since you remove
-<tt class="computeroutput">bzip2</tt>'s checks against
-compressing directories, symbolic links, devices, and other
-not-really-a-file entities. This could cause filesystem
-corruption!</p>
-<p>One other thing: if you create a
-<tt class="computeroutput">bzip2</tt> binary for public distribution,
-please consider linking it statically (<tt class="computeroutput">gcc
--static</tt>). This avoids all sorts of library-version
-issues that others may encounter later on.</p>
-<p>If you build <tt class="computeroutput">bzip2</tt> on
-Win32, you must set <tt class="computeroutput">BZ_UNIX</tt> to 0
-and <tt class="computeroutput">BZ_LCCWIN32</tt> to 1, in the
-file <tt class="computeroutput">bzip2.c</tt>, before compiling.
-Otherwise the resulting binary won't work correctly.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="bugs"></a>4.3. Reporting bugs</h2></div></div>
-<div></div>
-</div>
-<p>I tried pretty hard to make sure
-<tt class="computeroutput">bzip2</tt> is bug free, both by
-design and by testing. Hopefully you'll never need to read this
-section for real.</p>
-<p>Nevertheless, if <tt class="computeroutput">bzip2</tt> dies
-with a segmentation fault, a bus error or an internal assertion
-failure, it will ask you to email me a bug report. Experience from
-years of feedback of bzip2 users indicates that almost all these
-problems can be traced to either compiler bugs or hardware
-problems.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc">
-<p>Recompile the program with no optimisation, and
- see if it works. And/or try a different compiler. I heard all
- sorts of stories about various flavours of GNU C (and other
- compilers) generating bad code for
- <tt class="computeroutput">bzip2</tt>, and I've run across two
- such examples myself.</p>
-<p>2.7.X versions of GNU C are known to generate bad code
- from time to time, at high optimisation levels. If you get
- problems, try using the flags
- <tt class="computeroutput">-O2</tt>
- <tt class="computeroutput">-fomit-frame-pointer</tt>
- <tt class="computeroutput">-fno-strength-reduce</tt>. You
- should specifically <span class="emphasis"><em>not</em></span> use
- <tt class="computeroutput">-funroll-loops</tt>.</p>
-<p>You may notice that the Makefile runs six tests as part
- of the build process. If the program passes all of these, it's
- a pretty good (but not 100%) indication that the compiler has
- done its job correctly.</p>
-</li>
-<li style="list-style-type: disc">
-<p>If <tt class="computeroutput">bzip2</tt>
- crashes randomly, and the crashes are not repeatable, you may
- have a flaky memory subsystem.
- <tt class="computeroutput">bzip2</tt> really hammers your
- memory hierarchy, and if it's a bit marginal, you may get these
- problems. Ditto if your disk or I/O subsystem is slowly
- failing. Yup, this really does happen.</p>
-<p>Try using a different machine of the same type, and see
- if you can repeat the problem.</p>
-</li>
-<li style="list-style-type: disc"><p>This isn't really a bug, but ... If
- <tt class="computeroutput">bzip2</tt> tells you your file is
- corrupted on decompression, and you obtained the file via FTP,
- there is a possibility that you forgot to tell FTP to do a
- binary mode transfer. That absolutely will cause the file to
- be non-decompressible. You'll have to transfer it
- again.</p></li>
-</ul></div>
-<p>If you've incorporated
-<tt class="computeroutput">libbzip2</tt> into your own program
-and are getting problems, please, please, please, check that the
-parameters you are passing in calls to the library, are correct,
-and in accordance with what the documentation says is allowable.
-I have tried to make the library robust against such problems,
-but I'm sure I haven't succeeded.</p>
-<p>Finally, if the above comments don't help, you'll have to
-send me a bug report. Now, it's just amazing how many people
-will send me a bug report saying something like:</p>
-<pre class="programlisting">bzip2 crashed with segmentation fault on my machine</pre>
-<p>and absolutely nothing else. Needless to say, a such a
-report is <span class="emphasis"><em>totally, utterly, completely and
-comprehensively 100% useless; a waste of your time, my time, and
-net bandwidth</em></span>. With no details at all, there's no way
-I can possibly begin to figure out what the problem is.</p>
-<p>The rules of the game are: facts, facts, facts. Don't omit
-them because "oh, they won't be relevant". At the bare
-minimum:</p>
-<pre class="programlisting">Machine type. Operating system version.
-Exact version of bzip2 (do bzip2 -V).
-Exact version of the compiler used.
-Flags passed to the compiler.</pre>
-<p>However, the most important single thing that will help me
-is the file that you were trying to compress or decompress at the
-time the problem happened. Without that, my ability to do
-anything more than speculate about the cause, is limited.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="package"></a>4.4. Did you get the right package?</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">bzip2</tt> is a resource hog.
-It soaks up large amounts of CPU cycles and memory. Also, it
-gives very large latencies. In the worst case, you can feed many
-megabytes of uncompressed data into the library before getting
-any compressed output, so this probably rules out applications
-requiring interactive behaviour.</p>
-<p>These aren't faults of my implementation, I hope, but more
-an intrinsic property of the Burrows-Wheeler transform
-(unfortunately). Maybe this isn't what you want.</p>
-<p>If you want a compressor and/or library which is faster,
-uses less memory but gets pretty good compression, and has
-minimal latency, consider Jean-loup Gailly's and Mark Adler's
-work, <tt class="computeroutput">zlib-1.2.1</tt> and
-<tt class="computeroutput">gzip-1.2.4</tt>. Look for them at
-<a href="http://www.zlib.org" target="_top">http://www.zlib.org</a> and
-<a href="http://www.gzip.org" target="_top">http://www.gzip.org</a>
-respectively.</p>
-<p>For something faster and lighter still, you might try Markus F
-X J Oberhumer's <tt class="computeroutput">LZO</tt> real-time
-compression/decompression library, at
-<a href="http://www.oberhumer.com/opensource" target="_top">http://www.oberhumer.com/opensource</a>.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage">
-<div><div><h2 class="title" style="clear: both">
-<a name="reading"></a>4.5. Further Reading</h2></div></div>
-<div></div>
-</div>
-<p><tt class="computeroutput">bzip2</tt> is not research
-work, in the sense that it doesn't present any new ideas.
-Rather, it's an engineering exercise based on existing
-ideas.</p>
-<p>Four documents describe essentially all the ideas behind
-<tt class="computeroutput">bzip2</tt>:</p>
-<div class="literallayout"><p>Michael Burrows and D. J. Wheeler:<br>
-  "A block-sorting lossless data compression algorithm"<br>
-   10th May 1994. <br>
-   Digital SRC Research Report 124.<br>
-   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz<br>
-   If you have trouble finding it, try searching at the<br>
-   New Zealand Digital Library, http://www.nzdl.org.<br>
-<br>
-Daniel S. Hirschberg and Debra A. LeLewer<br>
-  "Efficient Decoding of Prefix Codes"<br>
-   Communications of the ACM, April 1990, Vol 33, Number 4.<br>
-   You might be able to get an electronic copy of this<br>
-   from the ACM Digital Library.<br>
-<br>
-David J. Wheeler<br>
-   Program bred3.c and accompanying document bred3.ps.<br>
-   This contains the idea behind the multi-table Huffman coding scheme.<br>
-   ftp://ftp.cl.cam.ac.uk/users/djw3/<br>
-<br>
-Jon L. Bentley and Robert Sedgewick<br>
-  "Fast Algorithms for Sorting and Searching Strings"<br>
-   Available from Sedgewick's web page,<br>
-   www.cs.princeton.edu/~rs<br>
-</p></div>
-<p>The following paper gives valuable additional insights into
-the algorithm, but is not immediately the basis of any code used
-in bzip2.</p>
-<div class="literallayout"><p>Peter Fenwick:<br>
-   Block Sorting Text Compression<br>
-   Proceedings of the 19th Australasian Computer Science Conference,<br>
-     Melbourne, Australia.  Jan 31 - Feb 2, 1996.<br>
-   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</p></div>
-<p>Kunihiko Sadakane's sorting algorithm, mentioned above, is
-available from:</p>
-<div class="literallayout"><p>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz<br>
-</p></div>
-<p>The Manber-Myers suffix array construction algorithm is
-described in a paper available from:</p>
-<div class="literallayout"><p>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps<br>
-</p></div>
-<p>Finally, the following papers document some
-investigations I made into the performance of sorting
-and decompression algorithms:</p>
-<div class="literallayout"><p>Julian Seward<br>
-   On the Performance of BWT Sorting Algorithms<br>
-   Proceedings of the IEEE Data Compression Conference 2000<br>
-     Snowbird, Utah.  28-30 March 2000.<br>
-<br>
-Julian Seward<br>
-   Space-time Tradeoffs in the Inverse B-W Transform<br>
-   Proceedings of the IEEE Data Compression Conference 2001<br>
-     Snowbird, Utah.  27-29 March 2001.<br>
-</p></div>
-</div>
-</div>
-</div></body>
-</html>
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.pdf b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.pdf
deleted file mode 100644
index 394b8092565..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.ps b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.ps
deleted file mode 100644
index 03831d194c8..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.ps
+++ /dev/null
@@ -1,68244 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: xpdf/pdftops 3.00
-%%LanguageLevel: 2
-%%DocumentSuppliedResources: (atend)
-%%DocumentMedia: plain 612 792 0 () ()
-%%BoundingBox: 0 0 612 792
-%%Pages: 38
-%%EndComments
-%%BeginDefaults
-%%PageMedia: plain
-%%EndDefaults
-%%BeginProlog
-%%BeginResource: procset xpdf 3.00 0
-/xpdf 75 dict def xpdf begin
-% PDF special state
-/pdfDictSize 15 def
-/pdfSetup {
- 3 1 roll 2 array astore
- /setpagedevice where {
- pop 3 dict begin
- /PageSize exch def
- /ImagingBBox null def
- /Policies 1 dict dup begin /PageSize 3 def end def
- { /Duplex true def } if
- currentdict end setpagedevice
- } {
- pop pop
- } ifelse
-} def
-/pdfStartPage {
- pdfDictSize dict begin
- /pdfFill [0] def
- /pdfStroke [0] def
- /pdfLastFill false def
- /pdfLastStroke false def
- /pdfTextMat [1 0 0 1 0 0] def
- /pdfFontSize 0 def
- /pdfCharSpacing 0 def
- /pdfTextRender 0 def
- /pdfTextRise 0 def
- /pdfWordSpacing 0 def
- /pdfHorizScaling 1 def
- /pdfTextClipPath [] def
-} def
-/pdfEndPage { end } def
-% separation convention operators
-/findcmykcustomcolor where {
- pop
-}{
- /findcmykcustomcolor { 5 array astore } def
-} ifelse
-/setcustomcolor where {
- pop
-}{
- /setcustomcolor {
- exch
- [ exch /Separation exch dup 4 get exch /DeviceCMYK exch
- 0 4 getinterval cvx
- [ exch /dup load exch { mul exch dup } /forall load
- /pop load dup ] cvx
- ] setcolorspace setcolor
- } def
-} ifelse
-/customcolorimage where {
- pop
-}{
- /customcolorimage {
- gsave
- [ exch /Separation exch dup 4 get exch /DeviceCMYK exch
- 0 4 getinterval
- [ exch /dup load exch { mul exch dup } /forall load
- /pop load dup ] cvx
- ] setcolorspace
- 10 dict begin
- /ImageType 1 def
- /DataSource exch def
- /ImageMatrix exch def
- /BitsPerComponent exch def
- /Height exch def
- /Width exch def
- /Decode [1 0] def
- currentdict end
- image
- grestore
- } def
-} ifelse
-% PDF color state
-/sCol {
- pdfLastStroke not {
- pdfStroke aload length
- dup 1 eq {
- pop setgray
- }{
- dup 3 eq {
- pop setrgbcolor
- }{
- 4 eq {
- setcmykcolor
- }{
- findcmykcustomcolor exch setcustomcolor
- } ifelse
- } ifelse
- } ifelse
- /pdfLastStroke true def /pdfLastFill false def
- } if
-} def
-/fCol {
- pdfLastFill not {
- pdfFill aload length
- dup 1 eq {
- pop setgray
- }{
- dup 3 eq {
- pop setrgbcolor
- }{
- 4 eq {
- setcmykcolor
- }{
- findcmykcustomcolor exch setcustomcolor
- } ifelse
- } ifelse
- } ifelse
- /pdfLastFill true def /pdfLastStroke false def
- } if
-} def
-% build a font
-/pdfMakeFont {
- 4 3 roll findfont
- 4 2 roll matrix scale makefont
- dup length dict begin
- { 1 index /FID ne { def } { pop pop } ifelse } forall
- /Encoding exch def
- currentdict
- end
- definefont pop
-} def
-/pdfMakeFont16 {
- exch findfont
- dup length dict begin
- { 1 index /FID ne { def } { pop pop } ifelse } forall
- /WMode exch def
- currentdict
- end
- definefont pop
-} def
-/pdfMakeFont16L3 {
- 1 index /CIDFont resourcestatus {
- pop pop 1 index /CIDFont findresource /CIDFontType known
- } {
- false
- } ifelse
- {
- 0 eq { /Identity-H } { /Identity-V } ifelse
- exch 1 array astore composefont pop
- } {
- pdfMakeFont16
- } ifelse
-} def
-% graphics state operators
-/q { gsave pdfDictSize dict begin } def
-/Q { end grestore } def
-/cm { concat } def
-/d { setdash } def
-/i { setflat } def
-/j { setlinejoin } def
-/J { setlinecap } def
-/M { setmiterlimit } def
-/w { setlinewidth } def
-% color operators
-/g { dup 1 array astore /pdfFill exch def setgray
- /pdfLastFill true def /pdfLastStroke false def } def
-/G { dup 1 array astore /pdfStroke exch def setgray
- /pdfLastStroke true def /pdfLastFill false def } def
-/rg { 3 copy 3 array astore /pdfFill exch def setrgbcolor
- /pdfLastFill true def /pdfLastStroke false def } def
-/RG { 3 copy 3 array astore /pdfStroke exch def setrgbcolor
- /pdfLastStroke true def /pdfLastFill false def } def
-/k { 4 copy 4 array astore /pdfFill exch def setcmykcolor
- /pdfLastFill true def /pdfLastStroke false def } def
-/K { 4 copy 4 array astore /pdfStroke exch def setcmykcolor
- /pdfLastStroke true def /pdfLastFill false def } def
-/ck { 6 copy 6 array astore /pdfFill exch def
- findcmykcustomcolor exch setcustomcolor
- /pdfLastFill true def /pdfLastStroke false def } def
-/CK { 6 copy 6 array astore /pdfStroke exch def
- findcmykcustomcolor exch setcustomcolor
- /pdfLastStroke true def /pdfLastFill false def } def
-% path segment operators
-/m { moveto } def
-/l { lineto } def
-/c { curveto } def
-/re { 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
- neg 0 rlineto closepath } def
-/h { closepath } def
-% path painting operators
-/S { sCol stroke } def
-/Sf { fCol stroke } def
-/f { fCol fill } def
-/f* { fCol eofill } def
-% clipping operators
-/W { clip newpath } def
-/W* { eoclip newpath } def
-% text state operators
-/Tc { /pdfCharSpacing exch def } def
-/Tf { dup /pdfFontSize exch def
- dup pdfHorizScaling mul exch matrix scale
- pdfTextMat matrix concatmatrix dup 4 0 put dup 5 0 put
- exch findfont exch makefont setfont } def
-/Tr { /pdfTextRender exch def } def
-/Ts { /pdfTextRise exch def } def
-/Tw { /pdfWordSpacing exch def } def
-/Tz { /pdfHorizScaling exch def } def
-% text positioning operators
-/Td { pdfTextMat transform moveto } def
-/Tm { /pdfTextMat exch def } def
-% text string operators
-/cshow where {
- pop
- /cshow2 {
- dup {
- pop pop
- 1 string dup 0 3 index put 3 index exec
- } exch cshow
- pop pop
- } def
-}{
- /cshow2 {
- currentfont /FontType get 0 eq {
- 0 2 2 index length 1 sub {
- 2 copy get exch 1 add 2 index exch get
- 2 copy exch 256 mul add
- 2 string dup 0 6 5 roll put dup 1 5 4 roll put
- 3 index exec
- } for
- } {
- dup {
- 1 string dup 0 3 index put 3 index exec
- } forall
- } ifelse
- pop pop
- } def
-} ifelse
-/awcp {
- exch {
- false charpath
- 5 index 5 index rmoveto
- 6 index eq { 7 index 7 index rmoveto } if
- } exch cshow2
- 6 {pop} repeat
-} def
-/Tj {
- fCol
- 1 index stringwidth pdfTextMat idtransform pop
- sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse
- pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
- 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
- pdfTextMat dtransform
- 6 5 roll Tj1
-} def
-/Tj16 {
- fCol
- 2 index stringwidth pdfTextMat idtransform pop
- sub exch div
- pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
- 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
- pdfTextMat dtransform
- 6 5 roll Tj1
-} def
-/Tj16V {
- fCol
- 2 index stringwidth pdfTextMat idtransform exch pop
- sub exch div
- 0 pdfWordSpacing pdfTextMat dtransform 32
- 4 3 roll pdfCharSpacing add 0 exch
- pdfTextMat dtransform
- 6 5 roll Tj1
-} def
-/Tj1 {
- 0 pdfTextRise pdfTextMat dtransform rmoveto
- currentpoint 8 2 roll
- pdfTextRender 1 and 0 eq {
- 6 copy awidthshow
- } if
- pdfTextRender 3 and dup 1 eq exch 2 eq or {
- 7 index 7 index moveto
- 6 copy
- currentfont /FontType get 3 eq { fCol } { sCol } ifelse
- false awcp currentpoint stroke moveto
- } if
- pdfTextRender 4 and 0 ne {
- 8 6 roll moveto
- false awcp
- /pdfTextClipPath [ pdfTextClipPath aload pop
- {/moveto cvx}
- {/lineto cvx}
- {/curveto cvx}
- {/closepath cvx}
- pathforall ] def
- currentpoint newpath moveto
- } {
- 8 {pop} repeat
- } ifelse
- 0 pdfTextRise neg pdfTextMat dtransform rmoveto
-} def
-/TJm { pdfFontSize 0.001 mul mul neg 0
- pdfTextMat dtransform rmoveto } def
-/TJmV { pdfFontSize 0.001 mul mul neg 0 exch
- pdfTextMat dtransform rmoveto } def
-/Tclip { pdfTextClipPath cvx exec clip newpath
- /pdfTextClipPath [] def } def
-% Level 2 image operators
-/pdfImBuf 100 string def
-/pdfIm {
- image
- { currentfile pdfImBuf readline
- not { pop exit } if
- (%-EOD-) eq { exit } if } loop
-} def
-/pdfImSep {
- findcmykcustomcolor exch
- dup /Width get /pdfImBuf1 exch string def
- dup /Decode get aload pop 1 index sub /pdfImDecodeRange exch def
- /pdfImDecodeLow exch def
- begin Width Height BitsPerComponent ImageMatrix DataSource end
- /pdfImData exch def
- { pdfImData pdfImBuf1 readstring pop
- 0 1 2 index length 1 sub {
- 1 index exch 2 copy get
- pdfImDecodeRange mul 255 div pdfImDecodeLow add round cvi
- 255 exch sub put
- } for }
- 6 5 roll customcolorimage
- { currentfile pdfImBuf readline
- not { pop exit } if
- (%-EOD-) eq { exit } if } loop
-} def
-/pdfImM {
- fCol imagemask
- { currentfile pdfImBuf readline
- not { pop exit } if
- (%-EOD-) eq { exit } if } loop
-} def
-end
-%%EndResource
-%%EndProlog
-%%BeginSetup
-xpdf begin
-/F121_0 /Helvetica-Bold 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
- /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
- /caron/dotlessi/dotlessj/ff/ffi/ffl/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/grave/quotesingle
- /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
- /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
- /zero/one/two/three/four/five/six/seven
- /eight/nine/colon/semicolon/less/equal/greater/question
- /at/A/B/C/D/E/F/G
- /H/I/J/K/L/M/N/O
- /P/Q/R/S/T/U/V/W
- /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
- /quoteleft/a/b/c/d/e/f/g
- /h/i/j/k/l/m/n/o
- /p/q/r/s/t/u/v/w
- /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
- /Euro/.notdef/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
- /circumflex/perthousand/Scaron/guilsinglleft/OE/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
- /tilde/trademark/scaron/guilsinglright/oe/.notdef/.notdef/Ydieresis
- /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
- /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
- /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
- /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
- /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
- /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
- /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
- /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
- /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
- /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
- /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
- /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-/F128_0 /Times-Roman 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
- /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
- /caron/dotlessi/dotlessj/ff/ffi/ffl/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/grave/quotesingle
- /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
- /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
- /zero/one/two/three/four/five/six/seven
- /eight/nine/colon/semicolon/less/equal/greater/question
- /at/A/B/C/D/E/F/G
- /H/I/J/K/L/M/N/O
- /P/Q/R/S/T/U/V/W
- /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
- /quoteleft/a/b/c/d/e/f/g
- /h/i/j/k/l/m/n/o
- /p/q/r/s/t/u/v/w
- /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
- /Euro/.notdef/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
- /circumflex/perthousand/Scaron/guilsinglleft/OE/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
- /tilde/trademark/scaron/guilsinglright/oe/.notdef/.notdef/Ydieresis
- /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
- /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
- /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
- /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
- /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
- /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
- /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
- /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
- /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
- /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
- /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
- /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-/F130_0 /Courier 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
- /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
- /caron/dotlessi/dotlessj/ff/ffi/ffl/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/grave/quotesingle
- /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
- /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
- /zero/one/two/three/four/five/six/seven
- /eight/nine/colon/semicolon/less/equal/greater/question
- /at/A/B/C/D/E/F/G
- /H/I/J/K/L/M/N/O
- /P/Q/R/S/T/U/V/W
- /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
- /quoteleft/a/b/c/d/e/f/g
- /h/i/j/k/l/m/n/o
- /p/q/r/s/t/u/v/w
- /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
- /Euro/.notdef/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
- /circumflex/perthousand/Scaron/guilsinglleft/OE/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
- /tilde/trademark/scaron/guilsinglright/oe/.notdef/.notdef/Ydieresis
- /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
- /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
- /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
- /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
- /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
- /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
- /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
- /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
- /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
- /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
- /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
- /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-%%BeginResource: font CJBHNS+CMMI10
-%!PS-AdobeFont-1.1: CMMI10 1.100
-%%CreationDate: 1996 Jul 23 07:53:57
-% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
-11 dict begin
-/FontInfo 7 dict dup begin
-/version (1.100) readonly def
-/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
-/FullName (CMMI10) readonly def
-/FamilyName (Computer Modern) readonly def
-/Weight (Medium) readonly def
-/ItalicAngle -14.04 def
-/isFixedPitch false def
-end readonly def
-/FontName /CJBHNS+CMMI10 def
-/PaintType 0 def
-/FontType 1 def
-/FontMatrix [0.001 0 0 0.001 0 0] readonly def
-/Encoding 256 array
-0 1 255 {1 index exch /.notdef put} for
-dup 45 /arrowhookright put
-dup 58 /period put
-readonly def
-/FontBBox{-32 -250 1048 750}readonly def
-/UniqueID 5087385 def
-currentdict end
-currentfile eexec
-d9d66f633b846a97b686a97e45a3d0aa0529731c99a784ccbe85b4993b2eebde
-3b12d472b7cf54651ef21185116a69ab1096ed4bad2f646635e019b6417cc77b
-532f85d811c70d1429a19a5307ef63eb5c5e02c89fc6c20f6d9d89e7d91fe470
-b72befda23f5df76be05af4ce93137a219ed8a04a9d7d6fdf37e6b7fcde0d90b
-986423e5960a5d9fbb4c956556e8df90cbfaec476fa36fd9a5c8175c9af513fe
-d919c2ddd26bdc0d99398b9f4d03d5993dfc0930297866e1cd0a319b6b1fd958
-9e394a533a081c36d456a09920001a3d2199583eb9b84b4dee08e3d12939e321
-990cd249827d9648574955f61baaa11263a91b6c3d47a5190165b0c25abf6d3e
-6ec187e4b05182126bb0d0323d943170b795255260f9fd25f2248d04f45dfbfb
-def7ff8b19bfef637b210018ae02572b389b3f76282beb29cc301905d388c721
-59616893e774413f48de0b408bc66dce3fe17cb9f84d205839d58014d6a88823
-d9320ae93af96d97a02c4d5a2bb2b8c7925c4578003959c46e3ce1a2f0eac4bf
-8b9b325e46435bde60bc54d72bc8acb5c0a34413ac87045dc7b84646a324b808
-6fd8e34217213e131c3b1510415ce45420688ed9c1d27890ec68bd7c1235faf9
-1dab3a369dd2fc3be5cf9655c7b7eda7361d7e05e5831b6b8e2eec542a7b38ee
-03be4bac6079d038acb3c7c916279764547c2d51976baba94ba9866d79f13909
-95aa39b0f03103a07cbdf441b8c5669f729020af284b7ff52a29c6255fcaacf1
-74109050fba2602e72593fbcbfc26e726ee4aef97b7632bc4f5f353b5c67fed2
-3ea752a4a57b8f7feff1d7341d895f0a3a0be1d8e3391970457a967eff84f6d8
-47750b1145b8cc5bd96ee7aa99ddc9e06939e383bda41175233d58ad263ebf19
-afc0e2f840512d321166547b306c592b8a01e1fa2564b9a26dac14256414e4c8
-42616728d918c74d13c349f4186ec7b9708b86467425a6fdb3a396562f7ee4d8
-40b43621744cf8a23a6e532649b66c2a0002dd04f8f39618e4f572819dd34837
-b5a08e643fdca1505af6a1fa3ddfd1fa758013caed8acddbbb334d664dff5b53
-95601766777978d01677b8d19e1b10a078432d2884bb42d1f224976325883657
-05acb022d1e9cb556e37af91917c78e98229e3a4dbf03ae741998542977ad6df
-1760fc1f1a479464922afda2cba7961e9da696b71205e19c542c97f25419c43c
-fa1a042ba0cf5622ffbd3e775d0d564135d99b9ffba011eebc4066b003ce2f88
-825936d7393d05d3804601cee9d123120fdf73624a9d4e361a28e998acec53f8
-7a62a0aee33be2e96542534a8af24497d1c377cd7f723767b44857d94c6cda7a
-c3d6f0087fa36655dd2b81eaecb31fe4f4a2fb1ea9fbe8b83d35826ac93fbb4f
-2bee014f41f8f276510cf5ce35c3954e8cafc521d0c3ab80ea8c7fc29427a1d4
-42d6f6c1800919e58de9ae12304d718ad80febbb412da54153469cd51a288628
-ad109baa77981525b3d9b0efe593537fcbb8520d38cccbd5db171a0385a432c1
-3030303030303030
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F143_0 /CJBHNS+CMMI10 1 1
-[ /Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma/Upsilon
- /Phi/Psi/Omega/alpha/beta/gamma/delta/epsilon1
- /zeta/eta/theta/iota/kappa/lambda/mu/nu
- /xi/pi/rho/sigma/tau/upsilon/phi/chi
- /psi/omega/epsilon/theta1/pi1/rho1/sigma1/phi1
- /arrowlefttophalf/arrowleftbothalf/arrowrighttophalf/arrowrightbothalf/arrowhookleft/arrowhookright/triangleright/triangleleft
- /zerooldstyle/oneoldstyle/twooldstyle/threeoldstyle/fouroldstyle/fiveoldstyle/sixoldstyle/sevenoldstyle
- /eightoldstyle/nineoldstyle/period/comma/less/slash/greater/star
- /partialdiff/A/B/C/D/E/F/G
- /H/I/J/K/L/M/N/O
- /P/Q/R/S/T/U/V/W
- /X/Y/Z/flat/natural/sharp/slurbelow/slurabove
- /lscript/a/b/c/d/e/f/g
- /h/i/j/k/l/m/n/o
- /p/q/r/s/t/u/v/w
- /x/y/z/dotlessi/dotlessj/weierstrass/vector/tie
- /psi/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /space/Gamma/Delta/Theta/Lambda/Xi/Pi/Sigma
- /Upsilon/Phi/Psi/.notdef/.notdef/Omega/alpha/beta
- /gamma/delta/epsilon1/zeta/eta/theta/iota/kappa
- /lambda/mu/nu/xi/pi/rho/sigma/tau
- /upsilon/phi/chi/psi/tie/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef]
-pdfMakeFont
-/F387_0 /Courier-Bold 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
- /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
- /caron/dotlessi/dotlessj/ff/ffi/ffl/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/grave/quotesingle
- /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
- /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
- /zero/one/two/three/four/five/six/seven
- /eight/nine/colon/semicolon/less/equal/greater/question
- /at/A/B/C/D/E/F/G
- /H/I/J/K/L/M/N/O
- /P/Q/R/S/T/U/V/W
- /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
- /quoteleft/a/b/c/d/e/f/g
- /h/i/j/k/l/m/n/o
- /p/q/r/s/t/u/v/w
- /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
- /Euro/.notdef/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
- /circumflex/perthousand/Scaron/guilsinglleft/OE/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
- /tilde/trademark/scaron/guilsinglright/oe/.notdef/.notdef/Ydieresis
- /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
- /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
- /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
- /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
- /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
- /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
- /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
- /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
- /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
- /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
- /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
- /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-%%BeginResource: font RBGKEI+CMSY10
-%!PS-AdobeFont-1.1: CMSY10 1.0
-%%CreationDate: 1991 Aug 15 07:20:57
-% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
-11 dict begin
-/FontInfo 7 dict dup begin
-/version (1.0) readonly def
-/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
-/FullName (CMSY10) readonly def
-/FamilyName (Computer Modern) readonly def
-/Weight (Medium) readonly def
-/ItalicAngle -14.035 def
-/isFixedPitch false def
-end readonly def
-/FontName /RBGKEI+CMSY10 def
-/PaintType 0 def
-/FontType 1 def
-/FontMatrix [0.001 0 0 0.001 0 0] readonly def
-/Encoding 256 array
-0 1 255 {1 index exch /.notdef put} for
-dup 32 /arrowleft put
-readonly def
-/FontBBox{-29 -960 1116 775}readonly def
-/UniqueID 5000820 def
-currentdict end
-currentfile eexec
-d9d66f633b846a97b686a97e45a3d0aa052f09f9c8ade9d907c058b87e9b6964
-7d53359e51216774a4eaa1e2b58ec3176bd1184a633b951372b4198d4e8c5ef4
-a213acb58aa0a658908035bf2ed8531779838a960dfe2b27ea49c37156989c85
-e21b3abf72e39a89232cd9f4237fc80c9e64e8425aa3bef7ded60b122a52922a
-221a37d9a807dd01161779dde7d31ff2b87f97c73d63eecdda4c49501773468a
-27d1663e0b62f461f6e40a5d6676d1d12b51e641c1d4e8e2771864fc104f8cbf
-5b78ec1d88228725f1c453a678f58a7e1b7bd7ca700717d288eb8da1f57c4f09
-0abf1d42c5ddd0c384c7e22f8f8047be1d4c1cc8e33368fb1ac82b4e96146730
-de3302b2e6b819cb6ae455b1af3187ffe8071aa57ef8a6616b9cb7941d44ec7a
-71a7bb3df755178d7d2e4bb69859efa4bbc30bd6bb1531133fd4d9438ff99f09
-4ecc068a324d75b5f696b8688eeb2f17e5ed34ccd6d047a4e3806d000c199d7c
-515db70a8d4f6146fe068dc1e5de8bc5703711da090312ba3fc00a08c453c609
-c627a8bd98d9e826f964721e92bbdc978e88eea0a9c14802ebcc41f810428fa8
-b9972032a01769a7c72d1a65276f414deedaf1d22be23f4705bf5ef31b6a3b69
-0c896320f09e9875b50220a5bdbbd57c041b5ea97f421685a7256b0d9755edbe
-d05190dabf1c3dbf558258163c8231d89167a816bba55fb1f14ad04320ae381d
-f783a9eacee8ae5c1838775fe2380bdd1f3afcccc96d2a2dfc999b52a6689c51
-af82b8d63205b339103134dac7e3c45e6693940276041bb07ebdb9b729e8ef0d
-ee8bf450fa42551be65217fea902e28decc09580b504f0f52f1e8fc5ce7ac28d
-c4e47f908fdaeba23827a97a0aa741aa7708f7bbfec6fa69cc4f7c3bd4303030
-3030303030
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F559_0 /RBGKEI+CMSY10 1 1
-[ /minus/periodcentered/multiply/asteriskmath/divide/diamondmath/plusminus/minusplus
- /circleplus/circleminus/circlemultiply/circledivide/circledot/circlecopyrt/openbullet/bullet
- /equivasymptotic/equivalence/reflexsubset/reflexsuperset/lessequal/greaterequal/precedesequal/followsequal
- /similar/approxequal/propersubset/propersuperset/lessmuch/greatermuch/precedes/follows
- /arrowleft/arrowright/arrowup/arrowdown/arrowboth/arrownortheast/arrowsoutheast/similarequal
- /arrowdblleft/arrowdblright/arrowdblup/arrowdbldown/arrowdblboth/arrownorthwest/arrowsouthwest/proportional
- /prime/infinity/element/owner/triangle/triangleinv/negationslash/mapsto
- /universal/existential/logicalnot/emptyset/Rfractur/Ifractur/latticetop/perpendicular
- /aleph/A/B/C/D/E/F/G
- /H/I/J/K/L/M/N/O
- /P/Q/R/S/T/U/V/W
- /X/Y/Z/union/intersection/unionmulti/logicaland/logicalor
- /turnstileleft/turnstileright/floorleft/floorright/ceilingleft/ceilingright/braceleft/braceright
- /angbracketleft/angbracketright/bar/bardbl/arrowbothv/arrowdblbothv/backslash/wreathproduct
- /radical/coproduct/nabla/integral/unionsq/intersectionsq/subsetsqequal/supersetsqequal
- /section/dagger/daggerdbl/paragraph/club/diamond/heart/spade
- /arrowleft/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/minus/periodcentered/multiply/asteriskmath/divide/diamondmath/plusminus
- /minusplus/circleplus/circleminus/.notdef/.notdef/circlemultiply/circledivide/circledot
- /circlecopyrt/openbullet/bullet/equivasymptotic/equivalence/reflexsubset/reflexsuperset/lessequal
- /greaterequal/precedesequal/followsequal/similar/approxequal/propersubset/propersuperset/lessmuch
- /greatermuch/precedes/follows/arrowleft/spade/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef]
-pdfMakeFont
-/F631_0 /Times-Italic 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
- /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
- /caron/dotlessi/dotlessj/ff/ffi/ffl/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/grave/quotesingle
- /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
- /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
- /zero/one/two/three/four/five/six/seven
- /eight/nine/colon/semicolon/less/equal/greater/question
- /at/A/B/C/D/E/F/G
- /H/I/J/K/L/M/N/O
- /P/Q/R/S/T/U/V/W
- /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
- /quoteleft/a/b/c/d/e/f/g
- /h/i/j/k/l/m/n/o
- /p/q/r/s/t/u/v/w
- /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
- /Euro/.notdef/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
- /circumflex/perthousand/Scaron/guilsinglleft/OE/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
- /tilde/trademark/scaron/guilsinglright/oe/.notdef/.notdef/Ydieresis
- /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
- /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
- /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
- /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
- /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
- /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
- /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
- /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
- /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
- /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
- /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
- /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-612 792 false pdfSetup
-%%EndSetup
-%%Page: 1 1
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 756] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 463.018 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -36] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.435 701.916 Td
-/F121_0 24.79 Tf
-(bzip2) 63.3632 Tj
--278 TJm
-(and) 44.0766 Tj
--278 TJm
-(libbzip2,) 99.1848 Tj
--278 TJm
-(ver) 37.2098 Tj
-15 TJm
-(sion) 50.9682 Tj
--278 TJm
-(1.0.3) 55.133 Tj
-[1 0 0 1 72 696.784] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -15.494] cm
-0 g
-0 G
-[1 0 0 1 -72 -681.29] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90.493 661.631 Td
-/F121_0 20.659 Tf
-(A) 14.9158 Tj
--278 TJm
-(pr) 20.659 Tj
-20 TJm
-(ogram) 63.1339 Tj
--278 TJm
-(and) 36.7317 Tj
--278 TJm
-(librar) 51.6682 Tj
--10 TJm
-(y) 11.4864 Tj
--278 TJm
-(f) 6.87945 Tj
-20 TJm
-(or) 20.659 Tj
--278 TJm
-(data) 42.4749 Tj
--277 TJm
-(compression) 128.582 Tj
-[1 0 0 1 72 657.035] cm
-0 g
-0 G
-[1 0 0 1 0 -144] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -513.035] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.676 503.285 Td
-/F121_0 11.955 Tf
-(J) 6.64698 Tj
-20 TJm
-(ulian) 27.903 Tj
--278 TJm
-(Se) 14.621 Tj
-15 TJm
-(war) 20.5985 Tj
-20 TJm
-(d,) 10.628 Tj
--278 TJm
-(http://www) 61.102 Tj
-40 TJm
-(.bzip.or) 42.512 Tj
-15 TJm
-(g) 7.30451 Tj
-[1 0 0 1 72 500.625] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -435.825] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 463.018 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 2 2
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 140.398 0] cm
-0 g
-0 G
-[1 0 0 1 -140.398 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -13.948] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 709.534 Td
-/F121_0 14.346 Tf
-(bzip2) 36.6684 Tj
--489 TJm
-(and) 25.5072 Tj
--488 TJm
-(libbzip2,) 57.3983 Tj
--542 TJm
-(ver) 21.5333 Tj
-15 TJm
-(sion) 29.4954 Tj
--489 TJm
-(1.0.3:) 36.6827 Tj
--765 TJm
-(A) 10.3578 Tj
--488 TJm
-(pr) 14.346 Tj
-20 TJm
-(ogram) 43.8414 Tj
--489 TJm
-(and) 25.5072 Tj
--489 TJm
-(librar) 35.8793 Tj
--10 TJm
-(y) 7.97638 Tj
--489 TJm
-(f) 4.77722 Tj
-20 TJm
-(or) 14.346 Tj
--488 TJm
-(data) 29.4954 Tj
-72 692.319 Td
-(compression) 89.2895 Tj
-[1 0 0 1 72 689.349] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -689.349] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 680.364 Td
-/F128_0 9.963 Tf
-(by) 9.963 Tj
--250 TJm
-(Julian) 23.8016 Tj
--250 TJm
-(Se) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(ard) 12.7228 Tj
-[1 0 0 1 72 678.207] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -678.207] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 668.409 Td
-/F128_0 9.963 Tf
-(Cop) 16.6083 Tj
-10 TJm
-(yright) 23.8016 Tj
-[1 0 0 1 114.799 668.409] cm
-0 g
-0 G
-[1 0 0 1 -114.799 -668.409] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-114.799 668.409 Td
-/F128_0 9.963 Tf
-(\251) 7.57188 Tj
-[1 0 0 1 122.371 668.409] cm
-0 g
-0 G
-[1 0 0 1 -122.371 -668.409] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.861 668.409 Td
-/F128_0 9.963 Tf
-(1996-2005) 43.1697 Tj
--250 TJm
-(Julian) 23.8016 Tj
--250 TJm
-(Se) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(ard) 12.7228 Tj
-[1 0 0 1 72 666.252] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -7.97] cm
-0 g
-0 G
-[1 0 0 1 -72 -658.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 650.874 Td
-/F128_0 7.97 Tf
-(This) 14.1707 Tj
--250 TJm
-(program,) 28.9949 Tj
-[1 0 0 1 119.151 650.874] cm
-0 g
-0 G
-[1 0 0 1 -119.151 -650.874] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.151 650.874 Td
-/F130_0 7.97 Tf
-(bzip2) 23.91 Tj
-[1 0 0 1 143.061 650.874] cm
-0 g
-0 G
-[1 0 0 1 -143.061 -650.874] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.061 650.874 Td
-/F128_0 7.97 Tf
-(,) 1.9925 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(associated) 32.7567 Tj
--250 TJm
-(library) 21.248 Tj
-[1 0 0 1 216.768 650.874] cm
-0 g
-0 G
-[1 0 0 1 -216.768 -650.874] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.768 650.874 Td
-/F130_0 7.97 Tf
-(libbzip2) 38.256 Tj
-[1 0 0 1 255.024 650.874] cm
-0 g
-0 G
-[1 0 0 1 -255.024 -650.874] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.024 650.874 Td
-/F128_0 7.97 Tf
-(,) 1.9925 Tj
--250 TJm
-(and) 11.5087 Tj
--250 TJm
-(all) 7.97 Tj
--250 TJm
-(documentation,) 49.3662 Tj
--250 TJm
-(are) 9.73137 Tj
--250 TJm
-(cop) 11.5087 Tj
-10 TJm
-(yright) 19.0403 Tj
--250 TJm
-(\251) 6.0572 Tj
--250 TJm
-(1996-2005) 34.534 Tj
--250 TJm
-(Julian) 19.0403 Tj
--250 TJm
-(Se) 7.97 Tj
-25 TJm
-(w) 5.75434 Tj
-10 TJm
-(ard.) 12.1702 Tj
--310 TJm
-(All) 10.1857 Tj
--250 TJm
-(rights) 18.1557 Tj
--250 TJm
-(reserv) 19.4707 Tj
-15 TJm
-(ed.) 9.51618 Tj
-[1 0 0 1 72 649.149] cm
-0 g
-0 G
-[1 0 0 1 0 -7.97] cm
-0 g
-0 G
-[1 0 0 1 -72 -641.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 633.34 Td
-/F128_0 7.97 Tf
-(Redistrib) 29.226 Tj
-20 TJm
-(ution) 16.3863 Tj
--250 TJm
-(and) 11.5087 Tj
--250 TJm
-(use) 10.624 Tj
--250 TJm
-(in) 6.20066 Tj
--250 TJm
-(source) 20.8017 Tj
--250 TJm
-(and) 11.5087 Tj
--250 TJm
-(binary) 20.3634 Tj
--250 TJm
-(forms,) 20.5865 Tj
--250 TJm
-(with) 14.1707 Tj
--250 TJm
-(or) 6.63901 Tj
--250 TJm
-(without) 24.3563 Tj
--250 TJm
-(modi\002cation,) 42.2888 Tj
--250 TJm
-(are) 9.73137 Tj
--250 TJm
-(permitted) 30.549 Tj
--250 TJm
-(pro) 10.624 Tj
-15 TJm
-(vided) 17.7093 Tj
--250 TJm
-(that) 11.955 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(follo) 15.0553 Tj
-25 TJm
-(wing) 15.94 Tj
--250 TJm
-(conditions) 33.211 Tj
--250 TJm
-(are) 9.73137 Tj
--250 TJm
-(met:) 14.1707 Tj
-[1 0 0 1 72 631.615] cm
-0 g
-0 G
-[1 0 0 1 0 -23.779] cm
-0 g
-0 G
-[1 0 0 1 5.579 0] cm
-0 g
-0 G
-[1 0 0 1 -77.579 -607.836] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.579 607.836 Td
-/F128_0 7.97 Tf
-(\225) 2.7895 Tj
-[1 0 0 1 80.369 607.836] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 1.594 0] cm
-0 g
-0 G
-[1 0 0 1 -83.955 -607.836] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.955 607.836 Td
-/F128_0 7.97 Tf
-(Redistrib) 29.226 Tj
-20 TJm
-(utions) 19.4867 Tj
--250 TJm
-(of) 6.63901 Tj
--250 TJm
-(source) 20.8017 Tj
--250 TJm
-(code) 15.0474 Tj
--250 TJm
-(must) 15.5017 Tj
--250 TJm
-(retain) 18.1477 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(abo) 11.5087 Tj
-15 TJm
-(v) 3.985 Tj
-15 TJm
-(e) 3.53868 Tj
--250 TJm
-(cop) 11.5087 Tj
-10 TJm
-(yright) 19.0403 Tj
--250 TJm
-(notice,) 21.4712 Tj
--250 TJm
-(this) 11.5167 Tj
--250 TJm
-(list) 9.74731 Tj
--250 TJm
-(of) 6.63901 Tj
--250 TJm
-(conditions) 33.211 Tj
--250 TJm
-(and) 11.5087 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(follo) 15.0553 Tj
-25 TJm
-(wing) 15.94 Tj
--250 TJm
-(disclaimer) 33.203 Tj
-55 TJm
-(.) 1.9925 Tj
-[1 0 0 1 470.908 607.836] cm
-0 g
-0 G
-[1 0 0 1 -398.908 -17.534] cm
-0 g
-0 G
-[1 0 0 1 5.579 0] cm
-0 g
-0 G
-[1 0 0 1 -77.579 -590.302] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.579 590.302 Td
-/F128_0 7.97 Tf
-(\225) 2.7895 Tj
-[1 0 0 1 80.369 590.302] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 1.594 0] cm
-0 g
-0 G
-[1 0 0 1 -83.955 -590.302] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.955 590.302 Td
-/F128_0 7.97 Tf
-(The) 12.3933 Tj
--270 TJm
-(origin) 19.0403 Tj
--270 TJm
-(of) 6.63901 Tj
--270 TJm
-(this) 11.5167 Tj
--270 TJm
-(softw) 17.7093 Tj
-10 TJm
-(are) 9.73137 Tj
--270 TJm
-(must) 15.5017 Tj
--270 TJm
-(not) 10.1857 Tj
--270 TJm
-(be) 7.52368 Tj
--270 TJm
-(misrepresented;) 50.466 Tj
--280 TJm
-(you) 11.955 Tj
--270 TJm
-(must) 15.5017 Tj
--270 TJm
-(not) 10.1857 Tj
--270 TJm
-(claim) 17.7093 Tj
--270 TJm
-(that) 11.955 Tj
--270 TJm
-(you) 11.955 Tj
--270 TJm
-(wrote) 18.1477 Tj
--270 TJm
-(the) 9.73934 Tj
--270 TJm
-(original) 24.7947 Tj
--270 TJm
-(softw) 17.7093 Tj
-10 TJm
-(are.) 11.7239 Tj
--739 TJm
-(If) 5.30802 Tj
--270 TJm
-(you) 11.955 Tj
--270 TJm
-(use) 10.624 Tj
--270 TJm
-(this) 11.5167 Tj
--270 TJm
-(softw) 17.7093 Tj
-10 TJm
-(are) 9.73137 Tj
--270 TJm
-(in) 6.20066 Tj
--270 TJm
-(a) 3.53868 Tj
-83.955 580.738 Td
-(product,) 26.3409 Tj
--250 TJm
-(an) 7.52368 Tj
--250 TJm
-(ackno) 19.0324 Tj
-25 TJm
-(wledgment) 35.4187 Tj
--250 TJm
-(in) 6.20066 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(product) 24.3484 Tj
--250 TJm
-(documentation) 47.3737 Tj
--250 TJm
-(w) 5.75434 Tj
-10 TJm
-(ould) 14.1707 Tj
--250 TJm
-(be) 7.52368 Tj
--250 TJm
-(appreciated) 36.7337 Tj
--250 TJm
-(b) 3.985 Tj
-20 TJm
-(ut) 6.20066 Tj
--250 TJm
-(is) 5.31599 Tj
--250 TJm
-(not) 10.1857 Tj
--250 TJm
-(required.) 28.5485 Tj
-[1 0 0 1 403.817 580.738] cm
-0 g
-0 G
-[1 0 0 1 -331.817 -17.535] cm
-0 g
-0 G
-[1 0 0 1 5.579 0] cm
-0 g
-0 G
-[1 0 0 1 -77.579 -563.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.579 563.203 Td
-/F128_0 7.97 Tf
-(\225) 2.7895 Tj
-[1 0 0 1 80.369 563.203] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 1.594 0] cm
-0 g
-0 G
-[1 0 0 1 -83.955 -563.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.955 563.203 Td
-/F128_0 7.97 Tf
-(Altered) 23.902 Tj
--250 TJm
-(source) 20.8017 Tj
--250 TJm
-(v) 3.985 Tj
-15 TJm
-(ersions) 22.579 Tj
--250 TJm
-(must) 15.5017 Tj
--250 TJm
-(be) 7.52368 Tj
--250 TJm
-(plainly) 22.1407 Tj
--250 TJm
-(mark) 16.3783 Tj
-10 TJm
-(ed) 7.52368 Tj
--250 TJm
-(as) 6.63901 Tj
--250 TJm
-(such,) 16.6015 Tj
--250 TJm
-(and) 11.5087 Tj
--250 TJm
-(must) 15.5017 Tj
--250 TJm
-(not) 10.1857 Tj
--250 TJm
-(be) 7.52368 Tj
--250 TJm
-(misrepresented) 48.2504 Tj
--250 TJm
-(as) 6.63901 Tj
--250 TJm
-(being) 17.7093 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(original) 24.7947 Tj
--250 TJm
-(softw) 17.7093 Tj
-10 TJm
-(are.) 11.7239 Tj
-[1 0 0 1 464.405 563.203] cm
-0 g
-0 G
-[1 0 0 1 -392.405 -17.534] cm
-0 g
-0 G
-[1 0 0 1 5.579 0] cm
-0 g
-0 G
-[1 0 0 1 -77.579 -545.669] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.579 545.669 Td
-/F128_0 7.97 Tf
-(\225) 2.7895 Tj
-[1 0 0 1 80.369 545.669] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 1.594 0] cm
-0 g
-0 G
-[1 0 0 1 -83.955 -545.669] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.955 545.669 Td
-/F128_0 7.97 Tf
-(The) 12.3933 Tj
--250 TJm
-(name) 17.263 Tj
--250 TJm
-(of) 6.63901 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(author) 20.3634 Tj
--250 TJm
-(may) 13.7243 Tj
--250 TJm
-(not) 10.1857 Tj
--250 TJm
-(be) 7.52368 Tj
--250 TJm
-(used) 14.609 Tj
--250 TJm
-(to) 6.20066 Tj
--250 TJm
-(endorse) 24.7867 Tj
--250 TJm
-(or) 6.63901 Tj
--250 TJm
-(promote) 26.564 Tj
--250 TJm
-(products) 27.4487 Tj
--250 TJm
-(deri) 12.3933 Tj
-25 TJm
-(v) 3.985 Tj
-15 TJm
-(ed) 7.52368 Tj
--250 TJm
-(from) 15.4937 Tj
--250 TJm
-(this) 11.5167 Tj
--250 TJm
-(softw) 17.7093 Tj
-10 TJm
-(are) 9.73137 Tj
--250 TJm
-(without) 24.3563 Tj
--250 TJm
-(speci\002c) 24.3483 Tj
--250 TJm
-(prior) 15.4937 Tj
--250 TJm
-(written) 22.579 Tj
--250 TJm
-(permission.) 36.9728 Tj
-[1 0 0 1 533.577 545.669] cm
-0 g
-0 G
-[1 0 0 1 -461.577 -9.696] cm
-0 g
-0 G
-[1 0 0 1 -72 -535.973] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 528.135 Td
-/F128_0 7.97 Tf
-(THIS) 17.7093 Tj
--259 TJm
-(SOFTW) 27.0103 Tj
-120 TJm
-(ARE) 15.94 Tj
--259 TJm
-(IS) 7.08533 Tj
--258 TJm
-(PR) 9.74731 Tj
-40 TJm
-(O) 5.75434 Tj
-50 TJm
-(VIDED) 24.7867 Tj
--259 TJm
-(BY) 11.0703 Tj
--259 TJm
-(THE) 15.4937 Tj
--259 TJm
-(A) 5.75434 Tj
-55 TJm
-(UTHOR) 27.4487 Tj
--258 TJm
-("AS) 13.4374 Tj
--259 TJm
-(IS") 10.3371 Tj
--259 TJm
-(AND) 17.263 Tj
--259 TJm
-(ANY) 17.263 Tj
--258 TJm
-(EXPRESS) 34.1036 Tj
--259 TJm
-(OR) 11.0703 Tj
--259 TJm
-(IMPLIED) 32.3184 Tj
--259 TJm
-(W) 7.52368 Tj
-120 TJm
-(ARRANTIES,) 46.7122 Tj
--259 TJm
-(INCLUDING,) 46.2579 Tj
--258 TJm
-(B) 5.31599 Tj
-10 TJm
-(UT) 10.624 Tj
--259 TJm
-(NO) 11.5087 Tj
-40 TJm
-(T) 4.86967 Tj
-72 518.571 Td
-(LIMITED) 32.7567 Tj
--303 TJm
-(T) 4.86967 Tj
-18 TJm
-(O,) 7.74684 Tj
--303 TJm
-(THE) 15.4937 Tj
--304 TJm
-(IMPLIED) 32.3184 Tj
--303 TJm
-(W) 7.52368 Tj
-120 TJm
-(ARRANTIES) 44.7197 Tj
--303 TJm
-(OF) 10.1857 Tj
--303 TJm
-(MERCHANT) 44.7197 Tj
-93 TJm
-(ABILITY) 31.872 Tj
--304 TJm
-(AND) 17.263 Tj
--303 TJm
-(FITNESS) 31.4417 Tj
--303 TJm
-(FOR) 15.5017 Tj
--303 TJm
-(A) 5.75434 Tj
--303 TJm
-(P) 4.43132 Tj
-92 TJm
-(AR) 11.0703 Tj
-60 TJm
-(TICULAR) 34.534 Tj
--304 TJm
-(PURPOSE) 34.9883 Tj
--303 TJm
-(ARE) 15.94 Tj
--303 TJm
-(DISCLAI-) 34.0877 Tj
-72 509.007 Td
-(MED.) 19.7018 Tj
--653 TJm
-(IN) 8.40835 Tj
--326 TJm
-(NO) 11.5087 Tj
--327 TJm
-(EVENT) 26.1177 Tj
--326 TJm
-(SHALL) 25.6793 Tj
--326 TJm
-(THE) 15.4937 Tj
--327 TJm
-(A) 5.75434 Tj
-55 TJm
-(UTHOR) 27.4487 Tj
--326 TJm
-(BE) 10.1857 Tj
--327 TJm
-(LIABLE) 28.3333 Tj
--326 TJm
-(FOR) 15.5017 Tj
--326 TJm
-(ANY) 17.263 Tj
--327 TJm
-(DIRECT) 28.7797 Tj
-74 TJm
-(,) 1.9925 Tj
--326 TJm
-(INDIRECT) 37.188 Tj
-74 TJm
-(,) 1.9925 Tj
--327 TJm
-(INCIDENT) 37.6264 Tj
-93 TJm
-(AL,) 12.6165 Tj
--326 TJm
-(SPECIAL,) 34.3188 Tj
--327 TJm
-(EXEMPLAR) 42.9503 Tj
-65 TJm
-(Y) 5.75434 Tj
-129 TJm
-(,) 1.9925 Tj
--326 TJm
-(OR) 11.0703 Tj
-72 499.442 Td
-(CONSEQ) 31.88 Tj
-10 TJm
-(UENTIAL) 34.526 Tj
--218 TJm
-(D) 5.75434 Tj
-40 TJm
-(AMA) 18.594 Tj
-40 TJm
-(GES) 15.0553 Tj
--218 TJm
-(\(INCLUDING,) 48.9119 Tj
--218 TJm
-(B) 5.31599 Tj
-10 TJm
-(UT) 10.624 Tj
--218 TJm
-(NO) 11.5087 Tj
-40 TJm
-(T) 4.86967 Tj
--218 TJm
-(LIMITED) 32.7567 Tj
--219 TJm
-(T) 4.86967 Tj
-18 TJm
-(O,) 7.74684 Tj
--218 TJm
-(PR) 9.74731 Tj
-40 TJm
-(OCUREMENT) 49.5893 Tj
--218 TJm
-(OF) 10.1857 Tj
--218 TJm
-(SUBSTITUTE) 47.82 Tj
--218 TJm
-(GOODS) 27.4487 Tj
--218 TJm
-(OR) 11.0703 Tj
--218 TJm
-(SER) 14.617 Tj
-80 TJm
-(VICES;) 25.241 Tj
--218 TJm
-(LOSS) 19.4867 Tj
-72 489.878 Td
-(OF) 10.1857 Tj
--207 TJm
-(USE,) 17.0478 Tj
--207 TJm
-(D) 5.75434 Tj
-40 TJm
-(A) 5.75434 Tj
-111 TJm
-(T) 4.86967 Tj
-93 TJm
-(A,) 7.74684 Tj
--208 TJm
-(OR) 11.0703 Tj
--207 TJm
-(PR) 9.74731 Tj
-40 TJm
-(OFITS;) 24.3563 Tj
--207 TJm
-(OR) 11.0703 Tj
--207 TJm
-(B) 5.31599 Tj
-10 TJm
-(USINESS) 32.3263 Tj
--207 TJm
-(INTERR) 28.7797 Tj
-40 TJm
-(UPTION\)) 31.872 Tj
--208 TJm
-(HO) 11.5087 Tj
-35 TJm
-(WEVER) 28.3333 Tj
--207 TJm
-(CA) 11.0703 Tj
-55 TJm
-(USED) 20.8097 Tj
--207 TJm
-(AND) 17.263 Tj
--207 TJm
-(ON) 11.5087 Tj
--207 TJm
-(ANY) 17.263 Tj
--207 TJm
-(THEOR) 26.564 Tj
-65 TJm
-(Y) 5.75434 Tj
--208 TJm
-(OF) 10.1857 Tj
--207 TJm
-(LIABILITY) 39.3957 Tj
-129 TJm
-(,) 1.9925 Tj
--207 TJm
-(WHETHER) 38.9574 Tj
-72 480.314 Td
-(IN) 8.40835 Tj
--205 TJm
-(CONTRA) 32.7647 Tj
-40 TJm
-(CT) 10.1857 Tj
-74 TJm
-(,) 1.9925 Tj
--205 TJm
-(STRICT) 27.4567 Tj
--204 TJm
-(LIABILITY) 39.3957 Tj
-129 TJm
-(,) 1.9925 Tj
--205 TJm
-(OR) 11.0703 Tj
--205 TJm
-(T) 4.86967 Tj
-18 TJm
-(OR) 11.0703 Tj
-60 TJm
-(T) 4.86967 Tj
--205 TJm
-(\(INCLUDING) 46.9194 Tj
--204 TJm
-(NEGLIGENCE) 50.466 Tj
--205 TJm
-(OR) 11.0703 Tj
--205 TJm
-(O) 5.75434 Tj
-40 TJm
-(THER) 20.8097 Tj
-55 TJm
-(WISE\)) 22.1327 Tj
--205 TJm
-(ARISING) 32.3184 Tj
--205 TJm
-(IN) 8.40835 Tj
--204 TJm
-(ANY) 17.263 Tj
--205 TJm
-(W) 7.52368 Tj
-120 TJm
-(A) 5.75434 Tj
-105 TJm
-(Y) 5.75434 Tj
--205 TJm
-(OUT) 16.3783 Tj
--205 TJm
-(OF) 10.1857 Tj
--204 TJm
-(THE) 15.4937 Tj
--205 TJm
-(USE) 15.0553 Tj
-72 470.75 Td
-(OF) 10.1857 Tj
--250 TJm
-(THIS) 17.7093 Tj
--250 TJm
-(SOFTW) 27.0103 Tj
-120 TJm
-(ARE,) 17.9325 Tj
--250 TJm
-(EVEN) 21.248 Tj
--250 TJm
-(IF) 7.08533 Tj
--250 TJm
-(AD) 11.5087 Tj
-40 TJm
-(VISED) 23.4637 Tj
--250 TJm
-(OF) 10.1857 Tj
--250 TJm
-(THE) 15.4937 Tj
--250 TJm
-(POSSIBILITY) 47.82 Tj
--250 TJm
-(OF) 10.1857 Tj
--250 TJm
-(SUCH) 21.256 Tj
--250 TJm
-(D) 5.75434 Tj
-40 TJm
-(AMA) 18.594 Tj
-40 TJm
-(GE.) 12.6165 Tj
-[1 0 0 1 72 469.598] cm
-0 g
-0 G
-[1 0 0 1 0 -7.97] cm
-0 g
-0 G
-[1 0 0 1 -72 -461.628] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 453.216 Td
-/F128_0 7.97 Tf
-(P) 4.43132 Tj
-92 TJm
-(A) 5.75434 Tj
-111 TJm
-(TENTS:) 27.0103 Tj
--296 TJm
-(T) 4.86967 Tj
-80 TJm
-(o) 3.985 Tj
--295 TJm
-(the) 9.73934 Tj
--296 TJm
-(best) 12.8397 Tj
--295 TJm
-(of) 6.63901 Tj
--296 TJm
-(my) 10.1857 Tj
--295 TJm
-(kno) 11.955 Tj
-25 TJm
-(wledge,) 25.0099 Tj
-[1 0 0 1 208.544 453.216] cm
-0 g
-0 G
-[1 0 0 1 -208.544 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.544 453.216 Td
-/F130_0 7.97 Tf
-(bzip2) 23.91 Tj
-[1 0 0 1 232.454 453.216] cm
-0 g
-0 G
-[1 0 0 1 -232.454 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.81 453.216 Td
-/F128_0 7.97 Tf
-(and) 11.5087 Tj
-[1 0 0 1 248.674 453.216] cm
-0 g
-0 G
-[1 0 0 1 -248.674 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.674 453.216 Td
-/F130_0 7.97 Tf
-(libbzip2) 38.256 Tj
-[1 0 0 1 286.931 453.216] cm
-0 g
-0 G
-[1 0 0 1 -286.931 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.286 453.216 Td
-/F128_0 7.97 Tf
-(do) 7.97 Tj
--296 TJm
-(not) 10.1857 Tj
--295 TJm
-(use) 10.624 Tj
--296 TJm
-(an) 7.52368 Tj
-15 TJm
-(y) 3.985 Tj
--295 TJm
-(patented) 27.0024 Tj
--296 TJm
-(algorithms.) 36.0882 Tj
--893 TJm
-(Ho) 9.73934 Tj
-25 TJm
-(we) 9.29302 Tj
-25 TJm
-(v) 3.985 Tj
-15 TJm
-(er) 6.19269 Tj
-40 TJm
-(,) 1.9925 Tj
--307 TJm
-(I) 2.65401 Tj
--295 TJm
-(do) 7.97 Tj
--296 TJm
-(not) 10.1857 Tj
--296 TJm
-(ha) 7.52368 Tj
-20 TJm
-(v) 3.985 Tj
-15 TJm
-(e) 3.53868 Tj
--295 TJm
-(the) 9.73934 Tj
--296 TJm
-(resources) 30.0947 Tj
--295 TJm
-(to) 6.20066 Tj
-72 443.652 Td
-(carry) 16.3704 Tj
--250 TJm
-(out) 10.1857 Tj
--250 TJm
-(a) 3.53868 Tj
--250 TJm
-(patent) 19.4787 Tj
--250 TJm
-(search.) 22.3479 Tj
--620 TJm
-(Therefore) 31.4177 Tj
--250 TJm
-(I) 2.65401 Tj
--250 TJm
-(cannot) 21.248 Tj
--250 TJm
-(gi) 6.20066 Tj
-25 TJm
-(v) 3.985 Tj
-15 TJm
-(e) 3.53868 Tj
--250 TJm
-(an) 7.52368 Tj
-15 TJm
-(y) 3.985 Tj
--250 TJm
-(guarantee) 30.9794 Tj
--250 TJm
-(of) 6.63901 Tj
--250 TJm
-(the) 9.73934 Tj
--250 TJm
-(abo) 11.5087 Tj
-15 TJm
-(v) 3.985 Tj
-15 TJm
-(e) 3.53868 Tj
--250 TJm
-(statement.) 32.5415 Tj
-[1 0 0 1 72 441.926] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -391.074] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 46.799 0] cm
-0 g
-0 G
-[1 0 0 1 -46.799 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 3 3
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 140.398 0] cm
-0 g
-0 G
-[1 0 0 1 -140.398 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -13.948] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 707.441 Td
-/F121_0 17.215 Tf
-(T) 10.5184 Tj
-80 TJm
-(ab) 20.0899 Tj
-10 TJm
-(le) 14.3573 Tj
--278 TJm
-(of) 16.251 Tj
--278 TJm
-(Contents) 74.5926 Tj
-[1 0 0 1 72 698.619] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.741] cm
-0 g
-0 G
-[1 0 0 1 -72 -686.878] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 686.878 Td
-/F128_0 9.963 Tf
-(1.) 7.47225 Tj
--310 TJm
-(Introduction) 49.2571 Tj
-[1 0 0 1 131.815 686.878] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -136.797 -686.878] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.733 686.878 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 686.878] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -686.878] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 686.878 Td
-/F128_0 9.963 Tf
-(1) 4.9815 Tj
-[1 0 0 1 516.09 686.878] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -72 -674.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 674.923 Td
-/F128_0 9.963 Tf
-(2.) 7.47225 Tj
--310 TJm
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 152.318 674.923] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -157.3 -674.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.054 674.923 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 674.923] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -674.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 674.923 Td
-/F128_0 9.963 Tf
-(2) 4.9815 Tj
-[1 0 0 1 516.09 674.923] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -662.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 662.968 Td
-/F128_0 9.963 Tf
-(2.1.) 14.9445 Tj
--310 TJm
-(N) 7.19329 Tj
-35 TJm
-(AME) 22.1378 Tj
-[1 0 0 1 142.924 662.968] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -147.905 -662.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-157.929 662.968 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 662.968] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -662.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 662.968 Td
-/F128_0 9.963 Tf
-(2) 4.9815 Tj
-[1 0 0 1 516.09 662.968] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -651.013] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 651.013 Td
-/F128_0 9.963 Tf
-(2.2.) 14.9445 Tj
--310 TJm
-(SYNOPSIS) 47.0552 Tj
-[1 0 0 1 160.996 651.013] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -165.977 -651.013] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-175.821 651.013 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 651.013] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -651.013] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 651.013 Td
-/F128_0 9.963 Tf
-(2) 4.9815 Tj
-[1 0 0 1 516.09 651.013] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.855] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -639.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 639.058 Td
-/F128_0 9.963 Tf
-(2.3.) 14.9445 Tj
--310 TJm
-(DESCRIPTION) 64.7595 Tj
-[1 0 0 1 178.699 639.058] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -183.681 -639.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.528 639.058 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 639.058] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -639.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 639.058 Td
-/F128_0 9.963 Tf
-(3) 4.9815 Tj
-[1 0 0 1 516.09 639.058] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.855] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -627.103] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 627.103 Td
-/F128_0 9.963 Tf
-(2.4.) 14.9445 Tj
--310 TJm
-(OPTIONS) 42.0638 Tj
-[1 0 0 1 156.005 627.103] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -160.986 -627.103] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.111 627.103 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 627.103] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -627.103] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 627.103 Td
-/F128_0 9.963 Tf
-(4) 4.9815 Tj
-[1 0 0 1 516.09 627.103] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -615.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 615.147 Td
-/F128_0 9.963 Tf
-(2.5.) 14.9445 Tj
--310 TJm
-(MEMOR) 37.6402 Tj
-65 TJm
-(Y) 7.19329 Tj
--250 TJm
-(MAN) 23.2437 Tj
-35 TJm
-(A) 7.19329 Tj
-40 TJm
-(GEMENT) 41.5059 Tj
-[1 0 0 1 231.81 615.147] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -236.791 -615.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.65 615.147 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 615.147] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -615.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 615.147 Td
-/F128_0 9.963 Tf
-(5) 4.9815 Tj
-[1 0 0 1 516.09 615.147] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -603.192] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 603.192 Td
-/F128_0 9.963 Tf
-(2.6.) 14.9445 Tj
--310 TJm
-(RECO) 26.5713 Tj
-50 TJm
-(VERING) 37.6303 Tj
--250 TJm
-(D) 7.19329 Tj
-40 TJm
-(A) 7.19329 Tj
-111 TJm
-(T) 6.08739 Tj
-93 TJm
-(A) 7.19329 Tj
--250 TJm
-(FR) 12.1847 Tj
-40 TJm
-(OM) 16.0504 Tj
--249 TJm
-(D) 7.19329 Tj
-40 TJm
-(AMA) 23.2437 Tj
-40 TJm
-(GED) 20.474 Tj
--250 TJm
-(FILES) 26.5713 Tj
-[1 0 0 1 317.359 603.192] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -322.34 -603.192] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-331.489 603.192 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 603.192] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -603.192] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 603.192 Td
-/F128_0 9.963 Tf
-(6) 4.9815 Tj
-[1 0 0 1 516.09 603.192] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -591.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 591.237 Td
-/F128_0 9.963 Tf
-(2.7.) 14.9445 Tj
--310 TJm
-(PERFORMANCE) 73.6266 Tj
--250 TJm
-(NO) 14.3866 Tj
-40 TJm
-(TES) 17.7142 Tj
-[1 0 0 1 221.758 591.237] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -226.739 -591.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.196 591.237 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 591.237] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -591.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 591.237 Td
-/F128_0 9.963 Tf
-(6) 4.9815 Tj
-[1 0 0 1 516.09 591.237] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -579.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 579.282 Td
-/F128_0 9.963 Tf
-(2.8.) 14.9445 Tj
--310 TJm
-(CA) 13.8386 Tj
-135 TJm
-(VEA) 20.474 Tj
-111 TJm
-(TS) 11.6268 Tj
-[1 0 0 1 157.429 579.282] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -162.411 -579.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.824 579.282 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 579.282] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -579.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 579.282 Td
-/F128_0 9.963 Tf
-(7) 4.9815 Tj
-[1 0 0 1 516.09 579.282] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.855] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -567.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 567.327 Td
-/F128_0 9.963 Tf
-(2.9.) 14.9445 Tj
--310 TJm
-(A) 7.19329 Tj
-55 TJm
-(UTHOR) 34.3126 Tj
-[1 0 0 1 154.899 567.327] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -159.88 -567.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-168.345 567.327 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 567.327] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -567.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 567.327 Td
-/F128_0 9.963 Tf
-(7) 4.9815 Tj
-[1 0 0 1 516.09 567.327] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.219] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.736] cm
-0 g
-0 G
-[1 0 0 1 -72 -555.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 555.372 Td
-/F128_0 9.963 Tf
-(3.) 7.47225 Tj
--310 TJm
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip) 27.6772 Tj
-1 TJm
-(2) 4.9815 Tj
-[1 0 0 1 195.197 555.372] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -200.178 -555.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.633 555.372 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 555.372] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -555.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 555.372 Td
-/F128_0 9.963 Tf
-(8) 4.9815 Tj
-[1 0 0 1 516.09 555.372] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -543.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 543.416 Td
-/F128_0 9.963 Tf
-(3.1.) 14.9445 Tj
--310 TJm
-(T) 6.08739 Tj
-80 TJm
-(op-le) 20.474 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(structure) 34.8605 Tj
-[1 0 0 1 188.831 543.416] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -193.812 -543.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.022 543.416 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 543.416] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -543.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 543.416 Td
-/F128_0 9.963 Tf
-(8) 4.9815 Tj
-[1 0 0 1 516.09 543.416] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -531.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 531.461 Td
-/F128_0 9.963 Tf
-(3.1.1.) 22.4168 Tj
--310 TJm
-(Lo) 11.0689 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(summary) 37.0823 Tj
-[1 0 0 1 225.195 531.461] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -230.176 -531.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.915 531.461 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 531.461] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -531.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 531.461 Td
-/F128_0 9.963 Tf
-(9) 4.9815 Tj
-[1 0 0 1 516.09 531.461] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -519.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 519.506 Td
-/F128_0 9.963 Tf
-(3.1.2.) 22.4168 Tj
--310 TJm
-(High-le) 30.437 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(summary) 37.0823 Tj
-[1 0 0 1 227.107 519.506] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -232.089 -519.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-242.085 519.506 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 519.506] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -519.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 519.506 Td
-/F128_0 9.963 Tf
-(9) 4.9815 Tj
-[1 0 0 1 516.09 519.506] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -507.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 507.551 Td
-/F128_0 9.963 Tf
-(3.1.3.) 22.4168 Tj
--310 TJm
-(Utility) 26.0234 Tj
--250 TJm
-(functions) 37.0823 Tj
--250 TJm
-(sum) 16.6083 Tj
-1 TJm
-(mary) 20.474 Tj
-[1 0 0 1 250.489 507.551] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -255.471 -507.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.846 507.551 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 507.551] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -507.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 507.551 Td
-/F128_0 9.963 Tf
-(9) 4.9815 Tj
-[1 0 0 1 516.09 507.551] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -495.596] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 495.596 Td
-/F128_0 9.963 Tf
-(3.2.) 14.9445 Tj
--310 TJm
-(Error) 21.0219 Tj
--250 TJm
-(handling) 34.8705 Tj
-[1 0 0 1 172.323 495.596] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -177.305 -495.596] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-185.636 495.596 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 495.596] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -495.596] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 495.596 Td
-/F128_0 9.963 Tf
-(10) 9.963 Tj
-[1 0 0 1 516.09 495.596] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -483.641] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 483.641 Td
-/F128_0 9.963 Tf
-(3.3.) 14.9445 Tj
--310 TJm
-(Lo) 11.0689 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
-[1 0 0 1 191.481 483.641] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -196.462 -483.641] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-206.284 483.641 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 483.641] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -483.641] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 483.641 Td
-/F128_0 9.963 Tf
-(11) 9.963 Tj
-[1 0 0 1 516.09 483.641] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -471.685] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 471.685 Td
-/F128_0 9.963 Tf
-(3.3.1.) 22.4168 Tj
--310 TJm
-(BZ2_bzCompressInit) 85.7914 Tj
-[1 0 0 1 231.112 471.685] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -236.094 -471.685] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.025 471.685 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 471.685] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -471.685] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 471.685 Td
-/F128_0 9.963 Tf
-(11) 9.963 Tj
-[1 0 0 1 516.09 471.685] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -459.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 459.73 Td
-/F128_0 9.963 Tf
-(3.3.2.) 22.4168 Tj
--310 TJm
-(BZ2_bzCompress) 71.9528 Tj
-[1 0 0 1 217.275 459.73] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -222.256 -459.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.464 459.73 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 459.73] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -459.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 459.73 Td
-/F128_0 9.963 Tf
-(13) 9.963 Tj
-[1 0 0 1 516.09 459.73] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -447.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 447.775 Td
-/F128_0 9.963 Tf
-(3.3.3.) 22.4168 Tj
--310 TJm
-(BZ2_bzCompressEnd) 88.0032 Tj
-[1 0 0 1 233.324 447.775] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -238.306 -447.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-247.131 447.775 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 447.775] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -447.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 447.775 Td
-/F128_0 9.963 Tf
-(16) 9.963 Tj
-[1 0 0 1 516.09 447.775] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -435.82] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 435.82 Td
-/F128_0 9.963 Tf
-(3.3.4.) 22.4168 Tj
--310 TJm
-(BZ2_bzDecompressIni) 92.4168 Tj
-1 TJm
-(t) 2.76971 Tj
-[1 0 0 1 240.507 435.82] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -245.488 -435.82] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.15 435.82 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 435.82] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -435.82] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 435.82 Td
-/F128_0 9.963 Tf
-(16) 9.963 Tj
-[1 0 0 1 516.09 435.82] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -423.865] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 423.865 Td
-/F128_0 9.963 Tf
-(3.3.5.) 22.4168 Tj
--310 TJm
-(BZ2_bzDecompress) 81.3479 Tj
-[1 0 0 1 226.669 423.865] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -231.651 -423.865] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-241.589 423.865 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 423.865] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -423.865] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 423.865 Td
-/F128_0 9.963 Tf
-(17) 9.963 Tj
-[1 0 0 1 516.09 423.865] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -411.91] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 411.91 Td
-/F128_0 9.963 Tf
-(3.3.6.) 22.4168 Tj
--310 TJm
-(BZ2_bzDecompressEn) 92.4168 Tj
-1 TJm
-(d) 4.9815 Tj
-[1 0 0 1 242.719 411.91] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -247.7 -411.91] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.256 411.91 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 411.91] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -411.91] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 411.91 Td
-/F128_0 9.963 Tf
-(18) 9.963 Tj
-[1 0 0 1 516.09 411.91] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -399.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 399.954 Td
-/F128_0 9.963 Tf
-(3.4.) 14.9445 Tj
--310 TJm
-(High-le) 30.437 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
-[1 0 0 1 193.394 399.954] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -198.375 -399.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.24 399.954 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 399.954] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -399.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 399.954 Td
-/F128_0 9.963 Tf
-(18) 9.963 Tj
-[1 0 0 1 516.09 399.954] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -387.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 387.999 Td
-/F128_0 9.963 Tf
-(3.4.1.) 22.4168 Tj
--310 TJm
-(BZ2_bzReadOpen) 74.1546 Tj
-[1 0 0 1 219.477 387.999] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -224.458 -387.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-233.565 387.999 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 387.999] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -387.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 387.999 Td
-/F128_0 9.963 Tf
-(19) 9.963 Tj
-[1 0 0 1 516.09 387.999] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -376.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 376.044 Td
-/F128_0 9.963 Tf
-(3.4.2.) 22.4168 Tj
--310 TJm
-(BZ2_bzRead) 52.5748 Tj
-[1 0 0 1 197.898 376.044] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -202.879 -376.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.706 376.044 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 376.044] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -376.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 376.044 Td
-/F128_0 9.963 Tf
-(20) 9.963 Tj
-[1 0 0 1 516.09 376.044] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.18] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.775] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -364.089] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 364.089 Td
-/F128_0 9.963 Tf
-(3.4.3.) 22.4168 Tj
--310 TJm
-(BZ2_bzReadGetUnuse) 92.4168 Tj
-1 TJm
-(d) 4.9815 Tj
-[1 0 0 1 242.719 364.089] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -247.7 -364.089] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.256 364.089 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 364.089] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -364.089] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 364.089 Td
-/F128_0 9.963 Tf
-(21) 9.963 Tj
-[1 0 0 1 516.09 364.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.181] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.774] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -352.134] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 352.134 Td
-/F128_0 9.963 Tf
-(3.4.4.) 22.4168 Tj
--310 TJm
-(BZ2_bzReadClose) 75.2705 Tj
-[1 0 0 1 220.592 352.134] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -225.573 -352.134] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.123 352.134 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 352.134] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -352.134] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 352.134 Td
-/F128_0 9.963 Tf
-(22) 9.963 Tj
-[1 0 0 1 516.09 352.134] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.181] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.774] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -340.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 340.179 Td
-/F128_0 9.963 Tf
-(3.4.5.) 22.4168 Tj
--310 TJm
-(BZ2_bzWriteOpen) 76.3664 Tj
-[1 0 0 1 221.688 340.179] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -226.669 -340.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.885 340.179 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 340.179] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -340.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 340.179 Td
-/F128_0 9.963 Tf
-(22) 9.963 Tj
-[1 0 0 1 516.09 340.179] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -328.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 328.223 Td
-/F128_0 9.963 Tf
-(3.4.6.) 22.4168 Tj
--310 TJm
-(BZ2_bzWrite) 54.7865 Tj
-[1 0 0 1 200.109 328.223] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -205.09 -328.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-215.026 328.223 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 328.223] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -328.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 328.223 Td
-/F128_0 9.963 Tf
-(23) 9.963 Tj
-[1 0 0 1 516.09 328.223] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.18] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.775] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -316.268] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 316.268 Td
-/F128_0 9.963 Tf
-(3.4.7.) 22.4168 Tj
--310 TJm
-(BZ2_bzWriteClose) 77.4823 Tj
-[1 0 0 1 222.804 316.268] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -227.785 -316.268] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.443 316.268 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 316.268] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -316.268] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 316.268 Td
-/F128_0 9.963 Tf
-(23) 9.963 Tj
-[1 0 0 1 516.09 316.268] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.18] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.775] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -304.313] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 304.313 Td
-/F128_0 9.963 Tf
-(3.4.8.) 22.4168 Tj
--310 TJm
-(Handling) 37.0823 Tj
--250 TJm
-(embedded) 40.9479 Tj
--250 TJm
-(com) 17.1563 Tj
-1 TJm
-(pressed) 29.879 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(streams) 30.437 Tj
-[1 0 0 1 327.38 304.313] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -332.362 -304.313] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-342.865 304.313 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 304.313] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -304.313] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 304.313 Td
-/F128_0 9.963 Tf
-(24) 9.963 Tj
-[1 0 0 1 516.09 304.313] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -292.358] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 292.358 Td
-/F128_0 9.963 Tf
-(3.4.9.) 22.4168 Tj
--310 TJm
-(Standard) 35.4185 Tj
--250 TJm
-(\002le-reading/) 48.6991 Tj
-1 TJm
-(writing) 28.7831 Tj
--250 TJm
-(code) 18.8101 Tj
-[1 0 0 1 282.011 292.358] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -286.992 -292.358] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-295.827 292.358 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 292.358] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -292.358] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 292.358 Td
-/F128_0 9.963 Tf
-(25) 9.963 Tj
-[1 0 0 1 516.09 292.358] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -280.403] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 280.403 Td
-/F128_0 9.963 Tf
-(3.5.) 14.9445 Tj
--310 TJm
-(Utility) 26.0234 Tj
--250 TJm
-(functions) 37.0823 Tj
-[1 0 0 1 179.536 280.403] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -184.517 -280.403] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.67 280.403 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 280.403] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -280.403] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 280.403 Td
-/F128_0 9.963 Tf
-(26) 9.963 Tj
-[1 0 0 1 516.09 280.403] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -268.448] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 268.448 Td
-/F128_0 9.963 Tf
-(3.5.1.) 22.4168 Tj
--310 TJm
-(BZ2_bzBuf) 47.0453 Tj
-25 TJm
-(fT) 9.40507 Tj
-80 TJm
-(oBuf) 19.926 Tj
-25 TJm
-(fCom) 22.6957 Tj
-1 TJm
-(press) 20.474 Tj
-[1 0 0 1 263.571 268.448] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -268.552 -268.448] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.751 268.448 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 268.448] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -268.448] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 268.448 Td
-/F128_0 9.963 Tf
-(26) 9.963 Tj
-[1 0 0 1 516.09 268.448] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -256.492] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 256.492 Td
-/F128_0 9.963 Tf
-(3.5.2.) 22.4168 Tj
--310 TJm
-(BZ2_bzBuf) 47.0453 Tj
-25 TJm
-(fT) 9.40507 Tj
-80 TJm
-(oBuf) 19.926 Tj
-25 TJm
-(fDeco) 24.3396 Tj
-1 TJm
-(mpress) 28.2252 Tj
-[1 0 0 1 272.965 256.492] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -277.947 -256.492] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-286.876 256.492 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 256.492] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -256.492] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 256.492 Td
-/F128_0 9.963 Tf
-(27) 9.963 Tj
-[1 0 0 1 516.09 256.492] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 244.537 Td
-/F128_0 9.963 Tf
-(3.6.) 14.9445 Tj
--310 TJm
-(zlib) 14.9445 Tj
--250 TJm
-(compatibility) 53.1426 Tj
--250 TJm
-(functio) 28.2252 Tj
-1 TJm
-(ns) 8.85711 Tj
-[1 0 0 1 224.088 244.537] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -229.069 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.085 244.537 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 244.537] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 244.537 Td
-/F128_0 9.963 Tf
-(28) 9.963 Tj
-[1 0 0 1 516.09 244.537] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 232.582 Td
-/F128_0 9.963 Tf
-(3.7.) 14.9445 Tj
--310 TJm
-(Using) 23.8016 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(library) 26.5614 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(stdio) 19.378 Tj
-1 TJm
-(-free) 18.8002 Tj
--250 TJm
-(en) 9.40507 Tj
-40 TJm
-(vironment) 40.9579 Tj
-[1 0 0 1 291.734 232.582] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -296.715 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.116 232.582 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 232.582] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 232.582 Td
-/F128_0 9.963 Tf
-(28) 9.963 Tj
-[1 0 0 1 516.09 232.582] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -220.627] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 220.627 Td
-/F128_0 9.963 Tf
-(3.7.1.) 22.4168 Tj
--310 TJm
-(Getting) 29.889 Tj
--250 TJm
-(rid) 11.0689 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(stdio) 19.378 Tj
-[1 0 0 1 221.429 220.627] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -226.41 -220.627] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.755 220.627 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 220.627] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -220.627] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 220.627 Td
-/F128_0 9.963 Tf
-(29) 9.963 Tj
-[1 0 0 1 516.09 220.627] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -208.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 208.672 Td
-/F128_0 9.963 Tf
-(3.7.2.) 22.4168 Tj
--310 TJm
-(Critical) 29.889 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(handlin) 29.889 Tj
-1 TJm
-(g) 4.9815 Tj
-[1 0 0 1 234.42 208.672] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -239.401 -208.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-249.892 208.672 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 208.672] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -208.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 208.672 Td
-/F128_0 9.963 Tf
-(29) 9.963 Tj
-[1 0 0 1 516.09 208.672] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -196.717] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 196.717 Td
-/F128_0 9.963 Tf
-(3.8.) 14.9445 Tj
--310 TJm
-(Making) 30.9949 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(W) 9.40507 Tj
-40 TJm
-(indo) 17.7142 Tj
-25 TJm
-(ws) 11.0689 Tj
--250 TJm
-(DLL) 19.3681 Tj
-[1 0 0 1 213.738 196.717] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -218.719 -196.717] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-228.482 196.717 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 196.717] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -196.717] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 196.717 Td
-/F128_0 9.963 Tf
-(29) 9.963 Tj
-[1 0 0 1 516.09 196.717] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -72 -184.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 184.761 Td
-/F128_0 9.963 Tf
-(4.) 7.47225 Tj
--310 TJm
-(Miscellanea) 48.1412 Tj
-[1 0 0 1 130.699 184.761] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -135.68 -184.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.898 184.761 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 184.761] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -184.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 184.761 Td
-/F128_0 9.963 Tf
-(31) 9.963 Tj
-[1 0 0 1 516.09 184.761] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -172.806] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 172.806 Td
-/F128_0 9.963 Tf
-(4.1.) 14.9445 Tj
--310 TJm
-(Limitations) 45.9494 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(compre) 29.879 Tj
-1 TJm
-(ssed) 17.1563 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(format) 26.5614 Tj
-[1 0 0 1 279.141 172.806] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -284.122 -172.806] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.392 172.806 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 172.806] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -172.806] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 172.806 Td
-/F128_0 9.963 Tf
-(31) 9.963 Tj
-[1 0 0 1 516.09 172.806] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -160.851] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 160.851 Td
-/F128_0 9.963 Tf
-(4.2.) 14.9445 Tj
--310 TJm
-(Portability) 42.0737 Tj
--250 TJm
-(issues) 23.8016 Tj
-[1 0 0 1 182.305 160.851] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -187.286 -160.851] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-197.268 160.851 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 160.851] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -160.851] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 160.851 Td
-/F128_0 9.963 Tf
-(32) 9.963 Tj
-[1 0 0 1 516.09 160.851] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -148.896] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 148.896 Td
-/F128_0 9.963 Tf
-(4.3.) 14.9445 Tj
--310 TJm
-(Reporting) 39.852 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ugs) 13.8386 Tj
-[1 0 0 1 174.904 148.896] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -179.885 -148.896] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.14 148.896 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 148.896] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -148.896] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 148.896 Td
-/F128_0 9.963 Tf
-(32) 9.963 Tj
-[1 0 0 1 516.09 148.896] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -136.941] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 136.941 Td
-/F128_0 9.963 Tf
-(4.4.) 14.9445 Tj
--310 TJm
-(Did) 14.9445 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(get) 12.1748 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(right) 18.8201 Tj
--250 TJm
-(packag) 28.2152 Tj
-1 TJm
-(e?) 8.84714 Tj
-[1 0 0 1 236.512 136.941] cm
-0 g
-0 G
-[1 0 0 1 3.088 0] cm
-0 g
-0 G
-[1 0 0 1 3.089 0] cm
-0 g
-0 G
-[1 0 0 1 -242.689 -136.941] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-254.348 136.941 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 136.941] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -136.941] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 136.941 Td
-/F128_0 9.963 Tf
-(33) 9.963 Tj
-[1 0 0 1 516.09 136.941] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 23.91 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -95.91 -124.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.91 124.986 Td
-/F128_0 9.963 Tf
-(4.5.) 14.9445 Tj
--310 TJm
-(Further) 29.3311 Tj
--250 TJm
-(Reading) 33.2067 Tj
-[1 0 0 1 178.968 124.986] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -183.95 -124.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.386 124.986 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 124.986] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -124.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 124.986 Td
-/F128_0 9.963 Tf
-(34) 9.963 Tj
-[1 0 0 1 516.09 124.986] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 0 -62.014] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 41.399 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -494.668 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-536.068 50.852 Td
-/F128_0 9.963 Tf
-(iii) 8.30914 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 4 4
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 140.398 0] cm
-0 g
-0 G
-[1 0 0 1 -140.398 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -13.948] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F121_0 24.79 Tf
-(1.) 20.6749 Tj
--278 TJm
-(Intr) 39.9367 Tj
-20 TJm
-(oduction) 104.663 Tj
-[1 0 0 1 72 701.606] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -691.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 679.998 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 679.998] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -679.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.507 679.998 Td
-/F128_0 9.963 Tf
-(compresses) 45.9294 Tj
--263 TJm
-(\002les) 16.6083 Tj
--262 TJm
-(using) 21.5898 Tj
--263 TJm
-(the) 12.1748 Tj
--263 TJm
-(Burro) 23.2437 Tj
-25 TJm
-(ws-Wheeler) 48.1313 Tj
--263 TJm
-(block-sor) 37.6303 Tj
-1 TJm
-(ting) 15.5024 Tj
--263 TJm
-(te) 7.19329 Tj
-15 TJm
-(xt) 7.75121 Tj
--263 TJm
-(compression) 50.363 Tj
--263 TJm
-(algorithm,) 41.2369 Tj
--266 TJm
-(and) 14.3866 Tj
--263 TJm
-(H) 7.19329 Tj
-1 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fman) 20.474 Tj
--263 TJm
-(coding.) 29.61 Tj
-72 668.043 Td
-(Compression) 52.5847 Tj
--203 TJm
-(is) 6.64532 Tj
--203 TJm
-(generally) 37.0723 Tj
--204 TJm
-(c) 4.42357 Tj
-1 TJm
-(onsiderably) 46.4874 Tj
--204 TJm
-(better) 22.6858 Tj
--203 TJm
-(than) 17.1563 Tj
--203 TJm
-(that) 14.9445 Tj
--203 TJm
-(achie) 21.0219 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ed) 9.40507 Tj
--203 TJm
-(by) 9.963 Tj
--204 TJm
-(more) 20.474 Tj
--203 TJm
-(con) 14.3866 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(entional) 32.1008 Tj
--203 TJm
-(LZ77/LZ78-based) 73.0487 Tj
--203 TJm
-(compressors,) 52.2958 Tj
-72 656.087 Td
-(and) 14.3866 Tj
--250 TJm
-(approaches) 44.8136 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(performan) 41.4959 Tj
-1 TJm
-(ce) 8.84714 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(PPM) 19.936 Tj
--250 TJm
-(f) 3.31768 Tj
-10 TJm
-(amily) 22.6957 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(statistical) 37.6402 Tj
--250 TJm
-(compressors.) 52.2958 Tj
-[1 0 0 1 72 653.931] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -643.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 634.17 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 634.17] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.074 634.17 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--320 TJm
-(b) 4.9815 Tj
-20 TJm
-(uilt) 13.2906 Tj
--319 TJm
-(on) 9.963 Tj
--320 TJm
-(top) 12.7327 Tj
--320 TJm
-(of) 8.29918 Tj
-[1 0 0 1 176.712 634.17] cm
-0 g
-0 G
-[1 0 0 1 -176.712 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.712 634.17 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 224.533 634.17] cm
-0 g
-0 G
-[1 0 0 1 -224.533 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.533 634.17 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--337 TJm
-(a) 4.42357 Tj
--320 TJm
-(\003e) 9.963 Tj
-15 TJm
-(xible) 19.926 Tj
--319 TJm
-(library) 26.5614 Tj
--320 TJm
-(for) 11.6169 Tj
--320 TJm
-(handling) 34.8705 Tj
--319 TJm
-(compressed) 47.0353 Tj
--320 TJm
-(data) 16.5984 Tj
--320 TJm
-(in) 7.75121 Tj
--319 TJm
-(the) 12.1748 Tj
-[1 0 0 1 449.816 634.17] cm
-0 g
-0 G
-[1 0 0 1 -449.816 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.816 634.17 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 479.704 634.17] cm
-0 g
-0 G
-[1 0 0 1 -479.704 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.889 634.17 Td
-/F128_0 9.963 Tf
-(format.) 29.0521 Tj
--1038 TJm
-(This) 17.7142 Tj
-72 622.214 Td
-(manual) 29.3311 Tj
--316 TJm
-(describes) 37.0723 Tj
--316 TJm
-(both) 17.7142 Tj
--316 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--316 TJm
-(to) 7.75121 Tj
--316 TJm
-(use) 13.2807 Tj
--317 TJm
-(the) 12.1748 Tj
--316 TJm
-(program) 33.7546 Tj
--316 TJm
-(and) 14.3866 Tj
--316 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--316 TJm
-(to) 7.75121 Tj
--316 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--316 TJm
-(with) 17.7142 Tj
--316 TJm
-(the) 12.1748 Tj
--316 TJm
-(library) 26.5614 Tj
--317 TJm
-(int) 10.5209 Tj
-1 TJm
-(erf) 11.0589 Tj
-10 TJm
-(ace.) 15.7615 Tj
--1018 TJm
-(M) 8.85711 Tj
-1 TJm
-(ost) 11.6268 Tj
--317 TJm
-(of) 8.29918 Tj
--316 TJm
-(the) 12.1748 Tj
--316 TJm
-(manual) 29.3311 Tj
--316 TJm
-(is) 6.64532 Tj
-72 610.259 Td
-(de) 9.40507 Tj
-25 TJm
-(v) 4.9815 Tj
-20 TJm
-(oted) 17.1563 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(the) 12.1748 Tj
--249 TJm
-(program,) 36.2454 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(good) 19.926 Tj
--250 TJm
-(ne) 9.40507 Tj
-25 TJm
-(ws) 11.0689 Tj
--250 TJm
-(if) 6.08739 Tj
--250 TJm
-(your) 18.2622 Tj
--250 TJm
-(interest) 29.3311 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(only) 17.7142 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(th) 7.75121 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(program.) 36.2454 Tj
-[1 0 0 1 72 608.102] cm
-0 g
-0 G
-[1 0 0 1 0 -29.723] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 578.379 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 578.379] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -86.944 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 578.379 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--259 TJm
-(to) 7.75121 Tj
--260 TJm
-(use) 13.2807 Tj
--259 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 156.985 578.379] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -156.985 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.57 578.379 Td
-/F128_0 9.963 Tf
-([2]) 11.6169 Tj
-[1 0 0 1 171.186 578.379] cm
-0 0 1 rg
-0 0 1 RG
-0 g
-0 G
-[1 0 0 1 -171.186 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.771 578.379 Td
-/F128_0 9.963 Tf
-(describes) 37.0723 Tj
--259 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--260 TJm
-(to) 7.75121 Tj
--259 TJm
-(use) 13.2807 Tj
-[1 0 0 1 259.119 578.379] cm
-0 g
-0 G
-[1 0 0 1 -259.119 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.119 578.379 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 289.007 578.379] cm
-0 g
-0 G
-[1 0 0 1 -289.007 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.007 578.379 Td
-/F128_0 9.963 Tf
-(;) 2.76971 Tj
--264 TJm
-(this) 14.3965 Tj
--260 TJm
-(i) 2.76971 Tj
-1 TJm
-(s) 3.87561 Tj
--260 TJm
-(the) 12.1748 Tj
--259 TJm
-(only) 17.7142 Tj
--260 TJm
-(part) 15.4925 Tj
--259 TJm
-(you) 14.9445 Tj
--259 TJm
-(need) 18.8101 Tj
--260 TJm
-(to) 7.75121 Tj
--259 TJm
-(read) 17.1463 Tj
--260 TJm
-(if) 6.08739 Tj
--259 TJm
-(you) 14.9445 Tj
--259 TJm
-(just) 14.3965 Tj
--260 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--259 TJm
-(to) 7.75121 Tj
--260 TJm
-(kno) 14.9445 Tj
-25 TJm
-(w) 7.19329 Tj
-86.944 566.424 Td
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(operate) 29.3211 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(program.) 36.2454 Tj
-[1 0 0 1 199.302 566.424] cm
-0 g
-0 G
-[1 0 0 1 -127.302 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 544.506 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 544.506] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -86.944 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 544.506 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 197.09 544.506] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -197.09 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.58 544.506 Td
-/F128_0 9.963 Tf
-([8]) 11.6169 Tj
-[1 0 0 1 211.197 544.506] cm
-0 0 1 rg
-0 0 1 RG
-0 g
-0 G
-[1 0 0 1 -211.197 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.687 544.506 Td
-/F128_0 9.963 Tf
-(describes) 37.0723 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(programming) 54.2386 Tj
--250 TJm
-(int) 10.5209 Tj
-1 TJm
-(erf) 11.0589 Tj
-10 TJm
-(aces) 17.1463 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(detail,) 24.6285 Tj
--250 TJm
-(and) 14.3866 Tj
-[1 0 0 1 417.501 544.506] cm
-0 g
-0 G
-[1 0 0 1 -345.501 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 522.588 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 522.588] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -86.944 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 522.588 Td
-/F128_0 9.963 Tf
-(Miscellanea) 48.1412 Tj
-[1 0 0 1 135.083 522.588] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -135.083 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.573 522.588 Td
-/F128_0 9.963 Tf
-([31]) 16.5984 Tj
-[1 0 0 1 154.171 522.588] cm
-0 0 1 rg
-0 0 1 RG
-0 g
-0 G
-[1 0 0 1 -154.171 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-156.662 522.588 Td
-/F128_0 9.963 Tf
-(records) 29.3211 Tj
--250 TJm
-(some) 21.0319 Tj
--250 TJm
-(miscellane) 42.6118 Tj
-1 TJm
-(ous) 13.8386 Tj
--250 TJm
-(notes) 21.0319 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(I) 3.31768 Tj
--250 TJm
-(thought) 30.4469 Tj
--250 TJm
-(ought) 22.6957 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(recorded) 34.8506 Tj
--250 TJm
-(some) 21.0319 Tj
-25 TJm
-(where.) 26.8304 Tj
-[1 0 0 1 492.31 522.588] cm
-0 g
-0 G
-[1 0 0 1 -420.31 -471.736] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.063 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -496.332 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.852 Td
-/F128_0 9.963 Tf
-(1) 4.9815 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 5 5
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 140.398 0] cm
-0 g
-0 G
-[1 0 0 1 -140.398 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -13.948] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F121_0 24.79 Tf
-(2.) 20.6749 Tj
--278 TJm
-(Ho) 33.0451 Tj
-15 TJm
-(w) 19.2866 Tj
--278 TJm
-(to) 23.4018 Tj
--278 TJm
-(use) 42.7132 Tj
--278 TJm
-(bzip2) 63.3632 Tj
-[1 0 0 1 72 696.784] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -14.944] cm
-0 g
-0 G
-[1 0 0 1 -72 -671.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 656.35 Td
-/F121_0 17.215 Tf
-(T) 10.5184 Tj
-80 TJm
-(ab) 20.0899 Tj
-10 TJm
-(le) 14.3573 Tj
--278 TJm
-(of) 16.251 Tj
--278 TJm
-(Contents) 74.5926 Tj
-[1 0 0 1 72 647.528] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.74] cm
-0 g
-0 G
-[1 0 0 1 -72 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 635.788 Td
-/F128_0 9.963 Tf
-(2.1.) 14.9445 Tj
--310 TJm
-(N) 7.19329 Tj
-35 TJm
-(AME) 22.1378 Tj
-[1 0 0 1 119.013 635.788] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -123.995 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-132.691 635.788 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 635.788] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 635.788 Td
-/F128_0 9.963 Tf
-(2) 4.9815 Tj
-[1 0 0 1 516.09 635.788] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -72 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 623.832 Td
-/F128_0 9.963 Tf
-(2.2.) 14.9445 Tj
--310 TJm
-(SYNOPSIS) 47.0552 Tj
-[1 0 0 1 137.086 623.832] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -142.067 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.582 623.832 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 623.832] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 623.832 Td
-/F128_0 9.963 Tf
-(2) 4.9815 Tj
-[1 0 0 1 516.09 623.832] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -72 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 611.877 Td
-/F128_0 9.963 Tf
-(2.3.) 14.9445 Tj
--310 TJm
-(DESCRIPTION) 64.7595 Tj
-[1 0 0 1 154.789 611.877] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -159.77 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-168.29 611.877 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 611.877] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 611.877 Td
-/F128_0 9.963 Tf
-(3) 4.9815 Tj
-[1 0 0 1 516.09 611.877] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -72 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 599.922 Td
-/F128_0 9.963 Tf
-(2.4.) 14.9445 Tj
--310 TJm
-(OPTIONS) 42.0638 Tj
-[1 0 0 1 132.094 599.922] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -137.076 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.873 599.922 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 599.922] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 599.922 Td
-/F128_0 9.963 Tf
-(4) 4.9815 Tj
-[1 0 0 1 516.09 599.922] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.855] cm
-0 g
-0 G
-[1 0 0 1 -72 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 587.967 Td
-/F128_0 9.963 Tf
-(2.5.) 14.9445 Tj
--310 TJm
-(MEMOR) 37.6402 Tj
-65 TJm
-(Y) 7.19329 Tj
--250 TJm
-(MAN) 23.2437 Tj
-35 TJm
-(A) 7.19329 Tj
-40 TJm
-(GEMENT) 41.5059 Tj
-[1 0 0 1 207.9 587.967] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -212.881 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.412 587.967 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 587.967] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 587.967 Td
-/F128_0 9.963 Tf
-(5) 4.9815 Tj
-[1 0 0 1 516.09 587.967] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.855] cm
-0 g
-0 G
-[1 0 0 1 -72 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 576.012 Td
-/F128_0 9.963 Tf
-(2.6.) 14.9445 Tj
--310 TJm
-(RECO) 26.5713 Tj
-50 TJm
-(VERING) 37.6303 Tj
--250 TJm
-(D) 7.19329 Tj
-40 TJm
-(A) 7.19329 Tj
-111 TJm
-(T) 6.08739 Tj
-93 TJm
-(A) 7.19329 Tj
--250 TJm
-(FR) 12.1847 Tj
-40 TJm
-(OM) 16.0504 Tj
--249 TJm
-(D) 7.19329 Tj
-40 TJm
-(AMA) 23.2437 Tj
-40 TJm
-(GED) 20.474 Tj
--250 TJm
-(FILES) 26.5713 Tj
-[1 0 0 1 293.449 576.012] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -298.43 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.464 576.012 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 576.012] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 576.012 Td
-/F128_0 9.963 Tf
-(6) 4.9815 Tj
-[1 0 0 1 516.09 576.012] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.855] cm
-0 g
-0 G
-[1 0 0 1 -72 -564.057] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 564.057 Td
-/F128_0 9.963 Tf
-(2.7.) 14.9445 Tj
--310 TJm
-(PERFORMANCE) 73.6266 Tj
--250 TJm
-(NO) 14.3866 Tj
-40 TJm
-(TES) 17.7142 Tj
-[1 0 0 1 197.847 564.057] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -202.829 -564.057] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.958 564.057 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 564.057] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -564.057] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 564.057 Td
-/F128_0 9.963 Tf
-(6) 4.9815 Tj
-[1 0 0 1 516.09 564.057] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -72 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 552.101 Td
-/F128_0 9.963 Tf
-(2.8.) 14.9445 Tj
--310 TJm
-(CA) 13.8386 Tj
-135 TJm
-(VEA) 20.474 Tj
-111 TJm
-(TS) 11.6268 Tj
-[1 0 0 1 133.519 552.101] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -138.5 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-148.799 552.101 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 552.101] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 552.101 Td
-/F128_0 9.963 Tf
-(7) 4.9815 Tj
-[1 0 0 1 516.09 552.101] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.099] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.856] cm
-0 g
-0 G
-[1 0 0 1 -72 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 540.146 Td
-/F128_0 9.963 Tf
-(2.9.) 14.9445 Tj
--310 TJm
-(A) 7.19329 Tj
-55 TJm
-(UTHOR) 34.3126 Tj
-[1 0 0 1 130.989 540.146] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -135.97 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.32 540.146 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 540.146] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 540.146 Td
-/F128_0 9.963 Tf
-(7) 4.9815 Tj
-[1 0 0 1 516.09 540.146] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.219] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -520.002] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 508.266 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--250 TJm
-(chapter) 29.3211 Tj
--250 TJm
-(contains) 33.2067 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(cop) 14.3866 Tj
-10 TJm
-(y) 4.9815 Tj
--249 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
-[1 0 0 1 213.837 508.266] cm
-0 g
-0 G
-[1 0 0 1 -213.837 -508.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.837 508.266 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 243.725 508.266] cm
-0 g
-0 G
-[1 0 0 1 -243.725 -508.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.215 508.266 Td
-/F128_0 9.963 Tf
-(man) 17.1563 Tj
--250 TJm
-(page,) 21.3009 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(nothing) 30.4469 Tj
--250 TJm
-(else.) 17.9832 Tj
-[1 0 0 1 72 506.109] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -496.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 473.513 Td
-/F121_0 20.659 Tf
-(2.1.) 34.4592 Tj
--278 TJm
-(NAME) 60.8201 Tj
-[1 0 0 1 72 473.513] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -31.881] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 441.632 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 441.632] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 441.632 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 116.832 441.632] cm
-0 g
-0 G
-[1 0 0 1 -116.832 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.832 441.632 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 121.813 441.632] cm
-0 g
-0 G
-[1 0 0 1 -121.813 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-121.813 441.632 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 163.656 441.632] cm
-0 g
-0 G
-[1 0 0 1 -163.656 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.147 441.632 Td
-/F128_0 9.963 Tf
-(-) 3.31768 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(block-sorting) 53.1327 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(compre) 29.879 Tj
-1 TJm
-(ssor) 16.0504 Tj
-40 TJm
-(,) 2.49075 Tj
--250 TJm
-(v1.0.3) 24.9075 Tj
-[1 0 0 1 325.129 441.632] cm
-0 g
-0 G
-[1 0 0 1 -253.129 -21.917] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -419.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 419.715 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 419.715] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -419.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 419.715 Td
-/F130_0 9.963 Tf
-(bzcat) 29.889 Tj
-[1 0 0 1 116.832 419.715] cm
-0 g
-0 G
-[1 0 0 1 -116.832 -419.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.323 419.715 Td
-/F128_0 9.963 Tf
-(-) 3.31768 Tj
--250 TJm
-(decompresses) 55.3345 Tj
--250 TJm
-(\002les) 16.6083 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(st) 6.64532 Tj
-1 TJm
-(dout) 17.7142 Tj
-[1 0 0 1 236.651 419.715] cm
-0 g
-0 G
-[1 0 0 1 -164.651 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -397.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 397.797 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 397.797] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -397.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 397.797 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 158.675 397.797] cm
-0 g
-0 G
-[1 0 0 1 -158.675 -397.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.166 397.797 Td
-/F128_0 9.963 Tf
-(-) 3.31768 Tj
--250 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(ers) 11.6169 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(from) 19.3681 Tj
--250 TJm
-(damage) 30.9849 Tj
-1 TJm
-(d) 4.9815 Tj
--250 TJm
-(bzip2) 22.1378 Tj
--250 TJm
-(\002les) 16.6083 Tj
-[1 0 0 1 323.545 397.797] cm
-0 g
-0 G
-[1 0 0 1 -251.545 -12.12] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -375.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 353.081 Td
-/F121_0 20.659 Tf
-(2.2.) 34.4592 Tj
--278 TJm
-(SYNOPSIS) 105.629 Tj
-[1 0 0 1 72 352.823] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -31.622] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -321.201] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 321.201 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 321.201] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -321.201] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 321.201 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 116.832 321.201] cm
-0 g
-0 G
-[1 0 0 1 -116.832 -321.201] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.323 321.201 Td
-/F128_0 9.963 Tf
-([) 3.31768 Tj
--250 TJm
-(-cdfkqstvzVL123456789) 100.168 Tj
--250 TJm
-(]) 3.31768 Tj
--250 TJm
-([) 3.31768 Tj
--249 TJm
-(\002lenames) 38.1882 Tj
--250 TJm
-(...) 7.47225 Tj
--620 TJm
-(]) 3.31768 Tj
-[1 0 0 1 297.045 321.201] cm
-0 g
-0 G
-[1 0 0 1 -225.045 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -299.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 299.283 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 299.283] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -299.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 299.283 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 128.787 299.283] cm
-0 g
-0 G
-[1 0 0 1 -128.787 -299.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.278 299.283 Td
-/F128_0 9.963 Tf
-([) 3.31768 Tj
--250 TJm
-(-fkvsVL) 33.7546 Tj
--250 TJm
-(]) 3.31768 Tj
--250 TJm
-([) 3.31768 Tj
--250 TJm
-(\002lenames) 38.1882 Tj
--250 TJm
-(...) 7.47225 Tj
--620 TJm
-(]) 3.31768 Tj
-[1 0 0 1 242.589 299.283] cm
-0 g
-0 G
-[1 0 0 1 -170.589 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -277.365] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 277.365 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 277.365] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -277.365] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 277.365 Td
-/F130_0 9.963 Tf
-(bzcat) 29.889 Tj
-[1 0 0 1 116.832 277.365] cm
-0 g
-0 G
-[1 0 0 1 -116.832 -277.365] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.323 277.365 Td
-/F128_0 9.963 Tf
-([) 3.31768 Tj
--250 TJm
-(-s) 7.19329 Tj
--250 TJm
-(]) 3.31768 Tj
--250 TJm
-([) 3.31768 Tj
--250 TJm
-(\002lenames) 38.1882 Tj
--250 TJm
-(...) 7.47225 Tj
--620 TJm
-(]) 3.31768 Tj
-[1 0 0 1 204.074 277.365] cm
-0 g
-0 G
-[1 0 0 1 -132.074 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -255.447] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 255.447 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 255.447] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -255.447] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 255.447 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 158.675 255.447] cm
-0 g
-0 G
-[1 0 0 1 -158.675 -255.447] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.166 255.447 Td
-/F128_0 9.963 Tf
-(\002lename) 34.3126 Tj
-[1 0 0 1 195.477 255.447] cm
-0 g
-0 G
-[1 0 0 1 -123.477 -204.595] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.063 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -496.332 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.852 Td
-/F128_0 9.963 Tf
-(2) 4.9815 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 6 6
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 105.519 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 704.93 Td
-/F121_0 20.659 Tf
-(2.3.) 34.4592 Tj
--278 TJm
-(DESCRIPTION) 141.184 Tj
-[1 0 0 1 72 704.672] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -694.709] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 683.012 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 683.012] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -683.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.56 683.012 Td
-/F128_0 9.963 Tf
-(compresses) 45.9294 Tj
--268 TJm
-(\002les) 16.6083 Tj
--268 TJm
-(using) 21.5898 Tj
--268 TJm
-(the) 12.1748 Tj
--268 TJm
-(Burro) 23.2437 Tj
-25 TJm
-(ws-Wheeler) 48.1313 Tj
--268 TJm
-(block) 22.1378 Tj
--268 TJm
-(sorting) 27.6772 Tj
--268 TJm
-(te) 7.19329 Tj
-15 TJm
-(xt) 7.75121 Tj
--268 TJm
-(compression) 50.363 Tj
--268 TJm
-(algorithm,) 41.2369 Tj
--273 TJm
-(and) 14.3866 Tj
--268 TJm
-(Huf) 15.4925 Tj
-25 TJm
-(fman) 20.474 Tj
--268 TJm
-(coding.) 29.61 Tj
-72 671.057 Td
-(Compression) 52.5847 Tj
--203 TJm
-(is) 6.64532 Tj
--203 TJm
-(generally) 37.0723 Tj
--204 TJm
-(c) 4.42357 Tj
-1 TJm
-(onsiderably) 46.4874 Tj
--204 TJm
-(better) 22.6858 Tj
--203 TJm
-(than) 17.1563 Tj
--203 TJm
-(that) 14.9445 Tj
--203 TJm
-(achie) 21.0219 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ed) 9.40507 Tj
--203 TJm
-(by) 9.963 Tj
--204 TJm
-(more) 20.474 Tj
--203 TJm
-(con) 14.3866 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(entional) 32.1008 Tj
--203 TJm
-(LZ77/LZ78-based) 73.0487 Tj
--203 TJm
-(compressors,) 52.2958 Tj
-72 659.101 Td
-(and) 14.3866 Tj
--250 TJm
-(approaches) 44.8136 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(performan) 41.4959 Tj
-1 TJm
-(ce) 8.84714 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(PPM) 19.936 Tj
--250 TJm
-(f) 3.31768 Tj
-10 TJm
-(amily) 22.6957 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(statistical) 37.6402 Tj
--250 TJm
-(compressors.) 52.2958 Tj
-[1 0 0 1 72 656.945] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -646.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 637.184 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--250 TJm
-(command-line) 57.5563 Tj
--250 TJm
-(options) 29.341 Tj
--250 TJm
-(ar) 7.74125 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(deliberately) 47.0353 Tj
--250 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
--250 TJm
-(similar) 27.6772 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(those) 21.0319 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(GNU) 21.5799 Tj
-[1 0 0 1 364.869 637.184] cm
-0 g
-0 G
-[1 0 0 1 -364.869 -637.184] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-364.869 637.184 Td
-/F130_0 9.963 Tf
-(gzip) 23.9112 Tj
-[1 0 0 1 388.779 637.184] cm
-0 g
-0 G
-[1 0 0 1 -388.779 -637.184] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-388.779 637.184 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--250 TJm
-(are) 12.1648 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(identical.) 36.8033 Tj
-[1 0 0 1 72 635.027] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -625.064] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 615.266 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 615.266] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -615.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.175 615.266 Td
-/F128_0 9.963 Tf
-(e) 4.42357 Tj
-15 TJm
-(xpects) 25.4555 Tj
--330 TJm
-(a) 4.42357 Tj
--330 TJm
-(list) 12.1847 Tj
--329 TJm
-(of) 8.29918 Tj
--330 TJm
-(\002le) 12.7327 Tj
--330 TJm
-(names) 25.4555 Tj
--330 TJm
-(to) 7.75121 Tj
--330 TJm
-(accompan) 40.39 Tj
-15 TJm
-(y) 4.9815 Tj
--329 TJm
-(the) 12.1748 Tj
--330 TJm
-(command-line) 57.5563 Tj
--330 TJm
-(\003ags.) 21.3109 Tj
--1099 TJm
-(Each) 19.916 Tj
--330 TJm
-(\002le) 12.7327 Tj
--330 TJm
-(is) 6.64532 Tj
--330 TJm
-(replaced) 33.7447 Tj
--330 TJm
-(by) 9.963 Tj
--329 TJm
-(a) 4.42357 Tj
--330 TJm
-(compressed) 47.0353 Tj
-72 603.311 Td
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--348 TJm
-(of) 8.29918 Tj
--349 TJm
-(itself,) 22.4168 Tj
--373 TJm
-(with) 17.7142 Tj
--349 TJm
-(the) 12.1748 Tj
--348 TJm
-(name) 21.5799 Tj
-[1 0 0 1 204.444 603.311] cm
-0 g
-0 G
-[1 0 0 1 -204.444 -603.311] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.444 603.311 Td
-/F130_0 9.963 Tf
-(original_name.bz2) 101.623 Tj
-[1 0 0 1 306.063 603.311] cm
-0 g
-0 G
-[1 0 0 1 -306.063 -603.311] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-306.063 603.311 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1211 TJm
-(Each) 19.916 Tj
--349 TJm
-(compressed) 47.0353 Tj
--348 TJm
-(\002le) 12.7327 Tj
--349 TJm
-(has) 13.2807 Tj
--348 TJm
-(the) 12.1748 Tj
--349 TJm
-(same) 20.474 Tj
--348 TJm
-(modi\002cation) 50.3729 Tj
--349 TJm
-(date,) 19.0891 Tj
-72 591.356 Td
-(permissions,) 50.094 Tj
--344 TJm
-(and,) 16.8773 Tj
--344 TJm
-(when) 21.5799 Tj
--325 TJm
-(possible,) 35.1495 Tj
--344 TJm
-(o) 4.9815 Tj
-25 TJm
-(w) 7.19329 Tj
-1 TJm
-(nership) 29.3311 Tj
--326 TJm
-(as) 8.29918 Tj
--325 TJm
-(the) 12.1748 Tj
--325 TJm
-(corresponding) 56.9983 Tj
--325 TJm
-(original,) 33.4856 Tj
--344 TJm
-(so) 8.85711 Tj
--325 TJm
-(that) 14.9445 Tj
--325 TJm
-(these) 20.474 Tj
--325 TJm
-(properties) 39.842 Tj
--325 TJm
-(can) 13.8286 Tj
--325 TJm
-(be) 9.40507 Tj
--325 TJm
-(correctly) 35.4085 Tj
-72 579.4 Td
-(restored) 32.0908 Tj
--308 TJm
-(at) 7.19329 Tj
--307 TJm
-(decompression) 59.768 Tj
--308 TJm
-(time.) 20.205 Tj
--483 TJm
-(File) 15.5024 Tj
--308 TJm
-(name) 21.5799 Tj
--308 TJm
-(handling) 34.8705 Tj
--308 TJm
-(is) 6.64532 Tj
--307 TJm
-(nai) 12.1748 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--308 TJm
-(in) 7.75121 Tj
--308 TJm
-(the) 12.1748 Tj
--308 TJm
-(sense) 21.5799 Tj
--308 TJm
-(that) 14.9445 Tj
--307 TJm
-(there) 19.916 Tj
--308 TJm
-(is) 6.64532 Tj
--308 TJm
-(no) 9.963 Tj
--308 TJm
-(mechanism) 45.3815 Tj
--307 TJm
-(for) 11.6169 Tj
--308 TJm
-(preserving) 42.0538 Tj
-72 567.445 Td
-(original) 30.9949 Tj
--334 TJm
-(\002le) 12.7327 Tj
--333 TJm
-(names,) 27.9462 Tj
--355 TJm
-(permissi) 33.7646 Tj
-1 TJm
-(ons,) 16.3294 Tj
--355 TJm
-(o) 4.9815 Tj
-25 TJm
-(wnerships) 40.4 Tj
--334 TJm
-(or) 8.29918 Tj
--333 TJm
-(dates) 20.474 Tj
--334 TJm
-(in) 7.75121 Tj
--333 TJm
-(\002lesystems) 44.2855 Tj
--334 TJm
-(which) 24.3496 Tj
--333 TJm
-(lack) 16.5984 Tj
--334 TJm
-(these) 20.474 Tj
--334 TJm
-(concepts,) 37.3513 Tj
--354 TJm
-(or) 8.29918 Tj
--334 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--333 TJm
-(serious) 28.2252 Tj
--334 TJm
-(\002le) 12.7327 Tj
-72 555.49 Td
-(name) 21.5799 Tj
--250 TJm
-(length) 24.9075 Tj
--250 TJm
-(restrictions,) 46.7663 Tj
--250 TJm
-(su) 8.85711 Tj
-1 TJm
-(ch) 9.40507 Tj
--250 TJm
-(as) 8.29918 Tj
--250 TJm
-(MS-DOS.) 40.131 Tj
-[1 0 0 1 72 553.333] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -543.371] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 533.572 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 533.572] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.379 533.572 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 121.255 533.572] cm
-0 g
-0 G
-[1 0 0 1 -121.255 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-121.255 533.572 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 163.098 533.572] cm
-0 g
-0 G
-[1 0 0 1 -163.098 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.589 533.572 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--250 TJm
-(by) 9.963 Tj
--250 TJm
-(def) 12.7228 Tj
-10 TJm
-(ault) 14.9445 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(erwrite) 28.2152 Tj
--250 TJm
-(e) 4.42357 Tj
-16 TJm
-(xisting) 27.1292 Tj
--250 TJm
-(\002les.) 19.0991 Tj
--620 TJm
-(If) 6.63536 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(happen,) 31.2639 Tj
--250 TJm
-(specify) 28.7731 Tj
--250 TJm
-(the) 12.1748 Tj
-[1 0 0 1 495.977 533.572] cm
-0 g
-0 G
-[1 0 0 1 -495.977 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-495.977 533.572 Td
-/F130_0 9.963 Tf
-(-f) 11.9556 Tj
-[1 0 0 1 507.932 533.572] cm
-0 g
-0 G
-[1 0 0 1 -507.932 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.423 533.572 Td
-/F128_0 9.963 Tf
-(\003ag.) 17.4353 Tj
-[1 0 0 1 72 531.415] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -521.453] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 511.654 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--284 TJm
-(no) 9.963 Tj
--285 TJm
-(\002) 5.53943 Tj
-1 TJm
-(le) 7.19329 Tj
--285 TJm
-(names) 25.4555 Tj
--284 TJm
-(are) 12.1648 Tj
--284 TJm
-(speci\002ed,) 37.9092 Tj
-[1 0 0 1 193.935 511.654] cm
-0 g
-0 G
-[1 0 0 1 -193.935 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.935 511.654 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 223.823 511.654] cm
-0 g
-0 G
-[1 0 0 1 -223.823 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-226.655 511.654 Td
-/F128_0 9.963 Tf
-(compresses) 45.9294 Tj
--284 TJm
-(from) 19.3681 Tj
--284 TJm
-(standard) 33.7546 Tj
--284 TJm
-(input) 20.4839 Tj
--285 TJm
-(to) 7.75121 Tj
--284 TJm
-(standard) 33.7546 Tj
--284 TJm
-(output.) 27.9562 Tj
--826 TJm
-(In) 8.29918 Tj
--284 TJm
-(this) 14.3965 Tj
--284 TJm
-(case,) 19.6371 Tj
-[1 0 0 1 491.778 511.654] cm
-0 g
-0 G
-[1 0 0 1 -491.778 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-491.778 511.654 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 521.666 511.654] cm
-0 g
-0 G
-[1 0 0 1 -521.666 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-524.498 511.654 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
-72 499.699 Td
-(decline) 28.7731 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(write) 20.474 Tj
--250 TJm
-(compressed) 47.0353 Tj
--249 TJm
-(output) 25.4654 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(terminal,) 35.6974 Tj
--250 TJm
-(as) 8.29918 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(entirely) 30.437 Tj
--250 TJm
-(incompre) 37.6303 Tj
-1 TJm
-(hensible) 33.2067 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(therefore) 35.9565 Tj
--250 TJm
-(pointless.) 37.9192 Tj
-[1 0 0 1 72 497.542] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -487.58] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 477.781 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 113.843 477.781] cm
-0 g
-0 G
-[1 0 0 1 -113.843 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.176 477.781 Td
-/F128_0 9.963 Tf
-(\(or) 11.6169 Tj
-[1 0 0 1 130.125 477.781] cm
-0 g
-0 G
-[1 0 0 1 -130.125 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-130.125 477.781 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
--600 TJm
-(-d) 11.9556 Tj
-[1 0 0 1 177.946 477.781] cm
-0 g
-0 G
-[1 0 0 1 -177.946 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-177.946 477.781 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--234 TJm
-(decompresses) 55.3345 Tj
--234 TJm
-(all) 9.963 Tj
--234 TJm
-(speci\002ed) 35.4185 Tj
--234 TJm
-(\002les.) 19.0991 Tj
--609 TJm
-(Files) 19.378 Tj
--234 TJm
-(which) 24.3496 Tj
--235 TJm
-(we) 11.6169 Tj
-1 TJm
-(re) 7.74125 Tj
--235 TJm
-(not) 12.7327 Tj
--234 TJm
-(created) 28.7632 Tj
--234 TJm
-(by) 9.963 Tj
-[1 0 0 1 445.012 477.781] cm
-0 g
-0 G
-[1 0 0 1 -445.012 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-445.012 477.781 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 474.9 477.781] cm
-0 g
-0 G
-[1 0 0 1 -474.9 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.233 477.781 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--234 TJm
-(be) 9.40507 Tj
--234 TJm
-(detected) 33.1967 Tj
-72 465.826 Td
-(and) 14.3866 Tj
--279 TJm
-(ignored,) 32.9277 Tj
--287 TJm
-(and) 14.3866 Tj
--280 TJm
-(a) 4.42357 Tj
--279 TJm
-(w) 7.19329 Tj
-10 TJm
-(arning) 25.4555 Tj
--279 TJm
-(issued.) 27.3983 Tj
-[1 0 0 1 216.033 465.826] cm
-0 g
-0 G
-[1 0 0 1 -216.033 -465.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.033 465.826 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 245.921 465.826] cm
-0 g
-0 G
-[1 0 0 1 -245.921 -465.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.705 465.826 Td
-/F128_0 9.963 Tf
-(attempts) 33.7646 Tj
--279 TJm
-(to) 7.75121 Tj
--280 TJm
-(guess) 22.1378 Tj
--279 TJm
-(the) 12.1748 Tj
--280 TJm
-(\002lenam) 29.889 Tj
-1 TJm
-(e) 4.42357 Tj
--280 TJm
-(for) 11.6169 Tj
--279 TJm
-(the) 12.1748 Tj
--280 TJm
-(decompressed) 56.4404 Tj
--279 TJm
-(\002le) 12.7327 Tj
--280 TJm
-(fr) 6.63536 Tj
-1 TJm
-(om) 12.7327 Tj
--280 TJm
-(that) 14.9445 Tj
--279 TJm
-(of) 8.29918 Tj
--280 TJm
-(the) 12.1748 Tj
-72 453.871 Td
-(compressed) 47.0353 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(as) 8.29918 Tj
--250 TJm
-(follo) 18.8201 Tj
-25 TJm
-(ws:) 13.8386 Tj
-[1 0 0 1 72 451.714] cm
-0 g
-0 G
-[1 0 0 1 0 -29.723] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 421.991 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 421.991] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 421.991 Td
-/F130_0 9.963 Tf
-(filename.bz2) 71.7336 Tj
-[1 0 0 1 164.653 421.991] cm
-0 g
-0 G
-[1 0 0 1 -164.653 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 421.991 Td
-/F128_0 9.963 Tf
-(becomes) 34.8605 Tj
-[1 0 0 1 204.493 421.991] cm
-0 g
-0 G
-[1 0 0 1 -204.493 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 421.991 Td
-/F130_0 9.963 Tf
-(filename) 47.8224 Tj
-[1 0 0 1 252.313 421.991] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -180.313 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 400.073 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 400.073] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 400.073 Td
-/F130_0 9.963 Tf
-(filename.bz) 65.7558 Tj
-[1 0 0 1 158.675 400.073] cm
-0 g
-0 G
-[1 0 0 1 -158.675 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.166 400.073 Td
-/F128_0 9.963 Tf
-(becomes) 34.8605 Tj
-[1 0 0 1 198.515 400.073] cm
-0 g
-0 G
-[1 0 0 1 -198.515 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.515 400.073 Td
-/F130_0 9.963 Tf
-(filename) 47.8224 Tj
-[1 0 0 1 246.336 400.073] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -174.336 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 378.155 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 378.155] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 378.155 Td
-/F130_0 9.963 Tf
-(filename.tbz2) 77.7114 Tj
-[1 0 0 1 164.653 378.155] cm
-0 g
-0 G
-[1 0 0 1 -164.653 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 378.155 Td
-/F128_0 9.963 Tf
-(becomes) 34.8605 Tj
-[1 0 0 1 204.493 378.155] cm
-0 g
-0 G
-[1 0 0 1 -204.493 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 378.155 Td
-/F130_0 9.963 Tf
-(filename.tar) 71.7336 Tj
-[1 0 0 1 276.224 378.155] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -204.224 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 356.237 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 356.237] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 356.237 Td
-/F130_0 9.963 Tf
-(filename.tbz) 71.7336 Tj
-[1 0 0 1 164.653 356.237] cm
-0 g
-0 G
-[1 0 0 1 -164.653 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 356.237 Td
-/F128_0 9.963 Tf
-(becomes) 34.8605 Tj
-[1 0 0 1 204.493 356.237] cm
-0 g
-0 G
-[1 0 0 1 -204.493 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 356.237 Td
-/F130_0 9.963 Tf
-(filename.tar) 71.7336 Tj
-[1 0 0 1 276.224 356.237] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -204.224 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 334.319 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 334.319] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 334.319 Td
-/F130_0 9.963 Tf
-(anyothername) 71.7336 Tj
-[1 0 0 1 164.653 334.319] cm
-0 g
-0 G
-[1 0 0 1 -164.653 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 334.319 Td
-/F128_0 9.963 Tf
-(becomes) 34.8605 Tj
-[1 0 0 1 204.493 334.319] cm
-0 g
-0 G
-[1 0 0 1 -204.493 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 334.319 Td
-/F130_0 9.963 Tf
-(anyothername.out) 95.6448 Tj
-[1 0 0 1 300.134 334.319] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -228.134 -11.526] cm
-0 g
-0 G
-[1 0 0 1 -72 -322.793] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 312.402 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--342 TJm
-(the) 12.1748 Tj
--342 TJm
-(\002le) 12.7327 Tj
--342 TJm
-(does) 18.2622 Tj
--342 TJm
-(not) 12.7327 Tj
--342 TJm
-(end) 14.3866 Tj
--342 TJm
-(in) 7.75121 Tj
--342 TJm
-(one) 14.3866 Tj
--343 TJm
-(of) 8.29918 Tj
--342 TJm
-(the) 12.1748 Tj
--342 TJm
-(recognised) 43.1597 Tj
--342 TJm
-(endings,) 33.4856 Tj
-[1 0 0 1 309.305 312.402] cm
-0 g
-0 G
-[1 0 0 1 -309.305 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.305 312.402 Td
-/F130_0 9.963 Tf
-(.bz2) 23.9112 Tj
-[1 0 0 1 333.215 312.402] cm
-0 g
-0 G
-[1 0 0 1 -333.215 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.215 312.402 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 339.344 312.402] cm
-0 g
-0 G
-[1 0 0 1 -339.344 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.344 312.402 Td
-/F130_0 9.963 Tf
-(.bz) 17.9334 Tj
-[1 0 0 1 357.276 312.402] cm
-0 g
-0 G
-[1 0 0 1 -357.276 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-357.276 312.402 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 363.405 312.402] cm
-0 g
-0 G
-[1 0 0 1 -363.405 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.405 312.402 Td
-/F130_0 9.963 Tf
-(.tbz2) 29.889 Tj
-[1 0 0 1 393.293 312.402] cm
-0 g
-0 G
-[1 0 0 1 -393.293 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-396.702 312.402 Td
-/F128_0 9.963 Tf
-(or) 8.29918 Tj
-[1 0 0 1 408.409 312.402] cm
-0 g
-0 G
-[1 0 0 1 -408.409 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-408.409 312.402 Td
-/F130_0 9.963 Tf
-(.tbz) 23.9112 Tj
-[1 0 0 1 432.319 312.402] cm
-0 g
-0 G
-[1 0 0 1 -432.319 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-432.319 312.402 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 438.448 312.402] cm
-0 g
-0 G
-[1 0 0 1 -438.448 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.448 312.402 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 468.336 312.402] cm
-0 g
-0 G
-[1 0 0 1 -468.336 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-471.744 312.402 Td
-/F128_0 9.963 Tf
-(complains) 40.9579 Tj
--342 TJm
-(that) 14.9445 Tj
--342 TJm
-(it) 5.53943 Tj
-72 300.446 Td
-(cannot) 26.5614 Tj
--250 TJm
-(guess) 22.1378 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(name) 21.5799 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--249 TJm
-(original) 30.9949 Tj
--250 TJm
-(\002le,) 15.2235 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(uses) 17.1563 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(original) 30.9949 Tj
--250 TJm
-(name) 21.5799 Tj
--250 TJm
-(with) 17.7142 Tj
-[1 0 0 1 370.009 300.446] cm
-0 g
-0 G
-[1 0 0 1 -370.009 -300.446] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.009 300.446 Td
-/F130_0 9.963 Tf
-(.out) 23.9112 Tj
-[1 0 0 1 393.92 300.446] cm
-0 g
-0 G
-[1 0 0 1 -393.92 -300.446] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-396.41 300.446 Td
-/F128_0 9.963 Tf
-(appended.) 40.669 Tj
-[1 0 0 1 72 298.29] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -288.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 278.529 Td
-/F128_0 9.963 Tf
-(As) 11.0689 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(compression,) 52.8537 Tj
--250 TJm
-(supply) 26.5713 Tj
-1 TJm
-(ing) 12.7327 Tj
--250 TJm
-(no) 9.963 Tj
--250 TJm
-(\002lenames) 38.1882 Tj
--250 TJm
-(causes) 26.0034 Tj
--250 TJm
-(decompression) 59.768 Tj
--250 TJm
-(from) 19.3681 Tj
--250 TJm
-(standard) 33.7546 Tj
--250 TJm
-(inp) 12.7327 Tj
-1 TJm
-(ut) 7.75121 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(standard) 33.7546 Tj
--250 TJm
-(output.) 27.9562 Tj
-[1 0 0 1 72 276.372] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -266.409] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 256.611 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 113.843 256.611] cm
-0 g
-0 G
-[1 0 0 1 -113.843 -256.611] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.409 256.611 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--257 TJm
-(correctly) 35.4085 Tj
--258 TJm
-(decompress) 47.0353 Tj
--257 TJm
-(a) 4.42357 Tj
--258 TJm
-(\002l) 8.30914 Tj
-1 TJm
-(e) 4.42357 Tj
--258 TJm
-(which) 24.3496 Tj
--257 TJm
-(is) 6.64532 Tj
--258 TJm
-(the) 12.1748 Tj
--257 TJm
-(concatenation) 55.3345 Tj
--258 TJm
-(of) 8.29918 Tj
--257 TJm
-(tw) 9.963 Tj
-10 TJm
-(o) 4.9815 Tj
--257 TJm
-(or) 8.29918 Tj
--258 TJm
-(more) 20.474 Tj
--257 TJm
-(compressed) 47.0353 Tj
--258 TJm
-(\002les.) 19.0991 Tj
--665 TJm
-(The) 15.4925 Tj
--257 TJm
-(result) 22.1378 Tj
--258 TJm
-(is) 6.64532 Tj
-72 244.656 Td
-(the) 12.1748 Tj
--239 TJm
-(concatena) 39.8321 Tj
-1 TJm
-(tion) 15.5024 Tj
--239 TJm
-(of) 8.29918 Tj
--239 TJm
-(the) 12.1748 Tj
--238 TJm
-(corresponding) 56.9983 Tj
--239 TJm
-(uncompressed) 56.9983 Tj
--238 TJm
-(\002les.) 19.0991 Tj
--613 TJm
-(Inte) 15.4925 Tj
-15 TJm
-(grity) 18.8201 Tj
--238 TJm
-(testing) 26.5713 Tj
--239 TJm
-(\() 3.31768 Tj
-[1 0 0 1 382.247 244.656] cm
-0 g
-0 G
-[1 0 0 1 -382.247 -244.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-382.247 244.656 Td
-/F130_0 9.963 Tf
-(-t) 11.9556 Tj
-[1 0 0 1 394.202 244.656] cm
-0 g
-0 G
-[1 0 0 1 -394.202 -244.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-394.202 244.656 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--239 TJm
-(of) 8.29918 Tj
--238 TJm
-(concatenated) 52.0069 Tj
--239 TJm
-(compressed) 47.0353 Tj
--238 TJm
-(\002les) 16.6083 Tj
--239 TJm
-(is) 6.64532 Tj
-72 232.7 Td
-(also) 16.0504 Tj
--250 TJm
-(supported.) 41.7848 Tj
-[1 0 0 1 72 230.544] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -220.581] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 210.783 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--399 TJm
-(can) 13.8286 Tj
--399 TJm
-(also) 16.0504 Tj
--399 TJm
-(compress) 37.6303 Tj
--399 TJm
-(or) 8.29918 Tj
--399 TJm
-(decompress) 47.0353 Tj
--399 TJm
-(\002les) 16.6083 Tj
--399 TJm
-(to) 7.75121 Tj
--399 TJm
-(the) 12.1748 Tj
--399 TJm
-(standard) 33.7546 Tj
--399 TJm
-(output) 25.4654 Tj
--399 TJm
-(by) 9.963 Tj
--399 TJm
-(gi) 7.75121 Tj
-25 TJm
-(ving) 17.7142 Tj
--399 TJm
-(the) 12.1748 Tj
-[1 0 0 1 409.67 210.783] cm
-0 g
-0 G
-[1 0 0 1 -409.67 -210.783] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-409.67 210.783 Td
-/F130_0 9.963 Tf
-(-c) 11.9556 Tj
-[1 0 0 1 421.625 210.783] cm
-0 g
-0 G
-[1 0 0 1 -421.625 -210.783] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.602 210.783 Td
-/F128_0 9.963 Tf
-(\003ag.) 17.4353 Tj
--757 TJm
-(Multiple) 34.3225 Tj
--399 TJm
-(\002les) 16.6083 Tj
--399 TJm
-(may) 17.1563 Tj
--399 TJm
-(be) 9.40507 Tj
-72 198.828 Td
-(compressed) 47.0353 Tj
--367 TJm
-(and) 14.3866 Tj
--367 TJm
-(dec) 13.8286 Tj
-1 TJm
-(ompressed) 42.6118 Tj
--367 TJm
-(lik) 10.5209 Tj
-10 TJm
-(e) 4.42357 Tj
--367 TJm
-(this.) 16.8873 Tj
--1321 TJm
-(The) 15.4925 Tj
--367 TJm
-(resulting) 34.8705 Tj
--367 TJm
-(outputs) 29.341 Tj
--367 TJm
-(are) 12.1648 Tj
--367 TJm
-(fed) 12.7228 Tj
--366 TJm
-(sequentially) 48.1512 Tj
--367 TJm
-(to) 7.75121 Tj
--367 TJm
-(stdout.) 26.8503 Tj
--1321 TJm
-(Compression) 52.5847 Tj
--367 TJm
-(of) 8.29918 Tj
-72 186.872 Td
-(multiple) 33.2166 Tj
--289 TJm
-(\002les) 16.6083 Tj
--289 TJm
-(in) 7.75121 Tj
--288 TJm
-(this) 14.3965 Tj
--289 TJm
-(manner) 29.879 Tj
--289 TJm
-(generates) 37.6203 Tj
--289 TJm
-(a) 4.42357 Tj
--289 TJm
-(stre) 14.3866 Tj
-1 TJm
-(am) 12.1748 Tj
--289 TJm
-(containing) 42.0638 Tj
--289 TJm
-(multiple) 33.2166 Tj
--289 TJm
-(compressed) 47.0353 Tj
--288 TJm
-(\002le) 12.7327 Tj
--289 TJm
-(representations.) 62.8068 Tj
--853 TJm
-(Such) 19.926 Tj
--289 TJm
-(a) 4.42357 Tj
--289 TJm
-(stream) 26.5614 Tj
-72 174.917 Td
-(can) 13.8286 Tj
--391 TJm
-(be) 9.40507 Tj
--391 TJm
-(dec) 13.8286 Tj
-1 TJm
-(ompressed) 42.6118 Tj
--391 TJm
-(correctly) 35.4085 Tj
--391 TJm
-(only) 17.7142 Tj
--391 TJm
-(by) 9.963 Tj
-[1 0 0 1 238.116 174.917] cm
-0 g
-0 G
-[1 0 0 1 -238.116 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.116 174.917 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 268.004 174.917] cm
-0 g
-0 G
-[1 0 0 1 -268.004 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-271.897 174.917 Td
-/F128_0 9.963 Tf
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--391 TJm
-(0.9.0) 19.926 Tj
--391 TJm
-(o) 4.9815 Tj
-1 TJm
-(r) 3.31768 Tj
--391 TJm
-(later) 17.7043 Tj
-55 TJm
-(.) 2.49075 Tj
--733 TJm
-(Earlier) 27.1093 Tj
--390 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--391 TJm
-(of) 8.29918 Tj
-[1 0 0 1 448.071 174.917] cm
-0 g
-0 G
-[1 0 0 1 -448.071 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-448.071 174.917 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 477.959 174.917] cm
-0 g
-0 G
-[1 0 0 1 -477.959 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-481.852 174.917 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--391 TJm
-(stop) 16.6083 Tj
--391 TJm
-(a) 4.42357 Tj
-1 TJm
-(fter) 13.8286 Tj
-72 162.962 Td
-(decompressing) 59.768 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\002rst) 15.5024 Tj
--250 TJm
-(\002le) 12.7327 Tj
--249 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 72 160.805] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -150.843] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 141.044 Td
-/F130_0 9.963 Tf
-(bzcat) 29.889 Tj
-[1 0 0 1 101.888 141.044] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -141.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.379 141.044 Td
-/F128_0 9.963 Tf
-(\(or) 11.6169 Tj
-[1 0 0 1 118.486 141.044] cm
-0 g
-0 G
-[1 0 0 1 -118.486 -141.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.486 141.044 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
--600 TJm
-(-dc) 17.9334 Tj
-[1 0 0 1 172.284 141.044] cm
-0 g
-0 G
-[1 0 0 1 -172.284 -141.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.284 141.044 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--250 TJm
-(decompresses) 55.3345 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(speci\002e) 30.437 Tj
-1 TJm
-(d) 4.9815 Tj
--250 TJm
-(\002les) 16.6083 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(standard) 33.7546 Tj
--250 TJm
-(output.) 27.9562 Tj
-[1 0 0 1 72 138.887] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -128.925] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 119.126 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 119.126] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.866 119.126 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--299 TJm
-(read) 17.1463 Tj
--299 TJm
-(ar) 7.74125 Tj
-18 TJm
-(gument) 29.889 Tj
-1 TJm
-(s) 3.87561 Tj
--299 TJm
-(from) 19.3681 Tj
--299 TJm
-(the) 12.1748 Tj
--299 TJm
-(en) 9.40507 Tj
-40 TJm
-(vironment) 40.9579 Tj
--299 TJm
-(v) 4.9815 Tj
-25 TJm
-(ariables) 30.9849 Tj
-[1 0 0 1 316.903 119.126] cm
-0 g
-0 G
-[1 0 0 1 -316.903 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-316.903 119.126 Td
-/F130_0 9.963 Tf
-(BZIP2) 29.889 Tj
-[1 0 0 1 346.791 119.126] cm
-0 g
-0 G
-[1 0 0 1 -346.791 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-349.769 119.126 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 367.133 119.126] cm
-0 g
-0 G
-[1 0 0 1 -367.133 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-367.133 119.126 Td
-/F130_0 9.963 Tf
-(BZIP) 23.9112 Tj
-[1 0 0 1 391.043 119.126] cm
-0 g
-0 G
-[1 0 0 1 -391.043 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-391.043 119.126 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--299 TJm
-(in) 7.75121 Tj
--299 TJm
-(that) 14.9445 Tj
--299 TJm
-(order) 21.0219 Tj
-40 TJm
-(,) 2.49075 Tj
--311 TJm
-(and) 14.3866 Tj
--299 TJm
-(wil) 12.7327 Tj
-1 TJm
-(l) 2.76971 Tj
--299 TJm
-(process) 29.879 Tj
--299 TJm
-(them) 19.926 Tj
-72 107.171 Td
-(before) 25.4455 Tj
--250 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--250 TJm
-(ar) 7.74125 Tj
-18 TJm
-(guments) 33.7646 Tj
--250 TJm
-(read) 17.1463 Tj
--250 TJm
-(from) 19.3681 Tj
--249 TJm
-(the) 12.1748 Tj
--250 TJm
-(command) 39.2941 Tj
--250 TJm
-(line.) 17.4353 Tj
--310 TJm
-(This) 17.7142 Tj
--250 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(con) 14.3866 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(enient) 24.3496 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ay) 9.40507 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(supply) 26.5713 Tj
--250 TJm
-(d) 4.9815 Tj
-1 TJm
-(ef) 7.74125 Tj
-10 TJm
-(ault) 14.9445 Tj
--250 TJm
-(ar) 7.74125 Tj
-18 TJm
-(guments.) 36.2554 Tj
-[1 0 0 1 72 105.014] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -95.052] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 85.253 Td
-/F128_0 9.963 Tf
-(Compression) 52.5847 Tj
--294 TJm
-(is) 6.64532 Tj
--294 TJm
-(al) 7.19329 Tj
-10 TJm
-(w) 7.19329 Tj
-10 TJm
-(ays) 13.2807 Tj
--293 TJm
-(performed,) 43.9866 Tj
--305 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--294 TJm
-(if) 6.08739 Tj
--294 TJm
-(the) 12.1748 Tj
--294 TJm
-(compressed) 47.0353 Tj
--294 TJm
-(\002le) 12.7327 Tj
--294 TJm
-(i) 2.76971 Tj
-1 TJm
-(s) 3.87561 Tj
--294 TJm
-(slightly) 29.899 Tj
--294 TJm
-(lar) 10.511 Tj
-18 TJm
-(ger) 12.7228 Tj
--294 TJm
-(than) 17.1563 Tj
--294 TJm
-(the) 12.1748 Tj
--294 TJm
-(original.) 33.4856 Tj
--883 TJm
-(Files) 19.378 Tj
--294 TJm
-(of) 8.29918 Tj
--294 TJm
-(less) 14.9445 Tj
--294 TJm
-(than) 17.1563 Tj
-72 73.298 Td
-(about) 22.1378 Tj
--246 TJm
-(one) 14.3866 Tj
--245 TJm
-(hundred) 32.6488 Tj
--246 TJm
-(bytes) 21.0319 Tj
--246 TJm
-(tend) 17.1563 Tj
--245 TJm
-(to) 7.75121 Tj
--246 TJm
-(get) 12.1748 Tj
--246 TJm
-(lar) 10.511 Tj
-18 TJm
-(ger) 12.7228 Tj
-40 TJm
-(,) 2.49075 Tj
--246 TJm
-(since) 20.474 Tj
--246 TJm
-(the) 12.1748 Tj
--246 TJm
-(compression) 50.363 Tj
--245 TJm
-(mechanism) 45.3815 Tj
--246 TJm
-(has) 13.2807 Tj
--246 TJm
-(a) 4.42357 Tj
--246 TJm
-(c) 4.42357 Tj
-1 TJm
-(onstant) 28.7831 Tj
--246 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(erhead) 26.5514 Tj
--246 TJm
-(in) 7.75121 Tj
--246 TJm
-(th) 7.75121 Tj
-1 TJm
-(e) 4.42357 Tj
--246 TJm
-(re) 7.74125 Tj
-15 TJm
-(gion) 17.7142 Tj
--246 TJm
-(of) 8.29918 Tj
-[1 0 0 1 72 50.852] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.063 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -496.332 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.951 Td
-/F128_0 9.963 Tf
-(3) 4.9815 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 7 7
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 105.519 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(50) 9.963 Tj
--264 TJm
-(bytes.) 23.5226 Tj
--351 TJm
-(Random) 33.7646 Tj
--263 TJm
-(data) 16.5984 Tj
--264 TJm
-(\(including) 40.9579 Tj
--263 TJm
-(the) 12.1748 Tj
--264 TJm
-(output) 25.4654 Tj
--264 TJm
-(of) 8.29918 Tj
--263 TJm
-(most) 19.378 Tj
--264 TJm
-(\002le) 12.7327 Tj
--263 TJm
-(compressors\)) 53.1227 Tj
--264 TJm
-(is) 6.64532 Tj
--264 TJm
-(coded) 23.7916 Tj
--263 TJm
-(at) 7.19329 Tj
--264 TJm
-(about) 22.1378 Tj
--263 TJm
-(8.05) 17.4353 Tj
--264 TJm
-(bits) 14.3965 Tj
--264 TJm
-(per) 12.7228 Tj
--263 TJm
-(byte,) 19.647 Tj
--267 TJm
-(gi) 7.75121 Tj
-25 TJm
-(ving) 17.7142 Tj
--264 TJm
-(an) 9.40507 Tj
-72 698.082 Td
-(e) 4.42357 Tj
-15 TJm
-(xpansion) 35.9764 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(around) 27.6673 Tj
--250 TJm
-(0.5%.) 23.2437 Tj
-[1 0 0 1 72 695.925] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-[1 0 0 1 -72 -686.081] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 676.283 Td
-/F128_0 9.963 Tf
-(As) 11.0689 Tj
--268 TJm
-(a) 4.42357 Tj
--268 TJm
-(self-check) 40.938 Tj
--268 TJm
-(for) 11.6169 Tj
--269 TJm
-(yo) 9.963 Tj
-1 TJm
-(ur) 8.29918 Tj
--269 TJm
-(protection) 40.4 Tj
-1 TJm
-(,) 2.49075 Tj
-[1 0 0 1 217.273 676.283] cm
-0 g
-0 G
-[1 0 0 1 -217.273 -676.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-217.273 676.283 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 247.161 676.283] cm
-0 g
-0 G
-[1 0 0 1 -247.161 -676.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-249.833 676.283 Td
-/F128_0 9.963 Tf
-(uses) 17.1563 Tj
--268 TJm
-(32-bit) 23.8016 Tj
--268 TJm
-(CRCs) 23.8116 Tj
--268 TJm
-(to) 7.75121 Tj
--268 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--269 TJm
-(sure) 16.5984 Tj
--268 TJm
-(that) 14.9445 Tj
--268 TJm
-(the) 12.1748 Tj
--268 TJm
-(decompressed) 56.4404 Tj
--268 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--268 TJm
-(of) 8.29918 Tj
--268 TJm
-(a) 4.42357 Tj
--268 TJm
-(\002le) 12.7327 Tj
--269 TJm
-(is) 6.64532 Tj
-72 664.328 Td
-(identical) 34.3126 Tj
--199 TJm
-(to) 7.75121 Tj
--200 TJm
-(the) 12.1748 Tj
--199 TJm
-(original.) 33.4856 Tj
--587 TJm
-(This) 17.7142 Tj
--199 TJm
-(guards) 26.5614 Tj
--200 TJm
-(ag) 9.40507 Tj
-5 TJm
-(ainst) 18.8201 Tj
--199 TJm
-(corruption) 41.5059 Tj
--200 TJm
-(of) 8.29918 Tj
--199 TJm
-(the) 12.1748 Tj
--200 TJm
-(compre) 29.879 Tj
-1 TJm
-(ssed) 17.1563 Tj
--200 TJm
-(data,) 19.0891 Tj
--210 TJm
-(and) 14.3866 Tj
--199 TJm
-(ag) 9.40507 Tj
-5 TJm
-(ainst) 18.8201 Tj
--200 TJm
-(unde) 19.3681 Tj
-1 TJm
-(tected) 23.7916 Tj
--200 TJm
-(b) 4.9815 Tj
-20 TJm
-(ugs) 13.8386 Tj
--199 TJm
-(in) 7.75121 Tj
-[1 0 0 1 510.112 664.328] cm
-0 g
-0 G
-[1 0 0 1 -510.112 -664.328] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 664.328 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 540 664.328] cm
-0 g
-0 G
-[1 0 0 1 -540 -664.328] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 652.373 Td
-/F128_0 9.963 Tf
-(\(hopefully) 41.5059 Tj
--275 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-1 TJm
-(ry) 8.29918 Tj
--275 TJm
-(unlik) 20.4839 Tj
-10 TJm
-(ely\).) 17.9832 Tj
--384 TJm
-(The) 15.4925 Tj
--275 TJm
-(chances) 31.5329 Tj
--274 TJm
-(of) 8.29918 Tj
--275 TJm
-(data) 16.5984 Tj
--275 TJm
-(corr) 16.0404 Tj
-1 TJm
-(uption) 25.4654 Tj
--275 TJm
-(going) 22.6957 Tj
--275 TJm
-(undetected) 43.1597 Tj
--274 TJm
-(is) 6.64532 Tj
--275 TJm
-(microscopic,) 51.1899 Tj
--280 TJm
-(about) 22.1378 Tj
--275 TJm
-(one) 14.3866 Tj
--275 TJm
-(chance) 27.6573 Tj
--274 TJm
-(in) 7.75121 Tj
--275 TJm
-(four) 16.5984 Tj
-72 640.417 Td
-(billion) 26.0234 Tj
--279 TJm
-(for) 11.6169 Tj
--279 TJm
-(each) 18.2522 Tj
--279 TJm
-(\002le) 12.7327 Tj
--279 TJm
-(processed.) 41.7749 Tj
--795 TJm
-(Be) 11.0689 Tj
--279 TJm
-(a) 4.42357 Tj
-15 TJm
-(w) 7.19329 Tj
-10 TJm
-(are,) 14.6556 Tj
--287 TJm
-(thou) 17.7142 Tj
-1 TJm
-(gh,) 12.4538 Tj
--287 TJm
-(that) 14.9445 Tj
--279 TJm
-(the) 12.1748 Tj
--279 TJm
-(check) 23.2337 Tj
--279 TJm
-(occurs) 26.0034 Tj
--279 TJm
-(upon) 19.926 Tj
--279 TJm
-(decompression,) 62.2588 Tj
--286 TJm
-(so) 8.85711 Tj
--280 TJm
-(it) 5.53943 Tj
--279 TJm
-(can) 13.8286 Tj
--279 TJm
-(only) 17.7142 Tj
--279 TJm
-(tell) 12.7327 Tj
--279 TJm
-(you) 14.9445 Tj
-72 628.462 Td
-(that) 14.9445 Tj
--237 TJm
-(something) 41.5158 Tj
--236 TJm
-(is) 6.64532 Tj
--237 TJm
-(wrong.) 27.9462 Tj
--611 TJm
-(It) 6.08739 Tj
--237 TJm
-(can') 17.1463 Tj
-18 TJm
-(t) 2.76971 Tj
--236 TJm
-(help) 17.1563 Tj
--237 TJm
-(you) 14.9445 Tj
--237 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--236 TJm
-(the) 12.1748 Tj
--237 TJm
-(original) 30.9949 Tj
--237 TJm
-(uncompressed) 56.9983 Tj
--236 TJm
-(data.) 19.0891 Tj
--611 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--237 TJm
-(can) 13.8286 Tj
--237 TJm
-(use) 13.2807 Tj
-[1 0 0 1 458.159 628.462] cm
-0 g
-0 G
-[1 0 0 1 -458.159 -628.462] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-458.159 628.462 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 529.89 628.462] cm
-0 g
-0 G
-[1 0 0 1 -529.89 -628.462] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-532.249 628.462 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
-72 616.507 Td
-(try) 11.0689 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(from) 19.3681 Tj
--250 TJm
-(damag) 26.5614 Tj
-1 TJm
-(ed) 9.40507 Tj
--250 TJm
-(\002les.) 19.0991 Tj
-[1 0 0 1 72 614.35] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-[1 0 0 1 -72 -604.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 594.708 Td
-/F128_0 9.963 Tf
-(Return) 27.1193 Tj
--298 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
--406 TJm
-(0) 4.9815 Tj
--298 TJm
-(f) 3.31768 Tj
-1 TJm
-(or) 8.29918 Tj
--298 TJm
-(a) 4.42357 Tj
--298 TJm
-(normal) 28.2252 Tj
--298 TJm
-(e) 4.42357 Tj
-15 TJm
-(xit,) 13.0117 Tj
--310 TJm
-(1) 4.9815 Tj
--298 TJm
-(for) 11.6169 Tj
--298 TJm
-(en) 9.40507 Tj
-40 TJm
-(vironmental) 48.1512 Tj
--298 TJm
-(p) 4.9815 Tj
-1 TJm
-(roblems) 32.1008 Tj
--298 TJm
-(\(\002le) 16.0504 Tj
--298 TJm
-(not) 12.7327 Tj
--298 TJm
-(found,) 25.7344 Tj
--310 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-25 TJm
-(alid) 14.9445 Tj
--298 TJm
-(\003ags,) 21.3109 Tj
--310 TJm
-(I/O) 13.2807 Tj
--297 TJm
-(errors,) 25.7245 Tj
--310 TJm
-(etc.\),) 19.916 Tj
--310 TJm
-(2) 4.9815 Tj
--298 TJm
-(to) 7.75121 Tj
-72 582.753 Td
-(indicate) 31.5429 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(corrupt) 28.7731 Tj
--250 TJm
-(compresse) 42.0538 Tj
-1 TJm
-(d) 4.9815 Tj
--250 TJm
-(\002le,) 15.2235 Tj
--250 TJm
-(3) 4.9815 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(an) 9.40507 Tj
--250 TJm
-(internal) 30.437 Tj
--250 TJm
-(consistenc) 41.5059 Tj
-15 TJm
-(y) 4.9815 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(\(e) 7.74125 Tj
-15 TJm
-(g,) 7.47225 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug\)) 13.2807 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(ca) 8.84714 Tj
-1 TJm
-(used) 18.2622 Tj
-[1 0 0 1 443.065 582.753] cm
-0 g
-0 G
-[1 0 0 1 -443.065 -582.753] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-443.065 582.753 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 472.953 582.753] cm
-0 g
-0 G
-[1 0 0 1 -472.953 -582.753] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-475.444 582.753 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(panic.) 24.0706 Tj
-[1 0 0 1 72 580.596] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -570.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 548.118 Td
-/F121_0 20.659 Tf
-(2.4.) 34.4592 Tj
--278 TJm
-(OPTIONS) 92.9862 Tj
-[1 0 0 1 72 547.86] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -528.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 516.475 Td
-/F130_0 9.963 Tf
-(-c) 11.9556 Tj
--600 TJm
-(--stdout) 47.8224 Tj
-[1 0 0 1 137.753 516.475] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -68.244 -0.209] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -516.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 504.52 Td
-/F128_0 9.963 Tf
-(Compress) 39.852 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(decompress) 47.0353 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(s) 3.87561 Tj
-1 TJm
-(tandard) 29.879 Tj
--250 TJm
-(output.) 27.9562 Tj
-[1 0 0 1 72 502.363] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.866] cm
-0 g
-0 G
-[1 0 0 1 0 -9.845] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -488.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 478.854 Td
-/F130_0 9.963 Tf
-(-d) 11.9556 Tj
--600 TJm
-(--decompress) 71.7336 Tj
-[1 0 0 1 161.664 478.854] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -92.154 -1.564] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -477.29] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 466.899 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(orce) 17.1463 Tj
--296 TJm
-(decompression.) 62.2588 Tj
-[1 0 0 1 200.214 466.899] cm
-0 g
-0 G
-[1 0 0 1 -200.214 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.214 466.899 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 230.102 466.899] cm
-0 g
-0 G
-[1 0 0 1 -230.102 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.102 466.899 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 235.659 466.899] cm
-0 g
-0 G
-[1 0 0 1 -235.659 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.659 466.899 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 277.502 466.899] cm
-0 g
-0 G
-[1 0 0 1 -277.502 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-280.454 466.899 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 297.791 466.899] cm
-0 g
-0 G
-[1 0 0 1 -297.791 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.791 466.899 Td
-/F130_0 9.963 Tf
-(bzcat) 29.889 Tj
-[1 0 0 1 327.679 466.899] cm
-0 g
-0 G
-[1 0 0 1 -327.679 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.631 466.899 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
--296 TJm
-(really) 22.6858 Tj
--296 TJm
-(the) 12.1748 Tj
--296 TJm
-(same) 20.474 Tj
--297 TJm
-(program) 33.7546 Tj
-1 TJm
-(,) 2.49075 Tj
--308 TJm
-(and) 14.3866 Tj
--297 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--297 TJm
-(decision) 33.2067 Tj
--296 TJm
-(about) 22.1378 Tj
-108 454.944 Td
-(what) 19.3681 Tj
--303 TJm
-(actions) 28.2252 Tj
--303 TJm
-(to) 7.75121 Tj
--303 TJm
-(tak) 12.1748 Tj
-10 TJm
-(e) 4.42357 Tj
--303 TJm
-(is) 6.64532 Tj
--303 TJm
-(done) 19.3681 Tj
--303 TJm
-(on) 9.963 Tj
--303 TJm
-(the) 12.1748 Tj
--303 TJm
-(basis) 19.926 Tj
--303 TJm
-(of) 8.29918 Tj
--303 TJm
-(which) 24.3496 Tj
--303 TJm
-(name) 21.5799 Tj
--303 TJm
-(is) 6.64532 Tj
--303 TJm
-(used.) 20.7529 Tj
--939 TJm
-(T) 6.08739 Tj
-1 TJm
-(his) 11.6268 Tj
--304 TJm
-(\003) 5.53943 Tj
-1 TJm
-(ag) 9.40507 Tj
--304 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-1 TJm
-(rrides) 22.6858 Tj
--303 TJm
-(that) 14.9445 Tj
--303 TJm
-(mechanism,) 47.8722 Tj
--317 TJm
-(and) 14.3866 Tj
-108 442.989 Td
-(forces) 24.3396 Tj
--250 TJm
-(bzip2) 22.1378 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(decompress.) 49.5261 Tj
-[1 0 0 1 72 440.832] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.867] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -427.121] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 417.323 Td
-/F130_0 9.963 Tf
-(-z) 11.9556 Tj
--600 TJm
-(--compress) 59.778 Tj
-[1 0 0 1 149.709 417.323] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -80.199 -1.564] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -415.759] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 405.368 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--250 TJm
-(complement) 49.2571 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 187.969 405.368] cm
-0 g
-0 G
-[1 0 0 1 -187.969 -405.368] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-187.969 405.368 Td
-/F130_0 9.963 Tf
-(-d) 11.9556 Tj
-[1 0 0 1 199.924 405.368] cm
-0 g
-0 G
-[1 0 0 1 -199.924 -405.368] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.924 405.368 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
--310 TJm
-(forces) 24.3396 Tj
--250 TJm
-(compression,) 52.8537 Tj
--250 TJm
-(re) 7.74125 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(ardles) 23.7916 Tj
-1 TJm
-(s) 3.87561 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-20 TJm
-(okation) 29.889 Tj
--250 TJm
-(name.) 24.0706 Tj
-[1 0 0 1 72 403.211] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.867] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -389.5] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 379.702 Td
-/F130_0 9.963 Tf
-(-t) 11.9556 Tj
--600 TJm
-(--test) 35.8668 Tj
-[1 0 0 1 125.798 379.702] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -56.289 -0.209] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -379.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 367.747 Td
-/F128_0 9.963 Tf
-(Check) 25.4555 Tj
--270 TJm
-(inte) 14.9445 Tj
-15 TJm
-(grity) 18.8201 Tj
--271 TJm
-(of) 8.29918 Tj
--270 TJm
-(the) 12.1748 Tj
--270 TJm
-(speci\002ed) 35.4185 Tj
--271 TJm
-(\002) 5.53943 Tj
-1 TJm
-(le\(s\),) 20.195 Tj
--276 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--270 TJm
-(don') 18.2622 Tj
-18 TJm
-(t) 2.76971 Tj
--271 TJm
-(decom) 26.5614 Tj
-1 TJm
-(press) 20.474 Tj
--271 TJm
-(them.) 22.4168 Tj
--742 TJm
-(This) 17.7142 Tj
--270 TJm
-(really) 22.6858 Tj
--271 TJm
-(performs) 35.9664 Tj
--270 TJm
-(a) 4.42357 Tj
--270 TJm
-(trial) 16.0504 Tj
--271 TJm
-(decompres-) 46.4774 Tj
-108 355.792 Td
-(sion) 16.6083 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(thro) 16.0504 Tj
-25 TJm
-(ws) 11.0689 Tj
--250 TJm
-(a) 4.42357 Tj
-15 TJm
-(w) 7.19329 Tj
-10 TJm
-(ay) 9.40507 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(resul) 19.3681 Tj
-1 TJm
-(t.) 5.26046 Tj
-[1 0 0 1 72 353.635] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.867] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -339.924] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 330.126 Td
-/F130_0 9.963 Tf
-(-f) 11.9556 Tj
--600 TJm
-(--force) 41.8446 Tj
-[1 0 0 1 131.776 330.126] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -62.266 -0.209] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -329.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 318.171 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(orce) 17.1463 Tj
--338 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(erwrite) 28.2152 Tj
--338 TJm
-(of) 8.29918 Tj
--339 TJm
-(output) 25.4654 Tj
--338 TJm
-(\002les.) 19.0991 Tj
--1149 TJm
-(Normally) 38.1882 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 289.831 318.171] cm
-0 g
-0 G
-[1 0 0 1 -289.831 -318.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.831 318.171 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 319.719 318.171] cm
-0 g
-0 G
-[1 0 0 1 -319.719 -318.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-323.089 318.171 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--338 TJm
-(not) 12.7327 Tj
--338 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(erwrite) 28.2152 Tj
--339 TJm
-(e) 4.42357 Tj
-15 TJm
-(xisti) 17.1662 Tj
-1 TJm
-(ng) 9.963 Tj
--339 TJm
-(output) 25.4654 Tj
--338 TJm
-(\002les.) 19.0991 Tj
--1150 TJm
-(Also) 18.8201 Tj
--338 TJm
-(forces) 24.3396 Tj
-[1 0 0 1 108 306.216] cm
-0 g
-0 G
-[1 0 0 1 -108 -306.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 306.216 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 137.888 306.216] cm
-0 g
-0 G
-[1 0 0 1 -137.888 -306.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.379 306.216 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(break) 22.1278 Tj
--250 TJm
-(hard) 17.7043 Tj
--250 TJm
-(links) 19.378 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(\002les) 16.6083 Tj
-1 TJm
-(,) 2.49075 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(otherwise) 38.7361 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ouldn') 26.0134 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(do.) 12.4538 Tj
-[1 0 0 1 72 304.652] cm
-0 g
-0 G
-[1 0 0 1 0 -9.845] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -294.807] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 284.416 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 137.888 284.416] cm
-0 g
-0 G
-[1 0 0 1 -137.888 -284.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-141.211 284.416 Td
-/F128_0 9.963 Tf
-(normally) 35.9764 Tj
--333 TJm
-(declines) 32.6488 Tj
--334 TJm
-(to) 7.75121 Tj
--333 TJm
-(decompress) 47.0353 Tj
--334 TJm
-(\002les) 16.6083 Tj
--333 TJm
-(which) 24.3496 Tj
--333 TJm
-(don') 18.2622 Tj
-18 TJm
-(t) 2.76971 Tj
--334 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--333 TJm
-(the) 12.1748 Tj
--334 TJm
-(correct) 27.6573 Tj
--333 TJm
-(magic) 24.3496 Tj
--334 TJm
-(header) 26.5514 Tj
--333 TJm
-(bytes.) 23.5226 Tj
--561 TJm
-(If) 6.63536 Tj
--333 TJm
-(forced) 25.4455 Tj
-108 272.461 Td
-(\() 3.31768 Tj
-[1 0 0 1 111.317 272.461] cm
-0 g
-0 G
-[1 0 0 1 -111.317 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-111.317 272.461 Td
-/F130_0 9.963 Tf
-(-f) 11.9556 Tj
-[1 0 0 1 123.273 272.461] cm
-0 g
-0 G
-[1 0 0 1 -123.273 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.273 272.461 Td
-/F128_0 9.963 Tf
-(\),) 5.80843 Tj
--250 TJm
-(ho) 9.963 Tj
-25 TJm
-(we) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
-40 TJm
-(,) 2.49075 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(will) 15.5024 Tj
--250 TJm
-(pass) 17.1563 Tj
--250 TJm
-(such) 18.2622 Tj
--249 TJm
-(\002les) 16.6083 Tj
--250 TJm
-(through) 30.9949 Tj
--250 TJm
-(unmodi\002ed.) 47.8822 Tj
--310 TJm
-(This) 17.7142 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(GNU) 21.5799 Tj
-[1 0 0 1 412.585 272.461] cm
-0 g
-0 G
-[1 0 0 1 -412.585 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-412.585 272.461 Td
-/F130_0 9.963 Tf
-(gzip) 23.9112 Tj
-[1 0 0 1 436.496 272.461] cm
-0 g
-0 G
-[1 0 0 1 -436.496 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.986 272.461 Td
-/F128_0 9.963 Tf
-(beha) 18.8101 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(es.) 10.7899 Tj
-[1 0 0 1 72 270.304] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.866] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -256.594] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 246.795 Td
-/F130_0 9.963 Tf
-(-k) 11.9556 Tj
--600 TJm
-(--keep) 35.8668 Tj
-[1 0 0 1 125.798 246.795] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -56.289 -1.564] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -245.231] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 234.84 Td
-/F128_0 9.963 Tf
-(K) 7.19329 Tj
-25 TJm
-(eep) 13.8286 Tj
--250 TJm
-(\(don') 21.5799 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(delete\)) 27.1093 Tj
--250 TJm
-(input) 20.4839 Tj
--250 TJm
-(\002le) 12.7327 Tj
-1 TJm
-(s) 3.87561 Tj
--250 TJm
-(during) 26.0134 Tj
--250 TJm
-(compression) 50.363 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(decompression.) 62.2588 Tj
-[1 0 0 1 72 232.683] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.866] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -218.973] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 209.175 Td
-/F130_0 9.963 Tf
-(-s) 11.9556 Tj
--600 TJm
-(--small) 41.8446 Tj
-[1 0 0 1 131.776 209.175] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -62.266 -0.21] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -208.965] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 197.219 Td
-/F128_0 9.963 Tf
-(Reduce) 29.879 Tj
--347 TJm
-(memory) 33.2067 Tj
--346 TJm
-(usage,) 25.1765 Tj
--371 TJm
-(for) 11.6169 Tj
--347 TJm
-(compression,) 52.8537 Tj
--371 TJm
-(decompression) 59.768 Tj
--346 TJm
-(and) 14.3866 Tj
--347 TJm
-(testing.) 29.0621 Tj
--1201 TJm
-(Files) 19.378 Tj
--347 TJm
-(are) 12.1648 Tj
--346 TJm
-(decompressed) 56.4404 Tj
--347 TJm
-(and) 14.3866 Tj
--347 TJm
-(tested) 23.2437 Tj
-108 185.264 Td
-(using) 21.5898 Tj
--388 TJm
-(a) 4.42357 Tj
--388 TJm
-(modi\002ed) 35.4284 Tj
--388 TJm
-(algorithm) 38.7461 Tj
--388 TJm
-(which) 24.3496 Tj
--388 TJm
-(only) 17.7142 Tj
--388 TJm
-(requires) 32.0908 Tj
--388 TJm
-(2.5) 12.4538 Tj
--388 TJm
-(bytes) 21.0319 Tj
--388 TJm
-(per) 12.7228 Tj
--388 TJm
-(block) 22.1378 Tj
--388 TJm
-(byte.) 19.647 Tj
--1449 TJm
-(This) 17.7142 Tj
--388 TJm
-(means) 25.4555 Tj
--388 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--388 TJm
-(\002le) 12.7327 Tj
--388 TJm
-(can) 13.8286 Tj
--389 TJm
-(be) 9.40507 Tj
-108 173.309 Td
-(decompressed) 56.4404 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(2300k) 24.9075 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(mem) 19.926 Tj
-1 TJm
-(ory) 13.2807 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(albeit) 22.1378 Tj
--250 TJm
-(at) 7.19329 Tj
--250 TJm
-(about) 22.1378 Tj
--250 TJm
-(half) 15.4925 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(normal) 28.2252 Tj
--250 TJm
-(speed.) 25.1765 Tj
-[1 0 0 1 72 171.152] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-[1 0 0 1 -72 -161.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 151.51 Td
-/F128_0 9.963 Tf
-(During) 28.2252 Tj
--251 TJm
-(compression,) 52.8537 Tj
-[1 0 0 1 194.09 151.51] cm
-0 g
-0 G
-[1 0 0 1 -194.09 -151.51] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.09 151.51 Td
-/F130_0 9.963 Tf
-(-s) 11.9556 Tj
-[1 0 0 1 206.046 151.51] cm
-0 g
-0 G
-[1 0 0 1 -206.046 -151.51] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.551 151.51 Td
-/F128_0 9.963 Tf
-(selects) 26.5614 Tj
--251 TJm
-(a) 4.42357 Tj
--252 TJm
-(block) 22.1378 Tj
--251 TJm
-(size) 15.4925 Tj
--252 TJm
-(of) 8.29918 Tj
--251 TJm
-(200k,) 22.4168 Tj
--252 TJm
-(which) 24.3496 Tj
--251 TJm
-(limits) 22.7057 Tj
--252 TJm
-(memory) 33.2067 Tj
--251 TJm
-(use) 13.2807 Tj
--252 TJm
-(to) 7.75121 Tj
--251 TJm
-(around) 27.6673 Tj
--251 TJm
-(the) 12.1748 Tj
--252 TJm
-(same) 20.474 Tj
--251 TJm
-(\002gure,) 25.7344 Tj
--252 TJm
-(at) 7.19329 Tj
-108 139.555 Td
-(the) 12.1748 Tj
--287 TJm
-(e) 4.42357 Tj
-15 TJm
-(xpense) 27.6673 Tj
--287 TJm
-(of) 8.29918 Tj
--287 TJm
-(your) 18.2622 Tj
--287 TJm
-(compression) 50.363 Tj
--287 TJm
-(ratio.) 20.7529 Tj
--843 TJm
-(In) 8.29918 Tj
--287 TJm
-(short,) 22.4168 Tj
--297 TJm
-(if) 6.08739 Tj
--287 TJm
-(your) 18.2622 Tj
--287 TJm
-(machine) 33.7546 Tj
--287 TJm
-(is) 6.64532 Tj
--287 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w) 7.19329 Tj
--287 TJm
-(on) 9.963 Tj
--287 TJm
-(memory) 33.2067 Tj
--287 TJm
-(\(8) 8.29918 Tj
--288 TJm
-(m) 7.75121 Tj
-1 TJm
-(e) 4.42357 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(abytes) 25.4555 Tj
--288 TJm
-(or) 8.29918 Tj
--287 TJm
-(less\),) 20.7529 Tj
-108 127.599 Td
-(use) 13.2807 Tj
-[1 0 0 1 123.771 127.599] cm
-0 g
-0 G
-[1 0 0 1 -123.771 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.771 127.599 Td
-/F130_0 9.963 Tf
-(-s) 11.9556 Tj
-[1 0 0 1 135.726 127.599] cm
-0 g
-0 G
-[1 0 0 1 -135.726 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.217 127.599 Td
-/F128_0 9.963 Tf
-(for) 11.6169 Tj
--250 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(erything.) 35.6974 Tj
--620 TJm
-(See) 14.3866 Tj
-[1 0 0 1 220.079 127.599] cm
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -220.079 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.079 127.599 Td
-/F128_0 9.963 Tf
-(MEMOR) 37.6402 Tj
-65 TJm
-(Y) 7.19329 Tj
--250 TJm
-(MAN) 23.2437 Tj
-35 TJm
-(A) 7.19329 Tj
-40 TJm
-(GEMENT) 41.5059 Tj
-[1 0 0 1 337.946 127.599] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -337.946 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-340.437 127.599 Td
-/F128_0 9.963 Tf
-([5]) 11.6169 Tj
-[1 0 0 1 352.053 127.599] cm
-0 0 1 rg
-0 0 1 RG
-0 g
-0 G
-[1 0 0 1 -352.053 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-354.544 127.599 Td
-/F128_0 9.963 Tf
-(belo) 17.1563 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 125.443] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.867] cm
-0 g
-0 G
-[1 0 0 1 0 -9.844] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -111.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 101.934 Td
-/F130_0 9.963 Tf
-(-q) 11.9556 Tj
--600 TJm
-(--quiet) 41.8446 Tj
-[1 0 0 1 131.776 101.934] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -62.266 -1.564] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -100.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 89.979 Td
-/F128_0 9.963 Tf
-(Suppress) 35.9764 Tj
--221 TJm
-(non-) 18.2622 Tj
-1 TJm
-(essential) 34.3126 Tj
--221 TJm
-(w) 7.19329 Tj
-10 TJm
-(arning) 25.4555 Tj
--221 TJm
-(mess) 19.926 Tj
-1 TJm
-(ages.) 20.195 Tj
--301 TJm
-(Messa) 25.4555 Tj
-1 TJm
-(ges) 13.2807 Tj
--221 TJm
-(pertaining) 40.4 Tj
--221 TJm
-(to) 7.75121 Tj
--220 TJm
-(I/O) 13.2807 Tj
--221 TJm
-(errors) 23.2337 Tj
--221 TJm
-(and) 14.3866 Tj
--220 TJm
-(other) 20.474 Tj
--221 TJm
-(critical) 27.6673 Tj
--220 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ents) 16.0504 Tj
--221 TJm
-(will) 15.5024 Tj
--221 TJm
-(not) 12.7327 Tj
-108 78.023 Td
-(be) 9.40507 Tj
--250 TJm
-(suppressed.) 46.2084 Tj
-[1 0 0 1 72 75.867] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.867] cm
-0 g
-0 G
-[1 0 0 1 0 -21.148] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.063 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -496.332 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.852 Td
-/F128_0 9.963 Tf
-(4) 4.9815 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 8 8
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 105.519 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.963 Tf
-(-v) 11.9556 Tj
--600 TJm
-(--verbose) 53.8002 Tj
-[1 0 0 1 143.731 710.037] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -74.222 -0.209] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -709.828] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 698.082 Td
-/F128_0 9.963 Tf
-(V) 7.19329 Tj
-111 TJm
-(erbose) 26.0034 Tj
--322 TJm
-(mode) 22.1378 Tj
--323 TJm
-(--) 6.63536 Tj
--323 TJm
-(sho) 13.8386 Tj
-25 TJm
-(w) 7.19329 Tj
--322 TJm
-(the) 12.1748 Tj
--323 TJm
-(compres) 33.7546 Tj
-1 TJm
-(sion) 16.6083 Tj
--323 TJm
-(ratio) 18.2622 Tj
--323 TJm
-(for) 11.6169 Tj
--322 TJm
-(each) 18.2522 Tj
--323 TJm
-(\002le) 12.7327 Tj
--322 TJm
-(processed.) 41.7749 Tj
--1056 TJm
-(Further) 29.3311 Tj
-[1 0 0 1 430.015 698.082] cm
-0 g
-0 G
-[1 0 0 1 -430.015 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-430.015 698.082 Td
-/F130_0 9.963 Tf
-(-v) 11.9556 Tj
-[1 0 0 1 441.97 698.082] cm
-0 g
-0 G
-[1 0 0 1 -441.97 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.97 698.082 Td
-/F128_0 9.963 Tf
-(') 3.31768 Tj
-55 TJm
-(s) 3.87561 Tj
--323 TJm
-(incre) 19.916 Tj
-1 TJm
-(ase) 12.7228 Tj
--323 TJm
-(the) 12.1748 Tj
--323 TJm
-(v) 4.9815 Tj
-15 TJm
-(erbos) 21.5799 Tj
-1 TJm
-(ity) 10.5209 Tj
-108 686.127 Td
-(le) 7.19329 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el,) 9.68404 Tj
--250 TJm
-(spe) 13.2807 Tj
-25 TJm
-(wing) 19.926 Tj
--250 TJm
-(out) 12.7327 Tj
--250 TJm
-(lots) 14.3965 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(info) 16.0504 Tj
-1 TJm
-(rmation) 30.9949 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(primarily) 37.0823 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(interest) 29.3311 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(diagnostic) 40.9579 Tj
--250 TJm
-(pu) 9.963 Tj
-1 TJm
-(rposes.) 27.9462 Tj
-[1 0 0 1 72 683.97] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -670.023] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 660.224 Td
-/F130_0 9.963 Tf
-(-L) 11.9556 Tj
--600 TJm
-(--license) 53.8002 Tj
--600 TJm
-(-V) 11.9556 Tj
--600 TJm
-(--version) 53.8002 Tj
-[1 0 0 1 221.44 660.224] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -151.93 -0.209] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -660.015] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 648.269 Td
-/F128_0 9.963 Tf
-(Display) 30.9949 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(softw) 22.1378 Tj
-10 TJm
-(are) 12.1648 Tj
--250 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
-1 TJm
-(,) 2.49075 Tj
--250 TJm
-(license) 27.6673 Tj
--250 TJm
-(terms) 22.1378 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(conditions.) 44.0066 Tj
-[1 0 0 1 72 646.112] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -632.165] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 622.366 Td
-/F130_0 9.963 Tf
-(-1) 11.9556 Tj
-[1 0 0 1 83.955 622.366] cm
-0 g
-0 G
-[1 0 0 1 -83.955 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.446 622.366 Td
-/F128_0 9.963 Tf
-(\(or) 11.6169 Tj
-[1 0 0 1 100.553 622.366] cm
-0 g
-0 G
-[1 0 0 1 -100.553 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-100.553 622.366 Td
-/F130_0 9.963 Tf
-(--fast) 35.8668 Tj
-[1 0 0 1 136.418 622.366] cm
-0 g
-0 G
-[1 0 0 1 -136.418 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-136.418 622.366 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 152.468 622.366] cm
-0 g
-0 G
-[1 0 0 1 -152.468 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.468 622.366 Td
-/F130_0 9.963 Tf
-(-9) 11.9556 Tj
-[1 0 0 1 164.423 622.366] cm
-0 g
-0 G
-[1 0 0 1 -164.423 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.914 622.366 Td
-/F128_0 9.963 Tf
-(\(or) 11.6169 Tj
-[1 0 0 1 181.021 622.366] cm
-0 g
-0 G
-[1 0 0 1 -181.021 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.021 622.366 Td
-/F130_0 9.963 Tf
-(-best) 29.889 Tj
-[1 0 0 1 210.909 622.366] cm
-0 g
-0 G
-[1 0 0 1 -210.909 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.909 622.366 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
-[1 0 0 1 214.226 622.366] cm
-0 g
-0 G
-[1 0 0 1 -142.226 -1.783] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -620.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 610.411 Td
-/F128_0 9.963 Tf
-(Set) 12.7327 Tj
--288 TJm
-(the) 12.1748 Tj
--288 TJm
-(block) 22.1378 Tj
--289 TJm
-(size) 15.4925 Tj
--288 TJm
-(to) 7.75121 Tj
--288 TJm
-(100) 14.9445 Tj
--288 TJm
-(k,) 7.47225 Tj
--298 TJm
-(200) 14.9445 Tj
--288 TJm
-(k) 4.9815 Tj
--289 TJm
-(...) 7.47225 Tj
--849 TJm
-(900) 14.9445 Tj
--288 TJm
-(k) 4.9815 Tj
--289 TJm
-(when) 21.5799 Tj
--288 TJm
-(compressing.) 52.8537 Tj
--849 TJm
-(Has) 15.4925 Tj
--289 TJm
-(no) 9.963 Tj
--288 TJm
-(ef) 7.74125 Tj
-25 TJm
-(fect) 14.9345 Tj
--288 TJm
-(when) 21.5799 Tj
--288 TJm
-(decompressing.) 62.2588 Tj
--850 TJm
-(See) 14.3866 Tj
-[1 0 0 1 108 598.456] cm
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -108 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 598.456 Td
-/F128_0 9.963 Tf
-(MEMOR) 37.6402 Tj
-65 TJm
-(Y) 7.19329 Tj
--297 TJm
-(MAN) 23.2437 Tj
-35 TJm
-(A) 7.19329 Tj
-40 TJm
-(GEMENT) 41.5059 Tj
-[1 0 0 1 226.338 598.456] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -226.338 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.3 598.456 Td
-/F128_0 9.963 Tf
-([5]) 11.6169 Tj
-[1 0 0 1 240.916 598.456] cm
-0 0 1 rg
-0 0 1 RG
-0 g
-0 G
-[1 0 0 1 -240.916 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.878 598.456 Td
-/F128_0 9.963 Tf
-(belo) 17.1563 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(.) 2.49075 Tj
--904 TJm
-(The) 15.4925 Tj
-[1 0 0 1 297.278 598.456] cm
-0 g
-0 G
-[1 0 0 1 -297.278 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.278 598.456 Td
-/F130_0 9.963 Tf
-(--fast) 35.8668 Tj
-[1 0 0 1 333.144 598.456] cm
-0 g
-0 G
-[1 0 0 1 -333.144 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-336.106 598.456 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 353.454 598.456] cm
-0 g
-0 G
-[1 0 0 1 -353.454 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.454 598.456 Td
-/F130_0 9.963 Tf
-(--best) 35.8668 Tj
-[1 0 0 1 389.319 598.456] cm
-0 g
-0 G
-[1 0 0 1 -389.319 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.281 598.456 Td
-/F128_0 9.963 Tf
-(aliases) 26.5614 Tj
--297 TJm
-(are) 12.1648 Tj
--297 TJm
-(primarily) 37.0823 Tj
--297 TJm
-(for) 11.6169 Tj
--298 TJm
-(GNU) 21.5799 Tj
-[1 0 0 1 516.09 598.456] cm
-0 g
-0 G
-[1 0 0 1 -516.09 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.09 598.456 Td
-/F130_0 9.963 Tf
-(gzip) 23.9112 Tj
-[1 0 0 1 540 598.456] cm
-0 g
-0 G
-[1 0 0 1 -540 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 586.501 Td
-/F128_0 9.963 Tf
-(compatibility) 53.1426 Tj
-65 TJm
-(.) 2.49075 Tj
--356 TJm
-(In) 8.29918 Tj
--265 TJm
-(particular) 38.1782 Tj
-40 TJm
-(,) 2.49075 Tj
-[1 0 0 1 220.423 586.501] cm
-0 g
-0 G
-[1 0 0 1 -220.423 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.423 586.501 Td
-/F130_0 9.963 Tf
-(--fast) 35.8668 Tj
-[1 0 0 1 256.288 586.501] cm
-0 g
-0 G
-[1 0 0 1 -256.288 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.932 586.501 Td
-/F128_0 9.963 Tf
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--265 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--265 TJm
-(things) 24.3595 Tj
--266 TJm
-(signi\002can) 38.7461 Tj
-1 TJm
-(tly) 10.5209 Tj
--266 TJm
-(f) 3.31768 Tj
-10 TJm
-(aster) 18.8101 Tj
-55 TJm
-(.) 2.49075 Tj
--712 TJm
-(And) 17.1563 Tj
-[1 0 0 1 444.622 586.501] cm
-0 g
-0 G
-[1 0 0 1 -444.622 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-444.622 586.501 Td
-/F130_0 9.963 Tf
-(--best) 35.8668 Tj
-[1 0 0 1 480.487 586.501] cm
-0 g
-0 G
-[1 0 0 1 -480.487 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-483.131 586.501 Td
-/F128_0 9.963 Tf
-(merely) 27.6673 Tj
--265 TJm
-(selects) 26.5614 Tj
-108 574.546 Td
-(the) 12.1748 Tj
--250 TJm
-(def) 12.7228 Tj
-10 TJm
-(ault) 14.9445 Tj
--250 TJm
-(beha) 18.8101 Tj
-20 TJm
-(viour) 21.0319 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 574.446] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -560.498] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 548.643 Td
-/F130_0 9.963 Tf
-(--) 11.9556 Tj
-[1 0 0 1 83.955 548.643] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -14.446 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -548.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 536.688 Td
-/F128_0 9.963 Tf
-(T) 6.08739 Tj
-35 TJm
-(reats) 18.8101 Tj
--261 TJm
-(all) 9.963 Tj
--260 TJm
-(subsequent) 44.2756 Tj
--261 TJm
-(ar) 7.74125 Tj
-18 TJm
-(guments) 33.7646 Tj
--261 TJm
-(as) 8.29918 Tj
--260 TJm
-(\002le) 12.7327 Tj
--261 TJm
-(names,) 27.9462 Tj
--263 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--261 TJm
-(if) 6.08739 Tj
--261 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--261 TJm
-(sta) 11.0689 Tj
-1 TJm
-(rt) 6.08739 Tj
--261 TJm
-(with) 17.7142 Tj
--261 TJm
-(a) 4.42357 Tj
--261 TJm
-(dash.) 20.7529 Tj
--684 TJm
-(This) 17.7142 Tj
--261 TJm
-(is) 6.64532 Tj
--261 TJm
-(so) 8.85711 Tj
--261 TJm
-(yo) 9.963 Tj
-1 TJm
-(u) 4.9815 Tj
--261 TJm
-(can) 13.8286 Tj
--261 TJm
-(handle) 26.5614 Tj
--261 TJm
-(\002les) 16.6083 Tj
-108 524.732 Td
-(with) 17.7142 Tj
--250 TJm
-(names) 25.4555 Tj
--250 TJm
-(be) 9.40507 Tj
-15 TJm
-(ginning) 30.4469 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(a) 4.42357 Tj
--249 TJm
-(dash,) 20.7529 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(e) 4.42357 Tj
-15 TJm
-(xample:) 32.1008 Tj
-[1 0 0 1 302.27 524.732] cm
-0 g
-0 G
-[1 0 0 1 -302.27 -524.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.27 524.732 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
--600 TJm
-(--) 11.9556 Tj
--600 TJm
-(-myfilename) 65.7558 Tj
-[1 0 0 1 421.821 524.732] cm
-0 g
-0 G
-[1 0 0 1 -421.821 -524.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-421.821 524.732 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 522.576] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -508.628] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 498.83 Td
-/F130_0 9.963 Tf
-(--repetitive-fast) 101.623 Tj
-[1 0 0 1 173.619 498.83] cm
-0 g
-0 G
-[1 0 0 1 -173.619 -498.83] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.619 498.83 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 178.6 498.83] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -181.091 -498.83] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.091 498.83 Td
-/F130_0 9.963 Tf
-(--repetitive-best) 101.623 Tj
-[1 0 0 1 282.71 498.83] cm
-0 g
-0 G
-[1 0 0 1 -282.71 -498.83] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.71 498.83 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 287.691 498.83] cm
-0 g
-0 G
-[1 0 0 1 -215.691 -1.564] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -497.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 486.874 Td
-/F128_0 9.963 Tf
-(These) 23.7916 Tj
--207 TJm
-(\003ags) 18.8201 Tj
--206 TJm
-(are) 12.1648 Tj
--207 TJm
-(redundant) 39.842 Tj
--206 TJm
-(in) 7.75121 Tj
--207 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--206 TJm
-(0.9.5) 19.926 Tj
--207 TJm
-(and) 14.3866 Tj
--207 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e.) 6.91432 Tj
--591 TJm
-(The) 15.4925 Tj
-15 TJm
-(y) 4.9815 Tj
--206 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vided) 22.1378 Tj
--207 TJm
-(some) 21.0319 Tj
--206 TJm
-(coarse) 25.4455 Tj
--207 TJm
-(control) 28.2252 Tj
--206 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--207 TJm
-(the) 12.1748 Tj
--207 TJm
-(beha) 18.8101 Tj
-20 TJm
-(viour) 21.0319 Tj
-108 474.919 Td
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--251 TJm
-(sorti) 17.7142 Tj
-1 TJm
-(ng) 9.963 Tj
--251 TJm
-(algorithm) 38.7461 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(earlier) 25.4455 Tj
--250 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions,) 30.7159 Tj
--251 TJm
-(which) 24.3496 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--250 TJm
-(sometimes) 42.6217 Tj
--250 TJm
-(useful.) 26.8403 Tj
--622 TJm
-(0.9.5) 19.926 Tj
--251 TJm
-(and) 14.3866 Tj
--250 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(an) 9.40507 Tj
--251 TJm
-(impro) 23.8016 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(ed) 9.40507 Tj
-108 462.964 Td
-(algorithm) 38.7461 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(renders) 29.3211 Tj
--250 TJm
-(thes) 16.0504 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(\003ags) 18.8201 Tj
--250 TJm
-(irrele) 21.0219 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ant.) 14.6655 Tj
-[1 0 0 1 72 460.807] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -436.897] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 414.264 Td
-/F121_0 20.659 Tf
-(2.5.) 34.4592 Tj
--278 TJm
-(MEMOR) 79.1859 Tj
-50 TJm
-(Y) 13.7796 Tj
--278 TJm
-(MANA) 61.9563 Tj
-50 TJm
-(GEMENT) 88.3792 Tj
-[1 0 0 1 72 414.006] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -404.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 392.346 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 392.346] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -392.346] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.454 392.346 Td
-/F128_0 9.963 Tf
-(compresses) 45.9294 Tj
--257 TJm
-(lar) 10.511 Tj
-18 TJm
-(ge) 9.40507 Tj
--258 TJm
-(\002les) 16.6083 Tj
--257 TJm
-(in) 7.75121 Tj
--258 TJm
-(blocks.) 28.5041 Tj
--665 TJm
-(The) 15.4925 Tj
--258 TJm
-(block) 22.1378 Tj
--257 TJm
-(size) 15.4925 Tj
--258 TJm
-(af) 7.74125 Tj
-25 TJm
-(fects) 18.8101 Tj
--257 TJm
-(both) 17.7142 Tj
--258 TJm
-(the) 12.1748 Tj
--257 TJm
-(compression) 50.363 Tj
--258 TJm
-(ratio) 18.2622 Tj
--257 TJm
-(achie) 21.0219 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ed,) 11.8958 Tj
--260 TJm
-(an) 9.40507 Tj
-1 TJm
-(d) 4.9815 Tj
--258 TJm
-(the) 12.1748 Tj
--258 TJm
-(amoun) 27.1193 Tj
-1 TJm
-(t) 2.76971 Tj
-72 380.391 Td
-(of) 8.29918 Tj
--215 TJm
-(memory) 33.2067 Tj
--215 TJm
-(needed) 28.2152 Tj
--214 TJm
-(for) 11.6169 Tj
--215 TJm
-(compression) 50.363 Tj
--215 TJm
-(and) 14.3866 Tj
--215 TJm
-(decompressi) 49.805 Tj
-1 TJm
-(on.) 12.4538 Tj
--597 TJm
-(The) 15.4925 Tj
--215 TJm
-(\003ags) 18.8201 Tj
-[1 0 0 1 337.719 380.391] cm
-0 g
-0 G
-[1 0 0 1 -337.719 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-337.719 380.391 Td
-/F130_0 9.963 Tf
-(-1) 11.9556 Tj
-[1 0 0 1 349.674 380.391] cm
-0 g
-0 G
-[1 0 0 1 -349.674 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-351.815 380.391 Td
-/F128_0 9.963 Tf
-(through) 30.9949 Tj
-[1 0 0 1 384.95 380.391] cm
-0 g
-0 G
-[1 0 0 1 -384.95 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.95 380.391 Td
-/F130_0 9.963 Tf
-(-9) 11.9556 Tj
-[1 0 0 1 396.905 380.391] cm
-0 g
-0 G
-[1 0 0 1 -396.905 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-399.046 380.391 Td
-/F128_0 9.963 Tf
-(specify) 28.7731 Tj
--215 TJm
-(the) 12.1748 Tj
--215 TJm
-(block) 22.1378 Tj
--214 TJm
-(size) 15.4925 Tj
--215 TJm
-(to) 7.75121 Tj
--215 TJm
-(be) 9.40507 Tj
--215 TJm
-(100,000) 32.3798 Tj
-72 368.435 Td
-(bytes) 21.0319 Tj
--278 TJm
-(throug) 26.0134 Tj
-1 TJm
-(h) 4.9815 Tj
--278 TJm
-(900,000) 32.3798 Tj
--278 TJm
-(bytes) 21.0319 Tj
--277 TJm
-(\(the) 15.4925 Tj
--278 TJm
-(def) 12.7228 Tj
-10 TJm
-(ault\)) 18.2622 Tj
--278 TJm
-(r) 3.31768 Tj
-1 TJm
-(especti) 27.6673 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ely) 12.1748 Tj
-65 TJm
-(.) 2.49075 Tj
--786 TJm
-(At) 9.963 Tj
--278 TJm
-(decompression) 59.768 Tj
--278 TJm
-(tim) 13.2906 Tj
-1 TJm
-(e,) 6.91432 Tj
--285 TJm
-(the) 12.1748 Tj
--278 TJm
-(block) 22.1378 Tj
--277 TJm
-(size) 15.4925 Tj
--278 TJm
-(used) 18.2622 Tj
--278 TJm
-(f) 3.31768 Tj
-1 TJm
-(or) 8.29918 Tj
--278 TJm
-(compression) 50.363 Tj
-72 356.48 Td
-(is) 6.64532 Tj
--242 TJm
-(read) 17.1463 Tj
--243 TJm
-(from) 19.3681 Tj
--242 TJm
-(the) 12.1748 Tj
--243 TJm
-(header) 26.5514 Tj
--242 TJm
-(of) 8.29918 Tj
--243 TJm
-(the) 12.1748 Tj
--242 TJm
-(compressed) 47.0353 Tj
--242 TJm
-(\002le,) 15.2235 Tj
--244 TJm
-(and) 14.3866 Tj
-[1 0 0 1 275.174 356.48] cm
-0 g
-0 G
-[1 0 0 1 -275.174 -356.48] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.174 356.48 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 317.017 356.48] cm
-0 g
-0 G
-[1 0 0 1 -317.017 -356.48] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-319.433 356.48 Td
-/F128_0 9.963 Tf
-(then) 17.1563 Tj
--242 TJm
-(allocates) 34.8605 Tj
--243 TJm
-(itself) 19.926 Tj
--242 TJm
-(just) 14.3965 Tj
--243 TJm
-(enough) 29.3311 Tj
--242 TJm
-(memory) 33.2067 Tj
--242 TJm
-(to) 7.75121 Tj
--243 TJm
-(decompress) 47.0353 Tj
-72 344.525 Td
-(the) 12.1748 Tj
--303 TJm
-(\002le.) 15.2235 Tj
--940 TJm
-(Since) 22.1378 Tj
--303 TJm
-(block) 22.1378 Tj
--303 TJm
-(sizes) 19.3681 Tj
--304 TJm
-(are) 12.1648 Tj
--303 TJm
-(stored) 24.3496 Tj
--303 TJm
-(in) 7.75121 Tj
--303 TJm
-(compressed) 47.0353 Tj
--304 TJm
-(\002) 5.53943 Tj
-1 TJm
-(les,) 13.5596 Tj
--317 TJm
-(it) 5.53943 Tj
--303 TJm
-(follo) 18.8201 Tj
-25 TJm
-(ws) 11.0689 Tj
--304 TJm
-(t) 2.76971 Tj
-1 TJm
-(hat) 12.1748 Tj
--304 TJm
-(the) 12.1748 Tj
--303 TJm
-(\003ags) 18.8201 Tj
-[1 0 0 1 406.35 344.525] cm
-0 g
-0 G
-[1 0 0 1 -406.35 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.35 344.525 Td
-/F130_0 9.963 Tf
-(-1) 11.9556 Tj
-[1 0 0 1 418.305 344.525] cm
-0 g
-0 G
-[1 0 0 1 -418.305 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-421.327 344.525 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
-[1 0 0 1 432.1 344.525] cm
-0 g
-0 G
-[1 0 0 1 -432.1 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-432.1 344.525 Td
-/F130_0 9.963 Tf
-(-9) 11.9556 Tj
-[1 0 0 1 444.055 344.525] cm
-0 g
-0 G
-[1 0 0 1 -444.055 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-447.077 344.525 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
--303 TJm
-(irrele) 21.0219 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ant) 12.1748 Tj
--303 TJm
-(to) 7.75121 Tj
--304 TJm
-(and) 14.3866 Tj
--303 TJm
-(so) 8.85711 Tj
-72 332.57 Td
-(ignored) 30.437 Tj
--250 TJm
-(during) 26.0134 Tj
--250 TJm
-(decompression) 59.768 Tj
-1 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 330.413] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -320.451] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 310.652 Td
-/F128_0 9.963 Tf
-(Compression) 52.5847 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(decompress) 47.0353 Tj
-1 TJm
-(ion) 12.7327 Tj
--250 TJm
-(requirements,) 54.5076 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(bytes,) 23.5226 Tj
--250 TJm
-(can) 13.8286 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(estimated) 38.1882 Tj
--250 TJm
-(as:) 11.0689 Tj
-[1 0 0 1 72 308.495] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 56.189] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -299.13] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 299.13 Td
-/F130_0 9.963 Tf
-(Compression:) 71.7336 Tj
--1278 TJm
-(400k) 23.9112 Tj
--426 TJm
-(+) 5.9778 Tj
--426 TJm
-(\() 5.9778 Tj
--425 TJm
-(8) 5.9778 Tj
--426 TJm
-(x) 5.9778 Tj
--426 TJm
-(block) 29.889 Tj
--426 TJm
-(size) 23.9112 Tj
--426 TJm
-(\)) 5.9778 Tj
-90 275.22 Td
-(Decompression:) 83.6892 Tj
--426 TJm
-(100k) 23.9112 Tj
--426 TJm
-(+) 5.9778 Tj
--426 TJm
-(\() 5.9778 Tj
--425 TJm
-(4) 5.9778 Tj
--426 TJm
-(x) 5.9778 Tj
--426 TJm
-(block) 29.889 Tj
--426 TJm
-(size) 23.9112 Tj
--426 TJm
-(\),) 11.9556 Tj
--426 TJm
-(or) 11.9556 Tj
-153.66 263.265 Td
-(100k) 23.9112 Tj
--426 TJm
-(+) 5.9778 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(2.5) 17.9334 Tj
--426 TJm
-(x) 5.9778 Tj
--426 TJm
-(block) 29.889 Tj
--426 TJm
-(s) 5.9778 Tj
-1 TJm
-(ize) 17.9334 Tj
--426 TJm
-(\)) 5.9778 Tj
-[1 0 0 1 72 247.723] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -237.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 225.805 Td
-/F128_0 9.963 Tf
-(Lar) 13.8286 Tj
-18 TJm
-(ger) 12.7228 Tj
--292 TJm
-(block) 22.1378 Tj
--291 TJm
-(sizes) 19.3681 Tj
--292 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--292 TJm
-(rapidly) 28.2252 Tj
--291 TJm
-(diminishing) 47.6132 Tj
--292 TJm
-(mar) 15.4925 Tj
-18 TJm
-(ginal) 19.926 Tj
--291 TJm
-(returns.) 30.158 Tj
--871 TJm
-(Most) 20.4839 Tj
--292 TJm
-(of) 8.29918 Tj
--291 TJm
-(the) 12.1748 Tj
--292 TJm
-(compression) 50.363 Tj
--292 TJm
-(com) 17.1563 Tj
-1 TJm
-(es) 8.29918 Tj
--292 TJm
-(from) 19.3681 Tj
--292 TJm
-(the) 12.1748 Tj
--292 TJm
-(\002rst) 15.5024 Tj
--291 TJm
-(tw) 9.963 Tj
-10 TJm
-(o) 4.9815 Tj
--292 TJm
-(or) 8.29918 Tj
-72 213.85 Td
-(three) 19.916 Tj
--232 TJm
-(hundred) 32.6488 Tj
--232 TJm
-(k) 4.9815 Tj
--232 TJm
-(o) 4.9815 Tj
-1 TJm
-(f) 3.31768 Tj
--232 TJm
-(block) 22.1378 Tj
--232 TJm
-(size,) 17.9832 Tj
--236 TJm
-(a) 4.42357 Tj
--232 TJm
-(f) 3.31768 Tj
-10 TJm
-(a) 4.42357 Tj
-1 TJm
-(ct) 7.19329 Tj
--232 TJm
-(w) 7.19329 Tj
-10 TJm
-(orth) 16.0504 Tj
--232 TJm
-(bearing) 29.879 Tj
--232 TJm
-(in) 7.75121 Tj
--232 TJm
-(mind) 20.4839 Tj
--232 TJm
-(when) 21.5799 Tj
--231 TJm
-(using) 21.5898 Tj
-[1 0 0 1 354.025 213.85] cm
-0 g
-0 G
-[1 0 0 1 -354.025 -213.85] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-354.025 213.85 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 383.913 213.85] cm
-0 g
-0 G
-[1 0 0 1 -383.913 -213.85] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-386.223 213.85 Td
-/F128_0 9.963 Tf
-(on) 9.963 Tj
--232 TJm
-(small) 21.5898 Tj
--232 TJm
-(machines.) 40.121 Tj
--303 TJm
-(It) 6.08739 Tj
--232 TJm
-(is) 6.64532 Tj
--232 TJm
-(also) 16.0504 Tj
--232 TJm
-(important) 38.7461 Tj
-72 201.895 Td
-(to) 7.75121 Tj
--250 TJm
-(appreciate) 40.938 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(decom) 26.5614 Tj
-1 TJm
-(pression) 33.2067 Tj
--250 TJm
-(memory) 33.2067 Tj
--250 TJm
-(requirement) 48.1412 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(set) 11.0689 Tj
--250 TJm
-(at) 7.19329 Tj
--250 TJm
-(compression) 50.363 Tj
--250 TJm
-(ti) 5.53943 Tj
-1 TJm
-(me) 12.1748 Tj
--250 TJm
-(by) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(choice) 26.0034 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(block) 22.1378 Tj
--250 TJm
-(size.) 17.9832 Tj
-[1 0 0 1 72 199.738] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -189.776] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 179.977 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--388 TJm
-(\002les) 16.6083 Tj
--389 TJm
-(compressed) 47.0353 Tj
--388 TJm
-(with) 17.7142 Tj
--388 TJm
-(the) 12.1748 Tj
--389 TJm
-(def) 12.7228 Tj
-10 TJm
-(ault) 14.9445 Tj
--388 TJm
-(900k) 19.926 Tj
--388 TJm
-(block) 22.1378 Tj
--389 TJm
-(size,) 17.9832 Tj
-[1 0 0 1 302.002 179.977] cm
-0 g
-0 G
-[1 0 0 1 -302.002 -179.977] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.002 179.977 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 343.845 179.977] cm
-0 g
-0 G
-[1 0 0 1 -343.845 -179.977] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-347.716 179.977 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--388 TJm
-(require) 28.2152 Tj
--389 TJm
-(about) 22.1378 Tj
--388 TJm
-(3700) 19.926 Tj
--388 TJm
-(kbytes) 26.0134 Tj
--389 TJm
-(to) 7.75121 Tj
--388 TJm
-(decompress.) 49.5261 Tj
-72 168.022 Td
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--424 TJm
-(support) 29.889 Tj
--424 TJm
-(decompression) 59.768 Tj
--424 TJm
-(of) 8.29918 Tj
--425 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--424 TJm
-(\002le) 12.7327 Tj
--424 TJm
-(on) 9.963 Tj
--424 TJm
-(a) 4.42357 Tj
--425 TJm
-(4) 4.9815 Tj
--424 TJm
-(me) 12.1748 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(abyte) 21.5799 Tj
--424 TJm
-(machine,) 36.2454 Tj
-[1 0 0 1 348.272 168.022] cm
-0 g
-0 G
-[1 0 0 1 -348.272 -168.022] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-348.272 168.022 Td
-/F130_0 9.963 Tf
-(bunzip2) 41.8446 Tj
-[1 0 0 1 390.115 168.022] cm
-0 g
-0 G
-[1 0 0 1 -390.115 -168.022] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-394.342 168.022 Td
-/F128_0 9.963 Tf
-(has) 13.2807 Tj
--424 TJm
-(an) 9.40507 Tj
--424 TJm
-(option) 25.4654 Tj
--425 TJm
-(to) 7.75121 Tj
--424 TJm
-(decompress) 47.0353 Tj
--424 TJm
-(using) 21.5898 Tj
-72 156.067 Td
-(approximately) 57.5563 Tj
--281 TJm
-(ha) 9.40507 Tj
-1 TJm
-(lf) 6.08739 Tj
--281 TJm
-(this) 14.3965 Tj
--281 TJm
-(amount) 29.889 Tj
--281 TJm
-(of) 8.29918 Tj
--280 TJm
-(memory) 33.2067 Tj
-65 TJm
-(,) 2.49075 Tj
--289 TJm
-(about) 22.1378 Tj
--280 TJm
-(2300) 19.926 Tj
--281 TJm
-(kbytes.) 28.5041 Tj
--805 TJm
-(Decom) 28.7731 Tj
-1 TJm
-(pression) 33.2067 Tj
--281 TJm
-(speed) 22.6858 Tj
--281 TJm
-(is) 6.64532 Tj
--281 TJm
-(a) 4.42357 Tj
-1 TJm
-(lso) 11.6268 Tj
--281 TJm
-(halv) 17.1563 Tj
-15 TJm
-(ed,) 11.8958 Tj
--289 TJm
-(so) 8.85711 Tj
--280 TJm
-(you) 14.9445 Tj
--281 TJm
-(should) 26.5713 Tj
-72 144.112 Td
-(use) 13.2807 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(option) 25.4654 Tj
--250 TJm
-(only) 17.7142 Tj
--250 TJm
-(where) 24.3396 Tj
--250 TJm
-(nec) 13.8286 Tj
-1 TJm
-(essary) 24.8975 Tj
-65 TJm
-(.) 2.49075 Tj
--620 TJm
-(The) 15.4925 Tj
--250 TJm
-(rele) 14.9345 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ant) 12.1748 Tj
--250 TJm
-(\003ag) 14.9445 Tj
--250 TJm
-(is) 6.64532 Tj
-[1 0 0 1 305.024 144.112] cm
-0 g
-0 G
-[1 0 0 1 -305.024 -144.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.024 144.112 Td
-/F130_0 9.963 Tf
-(-s) 11.9556 Tj
-[1 0 0 1 316.979 144.112] cm
-0 g
-0 G
-[1 0 0 1 -316.979 -144.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-316.979 144.112 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 141.955] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -131.992] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 122.194 Td
-/F128_0 9.963 Tf
-(In) 8.29918 Tj
--204 TJm
-(general,) 31.8119 Tj
--214 TJm
-(try) 11.0689 Tj
--204 TJm
-(and) 14.3866 Tj
--204 TJm
-(use) 13.2807 Tj
--205 TJm
-(the) 12.1748 Tj
--204 TJm
-(lar) 10.511 Tj
-18 TJm
-(gest) 16.0504 Tj
--204 TJm
-(block) 22.1378 Tj
--205 TJm
-(size) 15.4925 Tj
--204 TJm
-(memory) 33.2067 Tj
--204 TJm
-(constraints) 43.1697 Tj
--204 TJm
-(allo) 14.9445 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(,) 2.49075 Tj
--214 TJm
-(since) 20.474 Tj
--204 TJm
-(that) 14.9445 Tj
--204 TJm
-(maximises) 42.6217 Tj
--205 TJm
-(the) 12.1748 Tj
--204 TJm
-(compression) 50.363 Tj
--204 TJm
-(achie) 21.0219 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ed.) 11.8958 Tj
-72 110.239 Td
-(Compression) 52.5847 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(decompress) 47.0353 Tj
-1 TJm
-(ion) 12.7327 Tj
--250 TJm
-(speed) 22.6858 Tj
--250 TJm
-(are) 12.1648 Tj
--250 TJm
-(virtually) 33.7646 Tj
--250 TJm
-(unaf) 17.7043 Tj
-25 TJm
-(fected) 24.3396 Tj
--250 TJm
-(by) 9.963 Tj
--250 TJm
-(block) 22.1378 Tj
--250 TJm
-(size.) 17.9832 Tj
-[1 0 0 1 72 108.082] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -98.119] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 88.321 Td
-/F128_0 9.963 Tf
-(Another) 32.6488 Tj
--296 TJm
-(signi\002cant) 41.5158 Tj
--295 TJm
-(point) 20.4839 Tj
--296 TJm
-(applies) 28.2252 Tj
--296 TJm
-(to) 7.75121 Tj
--296 TJm
-(\002les) 16.6083 Tj
--295 TJm
-(which) 24.3496 Tj
--296 TJm
-(\002t) 8.30914 Tj
--296 TJm
-(in) 7.75121 Tj
--296 TJm
-(a) 4.42357 Tj
--296 TJm
-(s) 3.87561 Tj
-1 TJm
-(ingle) 19.926 Tj
--296 TJm
-(block) 22.1378 Tj
--296 TJm
-(--) 6.63536 Tj
--296 TJm
-(that) 14.9445 Tj
--296 TJm
-(mea) 16.5984 Tj
-1 TJm
-(ns) 8.85711 Tj
--296 TJm
-(most) 19.378 Tj
--296 TJm
-(\002les) 16.6083 Tj
--296 TJm
-(you') 18.2622 Tj
-50 TJm
-(d) 4.9815 Tj
--296 TJm
-(enc) 13.8286 Tj
-1 TJm
-(ounter) 25.4555 Tj
--296 TJm
-(using) 21.5898 Tj
--296 TJm
-(a) 4.42357 Tj
-72 76.366 Td
-(lar) 10.511 Tj
-18 TJm
-(ge) 9.40507 Tj
--290 TJm
-(block) 22.1378 Tj
--290 TJm
-(size) 15.4925 Tj
-1 TJm
-(.) 2.49075 Tj
--860 TJm
-(The) 15.4925 Tj
--290 TJm
-(amou) 22.1378 Tj
-1 TJm
-(nt) 7.75121 Tj
--290 TJm
-(of) 8.29918 Tj
--290 TJm
-(real) 14.9345 Tj
--290 TJm
-(memory) 33.2067 Tj
--290 TJm
-(touched) 31.5429 Tj
--289 TJm
-(is) 6.64532 Tj
--290 TJm
-(proportional) 49.2571 Tj
--290 TJm
-(to) 7.75121 Tj
--290 TJm
-(the) 12.1748 Tj
--290 TJm
-(size) 15.4925 Tj
--289 TJm
-(of) 8.29918 Tj
--290 TJm
-(the) 12.1748 Tj
--290 TJm
-(\002le,) 15.2235 Tj
--300 TJm
-(since) 20.474 Tj
--290 TJm
-(the) 12.1748 Tj
--289 TJm
-(\002le) 12.7327 Tj
--290 TJm
-(is) 6.64532 Tj
--290 TJm
-(smaller) 29.3311 Tj
-[1 0 0 1 72 50.852] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.063 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -496.332 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.951 Td
-/F128_0 9.963 Tf
-(5) 4.9815 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 9 9
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 105.519 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(than) 17.1563 Tj
--362 TJm
-(a) 4.42357 Tj
--362 TJm
-(block.) 24.6285 Tj
--1292 TJm
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--362 TJm
-(e) 4.42357 Tj
-15 TJm
-(xample,) 31.8218 Tj
--390 TJm
-(compressing) 50.363 Tj
--362 TJm
-(a) 4.42357 Tj
--362 TJm
-(\002le) 12.7327 Tj
--362 TJm
-(20,000) 27.3983 Tj
--362 TJm
-(bytes) 21.0319 Tj
--362 TJm
-(long) 17.7142 Tj
--362 TJm
-(with) 17.7142 Tj
--362 TJm
-(the) 12.1748 Tj
--362 TJm
-(\003ag) 14.9445 Tj
-[1 0 0 1 406.528 710.037] cm
-0 g
-0 G
-[1 0 0 1 -406.528 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.528 710.037 Td
-/F130_0 9.963 Tf
-(-9) 11.9556 Tj
-[1 0 0 1 418.483 710.037] cm
-0 g
-0 G
-[1 0 0 1 -418.483 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.091 710.037 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--362 TJm
-(cause) 22.1278 Tj
--362 TJm
-(the) 12.1748 Tj
--362 TJm
-(compressor) 45.9294 Tj
--362 TJm
-(to) 7.75121 Tj
-72 698.082 Td
-(allocate) 30.9849 Tj
--271 TJm
-(around) 27.6673 Tj
--272 TJm
-(7600k) 24.9075 Tj
--271 TJm
-(of) 8.29918 Tj
--272 TJm
-(m) 7.75121 Tj
-1 TJm
-(emory) 25.4555 Tj
-65 TJm
-(,) 2.49075 Tj
--277 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--272 TJm
-(only) 17.7142 Tj
--271 TJm
-(touch) 22.1378 Tj
--271 TJm
-(400k) 19.926 Tj
--272 TJm
-(+) 5.61913 Tj
--271 TJm
-(20000) 24.9075 Tj
--272 TJm
-(*) 4.9815 Tj
--271 TJm
-(8) 4.9815 Tj
--272 TJm
-(=) 5.61913 Tj
--271 TJm
-(560) 14.9445 Tj
--271 TJm
-(kbytes) 26.0134 Tj
--272 TJm
-(of) 8.29918 Tj
--271 TJm
-(it.) 8.03018 Tj
--749 TJm
-(Similarly) 37.0922 Tj
-65 TJm
-(,) 2.49075 Tj
--277 TJm
-(the) 12.1748 Tj
--271 TJm
-(decompressor) 55.3345 Tj
-72 686.127 Td
-(will) 15.5024 Tj
--250 TJm
-(allocate) 30.9849 Tj
--250 TJm
-(3700k) 24.9075 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(only) 17.7142 Tj
--250 TJm
-(t) 2.76971 Tj
-1 TJm
-(ouch) 19.3681 Tj
--250 TJm
-(100k) 19.926 Tj
--250 TJm
-(+) 5.61913 Tj
--250 TJm
-(20000) 24.9075 Tj
--250 TJm
-(*) 4.9815 Tj
--250 TJm
-(4) 4.9815 Tj
--250 TJm
-(=) 5.61913 Tj
--250 TJm
-(180) 14.9445 Tj
--250 TJm
-(kbytes.) 28.5041 Tj
-[1 0 0 1 72 683.97] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -674.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 664.209 Td
-/F128_0 9.963 Tf
-(Here) 19.3581 Tj
--293 TJm
-(is) 6.64532 Tj
--294 TJm
-(a) 4.42357 Tj
--293 TJm
-(table) 19.3681 Tj
--294 TJm
-(which) 24.3496 Tj
--293 TJm
-(summarises) 47.0453 Tj
--293 TJm
-(the) 12.1748 Tj
--294 TJm
-(maximu) 32.6587 Tj
-1 TJm
-(m) 7.75121 Tj
--294 TJm
-(memory) 33.2067 Tj
--293 TJm
-(usage) 22.6858 Tj
--294 TJm
-(for) 11.6169 Tj
--293 TJm
-(dif) 11.0689 Tj
-25 TJm
-(ferent) 23.2337 Tj
--293 TJm
-(block) 22.1378 Tj
--294 TJm
-(sizes.) 21.8588 Tj
--880 TJm
-(Also) 18.8201 Tj
--294 TJm
-(recorded) 34.8506 Tj
--293 TJm
-(is) 6.64532 Tj
--294 TJm
-(the) 12.1748 Tj
--293 TJm
-(total) 17.7142 Tj
-72 652.254 Td
-(compressed) 47.0353 Tj
--289 TJm
-(size) 15.4925 Tj
--289 TJm
-(for) 11.6169 Tj
--289 TJm
-(14) 9.963 Tj
--289 TJm
-(\002les) 16.6083 Tj
--289 TJm
-(of) 8.29918 Tj
--289 TJm
-(the) 12.1748 Tj
--289 TJm
-(Calg) 18.8201 Tj
-5 TJm
-(ary) 12.7228 Tj
--289 TJm
-(T) 6.08739 Tj
-70 TJm
-(e) 4.42357 Tj
-15 TJm
-(xt) 7.75121 Tj
--289 TJm
-(Compression) 52.5847 Tj
--289 TJm
-(Corpus) 28.7831 Tj
--289 TJm
-(totalling) 33.2166 Tj
--289 TJm
-(3,141,622) 39.852 Tj
--289 TJm
-(bytes.) 23.5226 Tj
--855 TJm
-(This) 17.7142 Tj
--289 TJm
-(column) 29.889 Tj
--289 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
-72 640.299 Td
-(some) 21.0319 Tj
--253 TJm
-(feel) 14.9345 Tj
--253 TJm
-(for) 11.6169 Tj
--253 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--253 TJm
-(compression) 50.363 Tj
--253 TJm
-(v) 4.9815 Tj
-25 TJm
-(aries) 18.8101 Tj
--253 TJm
-(with) 17.7142 Tj
--253 TJm
-(bl) 7.75121 Tj
-1 TJm
-(ock) 14.3866 Tj
--253 TJm
-(size.) 17.9832 Tj
--639 TJm
-(These) 23.7916 Tj
--253 TJm
-(\002g) 10.5209 Tj
-1 TJm
-(ures) 16.5984 Tj
--253 TJm
-(tend) 17.1563 Tj
--253 TJm
-(to) 7.75121 Tj
--253 TJm
-(understate) 40.9479 Tj
--253 TJm
-(the) 12.1748 Tj
--253 TJm
-(adv) 14.3866 Tj
-25 TJm
-(antage) 26.0034 Tj
--253 TJm
-(of) 8.29918 Tj
--253 TJm
-(lar) 10.511 Tj
-18 TJm
-(ger) 12.7228 Tj
--253 TJm
-(block) 22.1378 Tj
-72 628.344 Td
-(sizes) 19.3681 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(lar) 10.511 Tj
-18 TJm
-(ger) 12.7228 Tj
--250 TJm
-(\002les,) 19.0991 Tj
--250 TJm
-(since) 20.474 Tj
--250 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--250 TJm
-(Corpus) 28.7831 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(dominated) 42.0638 Tj
--250 TJm
-(by) 9.963 Tj
--250 TJm
-(smaller) 29.3311 Tj
--250 TJm
-(\002les.) 19.0991 Tj
-[1 0 0 1 72 626.187] cm
-0 g
-0 G
-[1 0 0 1 0 -156.414] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 155.417 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 151.831] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -616.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.952 616.822 Td
-/F130_0 9.963 Tf
-(Compress) 47.8224 Tj
--1278 TJm
-(Decompress) 59.778 Tj
--1277 TJm
-(Decompress) 59.778 Tj
--1278 TJm
-(Corpus) 35.8668 Tj
-90 604.867 Td
-(Flag) 23.9112 Tj
--2130 TJm
-(usage) 29.889 Tj
--2556 TJm
-(us) 11.9556 Tj
-1 TJm
-(age) 17.9334 Tj
--2982 TJm
-(-s) 11.9556 Tj
--426 TJm
-(usage) 29.889 Tj
--2130 TJm
-(Size) 23.9112 Tj
-94.244 580.957 Td
-(-1) 11.9556 Tj
--2556 TJm
-(1200k) 29.889 Tj
--2982 TJm
-(50) 11.9556 Tj
-1 TJm
-(0k) 11.9556 Tj
--3834 TJm
-(350k) 23.9112 Tj
--2556 TJm
-(914704) 35.8668 Tj
-94.244 569.001 Td
-(-2) 11.9556 Tj
--2556 TJm
-(2000k) 29.889 Tj
--2982 TJm
-(90) 11.9556 Tj
-1 TJm
-(0k) 11.9556 Tj
--3834 TJm
-(600k) 23.9112 Tj
--2556 TJm
-(877703) 35.8668 Tj
-94.244 557.046 Td
-(-3) 11.9556 Tj
--2556 TJm
-(2800k) 29.889 Tj
--2556 TJm
-(130) 17.9334 Tj
-1 TJm
-(0k) 11.9556 Tj
--3834 TJm
-(850k) 23.9112 Tj
--2556 TJm
-(860338) 35.8668 Tj
-94.244 545.091 Td
-(-4) 11.9556 Tj
--2556 TJm
-(3600k) 29.889 Tj
--2556 TJm
-(170) 17.9334 Tj
-1 TJm
-(0k) 11.9556 Tj
--3408 TJm
-(1100k) 29.889 Tj
--2556 TJm
-(846899) 35.8668 Tj
-94.244 533.136 Td
-(-5) 11.9556 Tj
--2556 TJm
-(4400k) 29.889 Tj
--2556 TJm
-(210) 17.9334 Tj
-1 TJm
-(0k) 11.9556 Tj
--3408 TJm
-(1350k) 29.889 Tj
--2556 TJm
-(845160) 35.8668 Tj
-94.244 521.181 Td
-(-6) 11.9556 Tj
--2556 TJm
-(5200k) 29.889 Tj
--2556 TJm
-(250) 17.9334 Tj
-1 TJm
-(0k) 11.9556 Tj
--3408 TJm
-(1600k) 29.889 Tj
--2556 TJm
-(838626) 35.8668 Tj
-94.244 509.225 Td
-(-7) 11.9556 Tj
--2556 TJm
-(6100k) 29.889 Tj
--2556 TJm
-(290) 17.9334 Tj
-1 TJm
-(0k) 11.9556 Tj
--3408 TJm
-(1850k) 29.889 Tj
--2556 TJm
-(834096) 35.8668 Tj
-94.244 497.27 Td
-(-8) 11.9556 Tj
--2556 TJm
-(6800k) 29.889 Tj
--2556 TJm
-(330) 17.9334 Tj
-1 TJm
-(0k) 11.9556 Tj
--3408 TJm
-(2100k) 29.889 Tj
--2556 TJm
-(828642) 35.8668 Tj
-94.244 485.315 Td
-(-9) 11.9556 Tj
--2556 TJm
-(7600k) 29.889 Tj
--2556 TJm
-(370) 17.9334 Tj
-1 TJm
-(0k) 11.9556 Tj
--3408 TJm
-(2350k) 29.889 Tj
--2556 TJm
-(828642) 35.8668 Tj
-[1 0 0 1 72 469.773] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -459.811] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 435.021 Td
-/F121_0 20.659 Tf
-(2.6.) 34.4592 Tj
--939 TJm
-(RECO) 59.6839 Tj
-50 TJm
-(VERING) 79.2066 Tj
--939 TJm
-(D) 14.9158 Tj
-40 TJm
-(A) 14.9158 Tj
-90 TJm
-(T) 12.6226 Tj
-90 TJm
-(A) 14.9158 Tj
--939 TJm
-(FR) 27.5384 Tj
-20 TJm
-(OM) 33.2816 Tj
--939 TJm
-(D) 14.9158 Tj
-40 TJm
-(AMA) 47.0405 Tj
-50 TJm
-(GED) 44.7681 Tj
-72 410.23 Td
-(FILES) 58.5476 Tj
-[1 0 0 1 72 409.972] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -400.01] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 388.313 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 388.313] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -388.313] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.138 388.313 Td
-/F128_0 9.963 Tf
-(compresses) 45.9294 Tj
--326 TJm
-(\002les) 16.6083 Tj
--326 TJm
-(in) 7.75121 Tj
--326 TJm
-(blocks,) 28.5041 Tj
--345 TJm
-(usually) 28.7831 Tj
--326 TJm
-(900kbytes) 40.9579 Tj
--326 TJm
-(long.) 20.205 Tj
--1077 TJm
-(Each) 19.916 Tj
--326 TJm
-(block) 22.1378 Tj
--326 TJm
-(is) 6.64532 Tj
--327 TJm
-(handle) 26.5614 Tj
-1 TJm
-(d) 4.9815 Tj
--327 TJm
-(independe) 40.9479 Tj
-1 TJm
-(ntly) 15.5024 Tj
-65 TJm
-(.) 2.49075 Tj
--1077 TJm
-(If) 6.63536 Tj
--327 TJm
-(a) 4.42357 Tj
--326 TJm
-(media) 24.3496 Tj
--326 TJm
-(or) 8.29918 Tj
-72 376.357 Td
-(transmission) 50.3729 Tj
--318 TJm
-(error) 19.3581 Tj
--319 TJm
-(causes) 26.0034 Tj
--318 TJm
-(a) 4.42357 Tj
--319 TJm
-(multi-block) 46.4973 Tj
-[1 0 0 1 234.519 376.357] cm
-0 g
-0 G
-[1 0 0 1 -234.519 -376.357] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.519 376.357 Td
-/F130_0 9.963 Tf
-(.bz2) 23.9112 Tj
-[1 0 0 1 258.429 376.357] cm
-0 g
-0 G
-[1 0 0 1 -258.429 -376.357] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.603 376.357 Td
-/F128_0 9.963 Tf
-(\002le) 12.7327 Tj
--319 TJm
-(to) 7.75121 Tj
--318 TJm
-(become) 30.9849 Tj
--319 TJm
-(da) 9.40507 Tj
-1 TJm
-(maged,) 29.0521 Tj
--336 TJm
-(it) 5.53943 Tj
--319 TJm
-(may) 17.1563 Tj
--318 TJm
-(be) 9.40507 Tj
--319 TJm
-(possible) 32.6587 Tj
--318 TJm
-(to) 7.75121 Tj
--319 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--318 TJm
-(data) 16.5984 Tj
--319 TJm
-(from) 19.3681 Tj
--318 TJm
-(the) 12.1748 Tj
-72 364.402 Td
-(undamaged) 45.9294 Tj
--250 TJm
-(blocks) 26.0134 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\002le.) 15.2235 Tj
-[1 0 0 1 72 362.245] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -352.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 342.484 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--358 TJm
-(com) 17.1563 Tj
-1 TJm
-(pressed) 29.879 Tj
--358 TJm
-(representation) 56.4404 Tj
--357 TJm
-(of) 8.29918 Tj
--358 TJm
-(each) 18.2522 Tj
--357 TJm
-(block) 22.1378 Tj
--358 TJm
-(is) 6.64532 Tj
--357 TJm
-(delimited) 37.6402 Tj
--358 TJm
-(by) 9.963 Tj
--357 TJm
-(a) 4.42357 Tj
--358 TJm
-(48-bit) 23.8016 Tj
--357 TJm
-(pattern,) 30.158 Tj
--385 TJm
-(which) 24.3496 Tj
--357 TJm
-(mak) 17.1563 Tj
-10 TJm
-(es) 8.29918 Tj
--358 TJm
-(it) 5.53943 Tj
--357 TJm
-(possible) 32.6587 Tj
--358 TJm
-(to) 7.75121 Tj
--357 TJm
-(\002nd) 15.5024 Tj
--358 TJm
-(the) 12.1748 Tj
-72 330.529 Td
-(block) 22.1378 Tj
--286 TJm
-(boundaries) 43.7176 Tj
--285 TJm
-(with) 17.7142 Tj
--286 TJm
-(reasonable) 42.6018 Tj
--285 TJm
-(certainty) 34.8605 Tj
-65 TJm
-(.) 2.49075 Tj
--835 TJm
-(Each) 19.916 Tj
--286 TJm
-(block) 22.1378 Tj
--285 TJm
-(also) 16.0504 Tj
--286 TJm
-(carries) 26.5514 Tj
--286 TJm
-(its) 9.41504 Tj
--285 TJm
-(o) 4.9815 Tj
-25 TJm
-(wn) 12.1748 Tj
--286 TJm
-(32-bit) 23.8016 Tj
--286 TJm
-(CRC,) 22.4267 Tj
--285 TJm
-(so) 8.85711 Tj
--286 TJm
-(damaged) 35.9664 Tj
--286 TJm
-(blocks) 26.0134 Tj
--285 TJm
-(can) 13.8286 Tj
--286 TJm
-(be) 9.40507 Tj
-72 318.574 Td
-(distinguished) 53.1426 Tj
--250 TJm
-(from) 19.3681 Tj
--250 TJm
-(undamage) 40.9479 Tj
-1 TJm
-(d) 4.9815 Tj
--250 TJm
-(ones.) 20.7529 Tj
-[1 0 0 1 72 316.417] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -306.455] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 296.656 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 143.731 296.656] cm
-0 g
-0 G
-[1 0 0 1 -143.731 -296.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.448 296.656 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--273 TJm
-(a) 4.42357 Tj
--272 TJm
-(simple) 26.5713 Tj
--273 TJm
-(program) 33.7546 Tj
--272 TJm
-(whose) 25.4555 Tj
--273 TJm
-(purpose) 31.5429 Tj
--273 TJm
-(i) 2.76971 Tj
-1 TJm
-(s) 3.87561 Tj
--273 TJm
-(to) 7.75121 Tj
--273 TJm
-(search) 25.4455 Tj
--272 TJm
-(for) 11.6169 Tj
--273 TJm
-(blocks) 26.0134 Tj
--273 TJm
-(in) 7.75121 Tj
-[1 0 0 1 392.655 296.656] cm
-0 g
-0 G
-[1 0 0 1 -392.655 -296.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.655 296.656 Td
-/F130_0 9.963 Tf
-(.bz2) 23.9112 Tj
-[1 0 0 1 416.566 296.656] cm
-0 g
-0 G
-[1 0 0 1 -416.566 -296.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.282 296.656 Td
-/F128_0 9.963 Tf
-(\002les,) 19.0991 Tj
--278 TJm
-(and) 14.3866 Tj
--273 TJm
-(write) 20.474 Tj
--273 TJm
-(e) 4.42357 Tj
-1 TJm
-(ach) 13.8286 Tj
--273 TJm
-(block) 22.1378 Tj
--273 TJm
-(out) 12.7327 Tj
-72 284.701 Td
-(into) 15.5024 Tj
--254 TJm
-(its) 9.41504 Tj
--255 TJm
-(o) 4.9815 Tj
-25 TJm
-(wn) 12.1748 Tj
-[1 0 0 1 121.429 284.701] cm
-0 g
-0 G
-[1 0 0 1 -121.429 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-121.429 284.701 Td
-/F130_0 9.963 Tf
-(.bz2) 23.9112 Tj
-[1 0 0 1 145.34 284.701] cm
-0 g
-0 G
-[1 0 0 1 -145.34 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.875 284.701 Td
-/F128_0 9.963 Tf
-(\002le.) 15.2235 Tj
--647 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--254 TJm
-(can) 13.8286 Tj
--255 TJm
-(then) 17.1563 Tj
--254 TJm
-(use) 13.2807 Tj
-[1 0 0 1 240.01 284.701] cm
-0 g
-0 G
-[1 0 0 1 -240.01 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-240.01 284.701 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
--600 TJm
-(-t) 11.9556 Tj
-[1 0 0 1 287.831 284.701] cm
-0 g
-0 G
-[1 0 0 1 -287.831 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-290.367 284.701 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--254 TJm
-(test) 13.8386 Tj
--255 TJm
-(the) 12.1748 Tj
--254 TJm
-(inte) 14.9445 Tj
-15 TJm
-(grity) 18.8201 Tj
--255 TJm
-(of) 8.29918 Tj
--254 TJm
-(the) 12.1748 Tj
--255 TJm
-(res) 11.6169 Tj
-1 TJm
-(ulting) 23.2536 Tj
--255 TJm
-(\002les,) 19.0991 Tj
--255 TJm
-(and) 14.3866 Tj
--255 TJm
-(decompress) 47.0353 Tj
--254 TJm
-(those) 21.0319 Tj
-72 272.746 Td
-(which) 24.3496 Tj
--250 TJm
-(are) 12.1648 Tj
--250 TJm
-(undamaged.) 48.4202 Tj
-[1 0 0 1 72 270.589] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -260.626] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 250.828 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 143.731 250.828] cm
-0 g
-0 G
-[1 0 0 1 -143.731 -250.828] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.099 250.828 Td
-/F128_0 9.963 Tf
-(tak) 12.1748 Tj
-10 TJm
-(es) 8.29918 Tj
--639 TJm
-(a) 4.42357 Tj
--639 TJm
-(single) 23.8016 Tj
--639 TJm
-(ar) 7.74125 Tj
-18 TJm
-(gument,) 32.3798 Tj
--736 TJm
-(the) 12.1748 Tj
--639 TJm
-(name) 21.5799 Tj
--639 TJm
-(of) 8.29918 Tj
--639 TJm
-(the) 12.1748 Tj
--640 TJm
-(da) 9.40507 Tj
-1 TJm
-(maged) 26.5614 Tj
--640 TJm
-(\002) 5.53943 Tj
-1 TJm
-(le,) 9.68404 Tj
--737 TJm
-(and) 14.3866 Tj
--639 TJm
-(writes) 24.3496 Tj
--639 TJm
-(a) 4.42357 Tj
--639 TJm
-(number) 30.437 Tj
--639 TJm
-(of) 8.29918 Tj
--639 TJm
-(\002les) 16.6083 Tj
-[1 0 0 1 72 238.873] cm
-0 g
-0 G
-[1 0 0 1 -72 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 238.873 Td
-/F130_0 9.963 Tf
-(rec0001file.bz2) 89.667 Tj
-[1 0 0 1 161.664 238.873] cm
-0 g
-0 G
-[1 0 0 1 -161.664 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.664 238.873 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 169.072 238.873] cm
-0 g
-0 G
-[1 0 0 1 -169.072 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.072 238.873 Td
-/F130_0 9.963 Tf
-(rec0002file.bz2) 89.667 Tj
-[1 0 0 1 258.736 238.873] cm
-0 g
-0 G
-[1 0 0 1 -258.736 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.736 238.873 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--494 TJm
-(etc,) 14.1076 Tj
--493 TJm
-(containing) 42.0638 Tj
--445 TJm
-(the) 12.1748 Tj
--445 TJm
-(e) 4.42357 Tj
-15 TJm
-(xtracted) 32.0908 Tj
--444 TJm
-(blocks.) 28.5041 Tj
--1790 TJm
-(The) 15.4925 Tj
--444 TJm
-(output) 25.4654 Tj
--445 TJm
-(\002lenames) 38.1882 Tj
--445 TJm
-(are) 12.1648 Tj
-72 226.918 Td
-(designed) 35.4185 Tj
--337 TJm
-(so) 8.85711 Tj
--337 TJm
-(that) 14.9445 Tj
--336 TJm
-(the) 12.1748 Tj
--337 TJm
-(use) 13.2807 Tj
--337 TJm
-(of) 8.29918 Tj
--337 TJm
-(wildcards) 38.7361 Tj
--337 TJm
-(in) 7.75121 Tj
--337 TJm
-(subsequent) 44.2756 Tj
--336 TJm
-(processing) 42.6118 Tj
--337 TJm
-(--) 6.63536 Tj
--337 TJm
-(for) 11.6169 Tj
--337 TJm
-(e) 4.42357 Tj
-15 TJm
-(xample,) 31.8218 Tj
-[1 0 0 1 396.538 226.918] cm
-0 g
-0 G
-[1 0 0 1 -396.538 -226.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-396.538 226.918 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
--600 TJm
-(-dc) 17.9334 Tj
--600 TJm
-(rec*file.bz2) 71.7336 Tj
--600 TJm
-(>) 5.9778 Tj
-72 214.963 Td
-(recovered_data) 83.6892 Tj
-[1 0 0 1 155.686 214.963] cm
-0 g
-0 G
-[1 0 0 1 -155.686 -214.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.177 214.963 Td
-/F128_0 9.963 Tf
-(--) 6.63536 Tj
--250 TJm
-(lists) 16.0604 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\002les) 16.6083 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(corr) 16.0404 Tj
-1 TJm
-(ect) 11.6169 Tj
--250 TJm
-(order) 21.0219 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 213.797] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -203.834] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 193.045 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 143.731 193.045] cm
-0 g
-0 G
-[1 0 0 1 -143.731 -193.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.93 193.045 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--221 TJm
-(be) 9.40507 Tj
--220 TJm
-(of) 8.29918 Tj
--221 TJm
-(most) 19.378 Tj
--220 TJm
-(use) 13.2807 Tj
--221 TJm
-(dealing) 29.3311 Tj
--221 TJm
-(with) 17.7142 Tj
--220 TJm
-(lar) 10.511 Tj
-18 TJm
-(ge) 9.40507 Tj
-[1 0 0 1 307.229 193.045] cm
-0 g
-0 G
-[1 0 0 1 -307.229 -193.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-307.229 193.045 Td
-/F130_0 9.963 Tf
-(.bz2) 23.9112 Tj
-[1 0 0 1 331.14 193.045] cm
-0 g
-0 G
-[1 0 0 1 -331.14 -193.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.338 193.045 Td
-/F128_0 9.963 Tf
-(\002les,) 19.0991 Tj
--226 TJm
-(as) 8.29918 Tj
--221 TJm
-(these) 20.474 Tj
--221 TJm
-(will) 15.5024 Tj
--220 TJm
-(contain) 29.3311 Tj
--221 TJm
-(man) 17.1563 Tj
-15 TJm
-(y) 4.9815 Tj
--221 TJm
-(b) 4.9815 Tj
-1 TJm
-(locks.) 23.5226 Tj
--601 TJm
-(It) 6.08739 Tj
--220 TJm
-(is) 6.64532 Tj
--221 TJm
-(clearly) 27.1093 Tj
-72 181.09 Td
-(futile) 21.0319 Tj
--289 TJm
-(to) 7.75121 Tj
--289 TJm
-(use) 13.2807 Tj
--289 TJm
-(it) 5.53943 Tj
--289 TJm
-(on) 9.963 Tj
--289 TJm
-(damaged) 35.9664 Tj
--289 TJm
-(single-block) 49.2571 Tj
--289 TJm
-(\002les,) 19.0991 Tj
--299 TJm
-(since) 20.474 Tj
--289 TJm
-(a) 4.42357 Tj
--289 TJm
-(damaged) 35.9664 Tj
--289 TJm
-(block) 22.1378 Tj
--289 TJm
-(cannot) 26.5614 Tj
--289 TJm
-(be) 9.40507 Tj
--289 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(ered) 17.1463 Tj
-1 TJm
-(.) 2.49075 Tj
--855 TJm
-(If) 6.63536 Tj
--289 TJm
-(you) 14.9445 Tj
--289 TJm
-(wish) 18.8201 Tj
--289 TJm
-(to) 7.75121 Tj
--289 TJm
-(minimise) 37.0922 Tj
-72 169.134 Td
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--320 TJm
-(potential) 34.8705 Tj
--319 TJm
-(data) 16.5984 Tj
--320 TJm
-(loss) 15.5024 Tj
--320 TJm
-(through) 30.9949 Tj
--319 TJm
-(media) 24.3496 Tj
--320 TJm
-(or) 8.29918 Tj
--320 TJm
-(transmission) 50.3729 Tj
--319 TJm
-(errors,) 25.7245 Tj
--337 TJm
-(you) 14.9445 Tj
--320 TJm
-(might) 23.2536 Tj
--320 TJm
-(consider) 33.7546 Tj
--319 TJm
-(compressing) 50.363 Tj
--320 TJm
-(with) 17.7142 Tj
--320 TJm
-(a) 4.42357 Tj
--319 TJm
-(smaller) 29.3311 Tj
--320 TJm
-(block) 22.1378 Tj
-72 157.179 Td
-(size.) 17.9832 Tj
-[1 0 0 1 72 157.08] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -147.117] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 122.426 Td
-/F121_0 20.659 Tf
-(2.7.) 34.4592 Tj
--278 TJm
-(PERFORMANCE) 161.822 Tj
--278 TJm
-(NO) 30.9885 Tj
-40 TJm
-(TES) 40.1818 Tj
-[1 0 0 1 72 122.168] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -112.206] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 100.509 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--304 TJm
-(sorting) 27.6772 Tj
--305 TJm
-(phase) 22.6858 Tj
--304 TJm
-(of) 8.29918 Tj
--305 TJm
-(compression) 50.363 Tj
--304 TJm
-(g) 4.9815 Tj
-5 TJm
-(athers) 23.7916 Tj
--305 TJm
-(together) 32.6488 Tj
--304 TJm
-(similar) 27.6772 Tj
--304 TJm
-(strings) 26.5713 Tj
--305 TJm
-(in) 7.75121 Tj
--304 TJm
-(the) 12.1748 Tj
--305 TJm
-(\002le.) 15.2235 Tj
--947 TJm
-(Because) 33.1967 Tj
--305 TJm
-(of) 8.29918 Tj
--304 TJm
-(this,) 16.8873 Tj
--318 TJm
-(\002les) 16.6083 Tj
--305 TJm
-(contai) 24.3496 Tj
-1 TJm
-(ning) 17.7142 Tj
--305 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
-72 88.553 Td
-(long) 17.7142 Tj
--286 TJm
-(run) 13.2807 Tj
-1 TJm
-(s) 3.87561 Tj
--286 TJm
-(of) 8.29918 Tj
--286 TJm
-(repeated) 33.7447 Tj
--285 TJm
-(symbols,) 35.7074 Tj
--295 TJm
-(l) 2.76971 Tj
-1 TJm
-(ik) 7.75121 Tj
-10 TJm
-(e) 4.42357 Tj
--286 TJm
-("aabaabaabaab) 59.3795 Tj
--285 TJm
-(...") 11.5372 Tj
--572 TJm
-(\(repea) 24.8876 Tj
-1 TJm
-(ted) 12.1748 Tj
--286 TJm
-(se) 8.29918 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(eral) 14.9345 Tj
--286 TJm
-(hun) 14.9445 Tj
-1 TJm
-(dred) 17.7043 Tj
--286 TJm
-(times\)) 24.9075 Tj
--286 TJm
-(m) 7.75121 Tj
-1 TJm
-(ay) 9.40507 Tj
--286 TJm
-(compress) 37.6303 Tj
--286 TJm
-(m) 7.75121 Tj
-1 TJm
-(ore) 12.7228 Tj
--286 TJm
-(slo) 11.6268 Tj
-25 TJm
-(wly) 14.9445 Tj
-72 76.598 Td
-(than) 17.1563 Tj
--321 TJm
-(normal.) 30.7159 Tj
--525 TJm
-(V) 7.19329 Tj
-111 TJm
-(ersions) 28.2252 Tj
--321 TJm
-(0.9.5) 19.926 Tj
--322 TJm
-(and) 14.3866 Tj
--322 TJm
-(a) 4.42357 Tj
-1 TJm
-(bo) 9.963 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--322 TJm
-(f) 3.31768 Tj
-10 TJm
-(are) 12.1648 Tj
--321 TJm
-(much) 22.1378 Tj
--322 TJm
-(better) 22.6858 Tj
--321 TJm
-(than) 17.1563 Tj
--322 TJm
-(pre) 12.7228 Tj
-25 TJm
-(vious) 21.5898 Tj
--321 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--322 TJm
-(in) 7.75121 Tj
--321 TJm
-(this) 14.3965 Tj
--322 TJm
-(respect.) 30.706 Tj
--1049 TJm
-(The) 15.4925 Tj
--322 TJm
-(ratio) 18.2622 Tj
--321 TJm
-(between) 33.1967 Tj
-[1 0 0 1 72 50.852] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.063 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -496.332 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.951 Td
-/F128_0 9.963 Tf
-(6) 4.9815 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 10 10
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 105.519 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(w) 7.19329 Tj
-10 TJm
-(orst-case) 35.4085 Tj
--289 TJm
-(and) 14.3866 Tj
--290 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(erage-c) 29.3111 Tj
-1 TJm
-(ase) 12.7228 Tj
--290 TJm
-(compression) 50.363 Tj
--289 TJm
-(time) 17.7142 Tj
--289 TJm
-(is) 6.64532 Tj
--290 TJm
-(in) 7.75121 Tj
--289 TJm
-(the) 12.1748 Tj
--290 TJm
-(re) 7.74125 Tj
-15 TJm
-(gion) 17.7142 Tj
--289 TJm
-(of) 8.29918 Tj
--289 TJm
-(10:1.) 20.205 Tj
--857 TJm
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--289 TJm
-(pre) 12.7228 Tj
-25 TJm
-(vious) 21.5898 Tj
--290 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions,) 30.7159 Tj
--299 TJm
-(this) 14.3965 Tj
--289 TJm
-(\002gure) 23.2437 Tj
--290 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--289 TJm
-(more) 20.474 Tj
-72 698.082 Td
-(lik) 10.5209 Tj
-10 TJm
-(e) 4.42357 Tj
--250 TJm
-(100:1.) 25.1865 Tj
--620 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--250 TJm
-(can) 13.8286 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(the) 12.1748 Tj
-[1 0 0 1 186.002 698.082] cm
-0 g
-0 G
-[1 0 0 1 -186.002 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-186.002 698.082 Td
-/F130_0 9.963 Tf
-(-vvvv) 29.889 Tj
-[1 0 0 1 215.89 698.082] cm
-0 g
-0 G
-[1 0 0 1 -215.89 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-218.38 698.082 Td
-/F128_0 9.963 Tf
-(option) 25.4654 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(monitor) 31.5528 Tj
--250 TJm
-(progress) 33.7546 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(g) 4.9815 Tj
-1 TJm
-(reat) 14.9345 Tj
--250 TJm
-(detail,) 24.6285 Tj
--250 TJm
-(if) 6.08739 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant.) 14.6655 Tj
-[1 0 0 1 72 695.925] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -685.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 676.164 Td
-/F128_0 9.963 Tf
-(Decompression) 61.9798 Tj
--250 TJm
-(speed) 22.6858 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(unaf) 17.7043 Tj
-26 TJm
-(fected) 24.3396 Tj
--250 TJm
-(by) 9.963 Tj
--250 TJm
-(these) 20.474 Tj
--250 TJm
-(phenomena.) 48.4202 Tj
-[1 0 0 1 72 674.008] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -664.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 654.247 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 654.247] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.863 654.247 Td
-/F128_0 9.963 Tf
-(usually) 28.7831 Tj
--298 TJm
-(allocates) 34.8605 Tj
--299 TJm
-(se) 8.29918 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(eral) 14.9345 Tj
--298 TJm
-(me) 12.1748 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(abytes) 25.4555 Tj
--299 TJm
-(of) 8.29918 Tj
--298 TJm
-(memory) 33.2067 Tj
--299 TJm
-(to) 7.75121 Tj
--298 TJm
-(operate) 29.3211 Tj
--299 TJm
-(in,) 10.242 Tj
--311 TJm
-(and) 14.3866 Tj
--298 TJm
-(then) 17.1563 Tj
--299 TJm
-(char) 17.1463 Tj
-18 TJm
-(ges) 13.2807 Tj
--298 TJm
-(all) 9.963 Tj
--299 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--298 TJm
-(it) 5.53943 Tj
--299 TJm
-(in) 7.75121 Tj
--298 TJm
-(a) 4.42357 Tj
--299 TJm
-(f) 3.31768 Tj
-10 TJm
-(airly) 18.2622 Tj
--299 TJm
-(r) 3.31768 Tj
-1 TJm
-(andom) 27.1193 Tj
-72 642.291 Td
-(f) 3.31768 Tj
-10 TJm
-(ashion.) 28.5041 Tj
--743 TJm
-(This) 17.7142 Tj
--270 TJm
-(means) 25.4555 Tj
--271 TJm
-(t) 2.76971 Tj
-1 TJm
-(hat) 12.1748 Tj
--271 TJm
-(performance,) 52.8338 Tj
--275 TJm
-(both) 17.7142 Tj
--271 TJm
-(for) 11.6169 Tj
--270 TJm
-(compressing) 50.363 Tj
--270 TJm
-(and) 14.3866 Tj
--271 TJm
-(decompressing,) 62.2588 Tj
--275 TJm
-(is) 6.64532 Tj
--271 TJm
-(la) 7.19329 Tj
-1 TJm
-(r) 3.31768 Tj
-18 TJm
-(gely) 17.1563 Tj
--271 TJm
-(determined) 44.8235 Tj
--270 TJm
-(by) 9.963 Tj
--271 TJm
-(the) 12.1748 Tj
--270 TJm
-(speed) 22.6858 Tj
-72 630.336 Td
-(at) 7.19329 Tj
--294 TJm
-(which) 24.3496 Tj
--294 TJm
-(your) 18.2622 Tj
--294 TJm
-(machine) 33.7546 Tj
--294 TJm
-(can) 13.8286 Tj
--294 TJm
-(service) 28.2152 Tj
--294 TJm
-(cache) 22.6758 Tj
--294 TJm
-(misses.) 29.0621 Tj
--442 TJm
-(Because) 33.1967 Tj
--294 TJm
-(of) 8.29918 Tj
--295 TJm
-(t) 2.76971 Tj
-1 TJm
-(his,) 14.1176 Tj
--306 TJm
-(smal) 18.8201 Tj
-1 TJm
-(l) 2.76971 Tj
--295 TJm
-(chang) 23.7916 Tj
-1 TJm
-(es) 8.29918 Tj
--295 TJm
-(to) 7.75121 Tj
--294 TJm
-(the) 12.1748 Tj
--294 TJm
-(code) 18.8101 Tj
--294 TJm
-(to) 7.75121 Tj
--294 TJm
-(reduce) 26.5514 Tj
--294 TJm
-(the) 12.1748 Tj
--294 TJm
-(miss) 18.2721 Tj
--294 TJm
-(rate) 14.9345 Tj
-72 618.381 Td
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--253 TJm
-(been) 18.8101 Tj
--253 TJm
-(observ) 26.5614 Tj
-15 TJm
-(ed) 9.40507 Tj
--253 TJm
-(to) 7.75121 Tj
--253 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--253 TJm
-(disproportionately) 73.0587 Tj
--253 TJm
-(la) 7.19329 Tj
-1 TJm
-(r) 3.31768 Tj
-18 TJm
-(ge) 9.40507 Tj
--253 TJm
-(performance) 50.343 Tj
--253 TJm
-(impro) 23.8016 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(ements.) 30.7159 Tj
--638 TJm
-(I) 3.31768 Tj
--253 TJm
-(imagine) 32.1008 Tj
-[1 0 0 1 438.909 618.381] cm
-0 g
-0 G
-[1 0 0 1 -438.909 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.909 618.381 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 468.797 618.381] cm
-0 g
-0 G
-[1 0 0 1 -468.797 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-471.318 618.381 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--253 TJm
-(perform) 32.0908 Tj
--253 TJm
-(best) 16.0504 Tj
-72 606.426 Td
-(on) 9.963 Tj
--250 TJm
-(machines) 37.6303 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
--250 TJm
-(lar) 10.511 Tj
-18 TJm
-(ge) 9.40507 Tj
--250 TJm
-(c) 4.42357 Tj
-1 TJm
-(aches.) 24.6186 Tj
-[1 0 0 1 72 604.269] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -594.306] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 571.673 Td
-/F121_0 20.659 Tf
-(2.8.) 34.4592 Tj
--278 TJm
-(CA) 29.8316 Tj
-80 TJm
-(VEA) 42.4749 Tj
-90 TJm
-(TS) 26.4022 Tj
-[1 0 0 1 72 571.415] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -561.452] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 549.755 Td
-/F128_0 9.963 Tf
-(I/O) 13.2807 Tj
--268 TJm
-(error) 19.3581 Tj
--267 TJm
-(messages) 37.6303 Tj
--268 TJm
-(are) 12.1648 Tj
--267 TJm
-(not) 12.7327 Tj
--268 TJm
-(as) 8.29918 Tj
--268 TJm
-(helpful) 28.2252 Tj
--267 TJm
-(as) 8.29918 Tj
--268 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--268 TJm
-(could) 22.1378 Tj
--267 TJm
-(be.) 11.8958 Tj
-[1 0 0 1 293.313 549.755] cm
-0 g
-0 G
-[1 0 0 1 -293.313 -549.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.313 549.755 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 323.201 549.755] cm
-0 g
-0 G
-[1 0 0 1 -323.201 -549.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-325.868 549.755 Td
-/F128_0 9.963 Tf
-(tries) 17.1563 Tj
--268 TJm
-(hard) 17.7043 Tj
--267 TJm
-(to) 7.75121 Tj
--268 TJm
-(detect) 23.7916 Tj
--268 TJm
-(I/O) 13.2807 Tj
--267 TJm
-(errors) 23.2337 Tj
--268 TJm
-(and) 14.3866 Tj
--267 TJm
-(e) 4.42357 Tj
-15 TJm
-(xit) 10.5209 Tj
--268 TJm
-(cleanly) 28.7731 Tj
-65 TJm
-(,) 2.49075 Tj
--272 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--268 TJm
-(the) 12.1748 Tj
-72 537.8 Td
-(details) 26.0134 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(what) 19.3681 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(problem) 33.2067 Tj
--249 TJm
-(is) 6.64532 Tj
--250 TJm
-(sometimes) 42.6217 Tj
--250 TJm
-(seem) 20.474 Tj
--250 TJm
-(rather) 23.2337 Tj
--250 TJm
-(misleading.) 46.2184 Tj
-[1 0 0 1 72 535.643] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -525.681] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 515.882 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--280 TJm
-(manu) 22.1378 Tj
-1 TJm
-(al) 7.19329 Tj
--280 TJm
-(page) 18.8101 Tj
--280 TJm
-(pertains) 31.5429 Tj
--279 TJm
-(to) 7.75121 Tj
--280 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--279 TJm
-(1.0.3) 19.926 Tj
--280 TJm
-(of) 8.29918 Tj
-[1 0 0 1 256.84 515.882] cm
-0 g
-0 G
-[1 0 0 1 -256.84 -515.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.84 515.882 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 286.727 515.882] cm
-0 g
-0 G
-[1 0 0 1 -286.727 -515.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-286.727 515.882 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--798 TJm
-(Compressed) 49.2571 Tj
--280 TJm
-(da) 9.40507 Tj
-1 TJm
-(ta) 7.19329 Tj
--280 TJm
-(created) 28.7632 Tj
--280 TJm
-(by) 9.963 Tj
--279 TJm
-(this) 14.3965 Tj
--280 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--279 TJm
-(is) 6.64532 Tj
--280 TJm
-(entirely) 30.437 Tj
--280 TJm
-(forw) 18.8101 Tj
-11 TJm
-(ards) 16.5984 Tj
-72 503.927 Td
-(and) 14.3866 Tj
--294 TJm
-(backw) 26.0034 Tj
-10 TJm
-(ards) 16.5984 Tj
--294 TJm
-(compatible) 44.2756 Tj
--295 TJm
-(wit) 12.7327 Tj
-1 TJm
-(h) 4.9815 Tj
--295 TJm
-(the) 12.1748 Tj
--294 TJm
-(pre) 12.7228 Tj
-25 TJm
-(vious) 21.5898 Tj
--294 TJm
-(public) 24.9075 Tj
--294 TJm
-(releases,) 34.0236 Tj
--306 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--294 TJm
-(0.1pl2,) 27.6772 Tj
--305 TJm
-(0.9.0) 19.926 Tj
--294 TJm
-(and) 14.3866 Tj
--295 TJm
-(0.9.5,) 22.4168 Tj
--305 TJm
-(1.0.0,) 22.4168 Tj
--305 TJm
-(1.0.1) 19.926 Tj
--295 TJm
-(and) 14.3866 Tj
--294 TJm
-(1.0.2,) 22.4168 Tj
-72 491.972 Td
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--282 TJm
-(with) 17.7142 Tj
--283 TJm
-(the) 12.1748 Tj
--282 TJm
-(follo) 18.8201 Tj
-25 TJm
-(wing) 19.926 Tj
--282 TJm
-(e) 4.42357 Tj
-15 TJm
-(xception:) 37.0823 Tj
--375 TJm
-(0.9.0) 19.926 Tj
--282 TJm
-(and) 14.3866 Tj
--282 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--283 TJm
-(can) 13.8286 Tj
--282 TJm
-(correctly) 35.4085 Tj
--282 TJm
-(decompress) 47.0353 Tj
--282 TJm
-(multiple) 33.2166 Tj
--283 TJm
-(concatena) 39.8321 Tj
-1 TJm
-(ted) 12.1748 Tj
--283 TJm
-(compressed) 47.0353 Tj
--282 TJm
-(\002les.) 19.0991 Tj
-72 480.017 Td
-(0.1pl2) 25.1865 Tj
--250 TJm
-(cannot) 26.5614 Tj
--250 TJm
-(do) 9.963 Tj
--250 TJm
-(this;) 17.1662 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(will) 15.5024 Tj
--249 TJm
-(stop) 16.6083 Tj
--250 TJm
-(after) 18.2522 Tj
--250 TJm
-(decompressing) 59.768 Tj
--250 TJm
-(just) 14.3965 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\002rst) 15.5024 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(strea) 18.8101 Tj
-1 TJm
-(m.) 10.242 Tj
-[1 0 0 1 72 477.86] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -467.897] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 458.099 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 143.731 458.099] cm
-0 g
-0 G
-[1 0 0 1 -143.731 -458.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.174 458.099 Td
-/F128_0 9.963 Tf
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--245 TJm
-(prior) 19.3681 Tj
--245 TJm
-(to) 7.75121 Tj
--245 TJm
-(1.0.2) 19.926 Tj
--245 TJm
-(used) 18.2622 Tj
--245 TJm
-(32-bit) 23.8016 Tj
--245 TJm
-(inte) 14.9445 Tj
-15 TJm
-(gers) 16.5984 Tj
--245 TJm
-(to) 7.75121 Tj
--246 TJm
-(repre) 20.464 Tj
-1 TJm
-(sent) 16.0504 Tj
--246 TJm
-(bit) 10.5209 Tj
--245 TJm
-(positions) 35.9864 Tj
--245 TJm
-(in) 7.75121 Tj
--245 TJm
-(compressed) 47.0353 Tj
--245 TJm
-(\002les,) 19.0991 Tj
--246 TJm
-(so) 8.85711 Tj
--245 TJm
-(it) 5.53943 Tj
--245 TJm
-(could) 22.1378 Tj
-72 446.144 Td
-(not) 12.7327 Tj
--383 TJm
-(handle) 26.5614 Tj
--384 TJm
-(compressed) 47.0353 Tj
--383 TJm
-(\002les) 16.6083 Tj
--384 TJm
-(more) 20.474 Tj
--383 TJm
-(than) 17.1563 Tj
--384 TJm
-(51) 9.963 Tj
-1 TJm
-(2) 4.9815 Tj
--384 TJm
-(me) 12.1748 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(abytes) 25.4555 Tj
--383 TJm
-(long.) 20.205 Tj
--1421 TJm
-(V) 7.19329 Tj
-111 TJm
-(ersions) 28.2252 Tj
--384 TJm
-(1.0.2) 19.926 Tj
--383 TJm
-(and) 14.3866 Tj
--384 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--383 TJm
-(use) 13.2807 Tj
--384 TJm
-(64-bit) 23.8016 Tj
--383 TJm
-(ints) 14.3965 Tj
--384 TJm
-(on) 9.963 Tj
--383 TJm
-(some) 21.0319 Tj
-72 434.189 Td
-(platforms) 38.1882 Tj
--245 TJm
-(which) 24.3496 Tj
--246 TJm
-(su) 8.85711 Tj
-1 TJm
-(pport) 21.0319 Tj
--246 TJm
-(them) 19.926 Tj
--245 TJm
-(\(GNU) 24.8975 Tj
--245 TJm
-(supported) 39.2941 Tj
--246 TJm
-(tar) 10.511 Tj
-18 TJm
-(gets,) 18.5411 Tj
--246 TJm
-(and) 14.3866 Tj
--245 TJm
-(W) 9.40507 Tj
-40 TJm
-(indo) 17.7142 Tj
-25 TJm
-(ws\).) 16.8773 Tj
--309 TJm
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--245 TJm
-(establish) 34.8705 Tj
--245 TJm
-(whether) 32.0908 Tj
--245 TJm
-(or) 8.29918 Tj
--246 TJm
-(not) 12.7327 Tj
-[1 0 0 1 468.269 434.189] cm
-0 g
-0 G
-[1 0 0 1 -468.269 -434.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.269 434.189 Td
-/F130_0 9.963 Tf
-(bzip2recover) 71.7336 Tj
-[1 0 0 1 540 434.189] cm
-0 g
-0 G
-[1 0 0 1 -540 -434.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 422.233 Td
-/F128_0 9.963 Tf
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--255 TJm
-(b) 4.9815 Tj
-20 TJm
-(uilt) 13.2906 Tj
--255 TJm
-(with) 17.7142 Tj
--255 TJm
-(such) 18.2622 Tj
--255 TJm
-(a) 4.42357 Tj
--255 TJm
-(limitation,) 41.2468 Tj
--256 TJm
-(run) 13.2807 Tj
--255 TJm
-(it) 5.53943 Tj
--255 TJm
-(without) 30.4469 Tj
--255 TJm
-(ar) 7.74125 Tj
-18 TJm
-(guments.) 36.2554 Tj
--325 TJm
-(In) 8.29918 Tj
--255 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--255 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
-1 TJm
-(t) 2.76971 Tj
--255 TJm
-(you) 14.9445 Tj
--255 TJm
-(can) 13.8286 Tj
--255 TJm
-(b) 4.9815 Tj
-20 TJm
-(uild) 15.5024 Tj
--255 TJm
-(yourself) 32.6488 Tj
--255 TJm
-(an) 9.40507 Tj
--255 TJm
-(unlimited) 38.1981 Tj
--255 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--255 TJm
-(if) 6.08739 Tj
-72 410.278 Td
-(you) 14.9445 Tj
--250 TJm
-(can) 13.8286 Tj
--250 TJm
-(recompile) 39.842 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(with) 17.7142 Tj
-[1 0 0 1 176.318 410.278] cm
-0 g
-0 G
-[1 0 0 1 -176.318 -410.278] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.318 410.278 Td
-/F130_0 9.963 Tf
-(MaybeUInt64) 65.7558 Tj
-[1 0 0 1 242.071 410.278] cm
-0 g
-0 G
-[1 0 0 1 -242.071 -410.278] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-244.562 410.278 Td
-/F128_0 9.963 Tf
-(set) 11.0689 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(an) 9.40507 Tj
--250 TJm
-(unsigned) 35.9764 Tj
--250 TJm
-(64-bit) 23.8016 Tj
--249 TJm
-(inte) 14.9445 Tj
-15 TJm
-(ger) 12.7228 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 408.121] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -398.159] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 375.525 Td
-/F121_0 20.659 Tf
-(2.9.) 34.4592 Tj
--278 TJm
-(A) 14.9158 Tj
-50 TJm
-(UTHOR) 73.4427 Tj
-[1 0 0 1 72 375.267] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -365.305] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 353.608 Td
-/F128_0 9.963 Tf
-(Julian) 23.8016 Tj
--250 TJm
-(Se) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(ard,) 15.2135 Tj
-[1 0 0 1 132.801 353.608] cm
-0 g
-0 G
-[1 0 0 1 -132.801 -353.608] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-132.801 353.608 Td
-/F130_0 9.963 Tf
-(jseward@bzip.org) 95.6448 Tj
-[1 0 0 1 228.443 353.608] cm
-0 g
-0 G
-[1 0 0 1 -156.443 -1.564] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -342.081] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 331.69 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--299 TJm
-(ideas) 20.474 Tj
--300 TJm
-(embodied) 39.2941 Tj
--299 TJm
-(in) 7.75121 Tj
-[1 0 0 1 166.942 331.69] cm
-0 g
-0 G
-[1 0 0 1 -166.942 -331.69] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.942 331.69 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 196.83 331.69] cm
-0 g
-0 G
-[1 0 0 1 -196.83 -331.69] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.813 331.69 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
--299 TJm
-(due) 14.3866 Tj
--300 TJm
-(to) 7.75121 Tj
--299 TJm
-(\(at) 10.511 Tj
--300 TJm
-(least\)) 21.5799 Tj
--299 TJm
-(the) 12.1748 Tj
--299 TJm
-(follo) 18.8201 Tj
-25 TJm
-(wing) 19.926 Tj
--300 TJm
-(people:) 29.3311 Tj
--408 TJm
-(Michael) 32.6488 Tj
--300 TJm
-(Burro) 23.2437 Tj
-25 TJm
-(ws) 11.0689 Tj
--299 TJm
-(and) 14.3866 Tj
--300 TJm
-(D) 7.19329 Tj
-1 TJm
-(a) 4.42357 Tj
-20 TJm
-(vid) 12.7327 Tj
--300 TJm
-(Wheeler) 33.7447 Tj
--299 TJm
-(\(for) 14.9345 Tj
-72 319.735 Td
-(the) 12.1748 Tj
--312 TJm
-(block) 22.1378 Tj
--313 TJm
-(s) 3.87561 Tj
-1 TJm
-(orting) 23.8016 Tj
--313 TJm
-(transformati) 48.6991 Tj
-1 TJm
-(on\),) 15.7714 Tj
--328 TJm
-(Da) 11.6169 Tj
-20 TJm
-(vid) 12.7327 Tj
--313 TJm
-(Whee) 23.2337 Tj
-1 TJm
-(ler) 10.511 Tj
--313 TJm
-(\(ag) 12.7228 Tj
-5 TJm
-(ain,) 14.6655 Tj
--328 TJm
-(for) 11.6169 Tj
--312 TJm
-(the) 12.1748 Tj
--312 TJm
-(Huf) 15.4925 Tj
-25 TJm
-(fman) 20.474 Tj
--312 TJm
-(coder\),) 27.9363 Tj
--328 TJm
-(Peter) 20.474 Tj
--312 TJm
-(Fenwick) 34.3126 Tj
--313 TJm
-(\(for) 14.9345 Tj
--312 TJm
-(the) 12.1748 Tj
--312 TJm
-(structured) 39.842 Tj
-72 307.779 Td
-(coding) 27.1193 Tj
--325 TJm
-(model) 24.9075 Tj
--326 TJm
-(in) 7.75121 Tj
--325 TJm
-(the) 12.1748 Tj
--326 TJm
-(origin) 23.8016 Tj
-1 TJm
-(al) 7.19329 Tj
-[1 0 0 1 191.156 307.779] cm
-0 g
-0 G
-[1 0 0 1 -191.156 -307.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-191.156 307.779 Td
-/F130_0 9.963 Tf
-(bzip) 23.9112 Tj
-[1 0 0 1 215.067 307.779] cm
-0 g
-0 G
-[1 0 0 1 -215.067 -307.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-215.067 307.779 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--344 TJm
-(and) 14.3866 Tj
--326 TJm
-(man) 17.1563 Tj
-15 TJm
-(y) 4.9815 Tj
--325 TJm
-(re\002nements\),) 52.2958 Tj
--344 TJm
-(and) 14.3866 Tj
--326 TJm
-(Alistair) 29.889 Tj
--325 TJm
-(Mof) 17.1563 Tj
-25 TJm
-(f) 3.31768 Tj
-10 TJm
-(at,) 9.68404 Tj
--344 TJm
-(Radford) 32.6488 Tj
--326 TJm
-(Ne) 11.6169 Tj
-1 TJm
-(al) 7.19329 Tj
--326 TJm
-(and) 14.3866 Tj
--325 TJm
-(Ian) 12.7228 Tj
--326 TJm
-(W) 9.40507 Tj
-40 TJm
-(itten) 17.7142 Tj
--325 TJm
-(\(for) 14.9345 Tj
-72 295.824 Td
-(the) 12.1748 Tj
--277 TJm
-(arithmetic) 40.4 Tj
--277 TJm
-(coder) 22.1278 Tj
--276 TJm
-(in) 7.75121 Tj
--277 TJm
-(the) 12.1748 Tj
--277 TJm
-(original) 30.9949 Tj
-[1 0 0 1 214.171 295.824] cm
-0 g
-0 G
-[1 0 0 1 -214.171 -295.824] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.171 295.824 Td
-/F130_0 9.963 Tf
-(bzip) 23.9112 Tj
-[1 0 0 1 238.082 295.824] cm
-0 g
-0 G
-[1 0 0 1 -238.082 -295.824] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.082 295.824 Td
-/F128_0 9.963 Tf
-(\).) 5.80843 Tj
--782 TJm
-(I) 3.31768 Tj
--276 TJm
-(am) 12.1748 Tj
--277 TJm
-(much) 22.1378 Tj
--277 TJm
-(indebted) 34.3126 Tj
--277 TJm
-(for) 11.6169 Tj
--277 TJm
-(their) 18.2622 Tj
--277 TJm
-(help,) 19.647 Tj
--283 TJm
-(support) 29.889 Tj
--277 TJm
-(and) 14.3866 Tj
--277 TJm
-(advice.) 28.4942 Tj
--781 TJm
-(See) 14.3866 Tj
--277 TJm
-(the) 12.1748 Tj
--277 TJm
-(manual) 29.3311 Tj
-72 283.869 Td
-(in) 7.75121 Tj
--330 TJm
-(the) 12.1748 Tj
--330 TJm
-(source) 26.0034 Tj
--329 TJm
-(distrib) 25.4654 Tj
-20 TJm
-(ution) 20.4839 Tj
--330 TJm
-(for) 11.6169 Tj
--330 TJm
-(pointers) 32.1008 Tj
--330 TJm
-(to) 7.75121 Tj
--330 TJm
-(sour) 17.1563 Tj
-1 TJm
-(ces) 12.7228 Tj
--330 TJm
-(of) 8.29918 Tj
--330 TJm
-(documentation.) 61.7108 Tj
--1099 TJm
-(Christian) 36.5343 Tj
--330 TJm
-(v) 4.9815 Tj
-20 TJm
-(on) 9.963 Tj
--330 TJm
-(Roques) 29.889 Tj
--330 TJm
-(encou) 23.7916 Tj
-1 TJm
-(raged) 22.1278 Tj
--330 TJm
-(me) 12.1748 Tj
--330 TJm
-(to) 7.75121 Tj
--330 TJm
-(look) 17.7142 Tj
-72 271.914 Td
-(for) 11.6169 Tj
--271 TJm
-(f) 3.31768 Tj
-10 TJm
-(aster) 18.8101 Tj
--271 TJm
-(sorting) 27.6772 Tj
--271 TJm
-(algorithms,) 45.1125 Tj
--276 TJm
-(so) 8.85711 Tj
--271 TJm
-(as) 8.29918 Tj
--271 TJm
-(to) 7.75121 Tj
--271 TJm
-(speed) 22.6858 Tj
--271 TJm
-(up) 9.963 Tj
--271 TJm
-(compression.) 52.8537 Tj
--746 TJm
-(Bela) 18.2622 Tj
--271 TJm
-(Lubkin) 28.7831 Tj
--271 TJm
-(encouraged) 45.9195 Tj
--271 TJm
-(me) 12.1748 Tj
--271 TJm
-(to) 7.75121 Tj
--271 TJm
-(impro) 23.8016 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--271 TJm
-(the) 12.1748 Tj
--271 TJm
-(w) 7.19329 Tj
-10 TJm
-(orst-case) 35.4085 Tj
-72 259.959 Td
-(compression) 50.363 Tj
--340 TJm
-(performan) 41.4959 Tj
-1 TJm
-(ce.) 11.3379 Tj
--580 TJm
-(Donna) 26.5614 Tj
--340 TJm
-(Robinson) 38.1981 Tj
--340 TJm
-(XMLise) 33.2067 Tj
-1 TJm
-(d) 4.9815 Tj
--340 TJm
-(the) 12.1748 Tj
--340 TJm
-(documentation.) 61.7108 Tj
--580 TJm
-(Man) 18.2622 Tj
-15 TJm
-(y) 4.9815 Tj
--339 TJm
-(people) 26.5614 Tj
--340 TJm
-(sent) 16.0504 Tj
--340 TJm
-(patches,) 32.3698 Tj
--362 TJm
-(helped) 26.5614 Tj
--340 TJm
-(with) 17.7142 Tj
-72 248.004 Td
-(portability) 41.5158 Tj
--250 TJm
-(problems,) 39.573 Tj
--250 TJm
-(lent) 14.9445 Tj
--250 TJm
-(m) 7.75121 Tj
-1 TJm
-(achines,) 32.3698 Tj
--250 TJm
-(g) 4.9815 Tj
-5 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(advice) 26.0034 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(were) 19.3581 Tj
--250 TJm
-(generally) 37.0723 Tj
--250 TJm
-(helpful.) 30.7159 Tj
-[1 0 0 1 72 245.847] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -194.995] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.585] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.063 -6.486] cm
-0 g
-0 G
-[1 0 0 1 -496.332 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.951 Td
-/F128_0 9.963 Tf
-(7) 4.9815 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 11 11
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 4.384 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 141.644 0] cm
-0 g
-0 G
-[1 0 0 1 -141.644 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -13.948] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -15.037 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F121_0 24.79 Tf
-(3.) 20.6749 Tj
--556 TJm
-(Pr) 26.1782 Tj
-20 TJm
-(ogramming) 134.982 Tj
--278 TJm
-(with) 49.58 Tj
-[1 0 0 1 330.484 701.916] cm
-0 g
-0 G
-[1 0 0 1 -330.484 -701.916] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.484 701.916 Td
-/F387_0 24.79 Tf
-(libbzip2) 118.992 Tj
-[1 0 0 1 449.477 701.916] cm
-0 g
-0 G
-[1 0 0 1 -377.477 -5.516] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -14.944] cm
-0 g
-0 G
-[1 0 0 1 -72 -671.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 656.35 Td
-/F121_0 17.215 Tf
-(T) 10.5184 Tj
-80 TJm
-(ab) 20.0899 Tj
-10 TJm
-(le) 14.3573 Tj
--278 TJm
-(of) 16.251 Tj
--278 TJm
-(Contents) 74.5926 Tj
-[1 0 0 1 72 647.528] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.74] cm
-0 g
-0 G
-[1 0 0 1 -72 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 635.788 Td
-/F128_0 9.963 Tf
-(3.1.) 14.9445 Tj
--310 TJm
-(T) 6.08739 Tj
-80 TJm
-(op-le) 20.474 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(structure) 34.8605 Tj
-[1 0 0 1 164.921 635.788] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -169.902 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.997 635.788 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 635.788] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 635.788 Td
-/F128_0 9.963 Tf
-(8) 4.9815 Tj
-[1 0 0 1 516.09 635.788] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 623.832 Td
-/F128_0 9.963 Tf
-(3.1.1.) 22.4168 Tj
--310 TJm
-(Lo) 11.0689 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(summary) 37.0823 Tj
-[1 0 0 1 225.195 623.832] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -230.176 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.915 623.832 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 623.832] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 623.832 Td
-/F128_0 9.963 Tf
-(9) 4.9815 Tj
-[1 0 0 1 516.09 623.832] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 611.877 Td
-/F128_0 9.963 Tf
-(3.1.2.) 22.4168 Tj
--310 TJm
-(High-le) 30.437 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(summary) 37.0823 Tj
-[1 0 0 1 227.107 611.877] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -232.089 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-242.085 611.877 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 611.877] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 611.877 Td
-/F128_0 9.963 Tf
-(9) 4.9815 Tj
-[1 0 0 1 516.09 611.877] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 599.922 Td
-/F128_0 9.963 Tf
-(3.1.3.) 22.4168 Tj
--310 TJm
-(Utility) 26.0234 Tj
--250 TJm
-(functions) 37.0823 Tj
--250 TJm
-(sum) 16.6083 Tj
-1 TJm
-(mary) 20.474 Tj
-[1 0 0 1 250.489 599.922] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -255.471 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.846 599.922 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 511.108 599.922] cm
-0 g
-0 G
-[1 0 0 1 -511.108 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 599.922 Td
-/F128_0 9.963 Tf
-(9) 4.9815 Tj
-[1 0 0 1 516.09 599.922] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 587.967 Td
-/F128_0 9.963 Tf
-(3.2.) 14.9445 Tj
--310 TJm
-(Error) 21.0219 Tj
--250 TJm
-(handling) 34.8705 Tj
-[1 0 0 1 148.413 587.967] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -153.394 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-162.611 587.967 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 587.967] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 587.967 Td
-/F128_0 9.963 Tf
-(10) 9.963 Tj
-[1 0 0 1 516.09 587.967] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 576.012 Td
-/F128_0 9.963 Tf
-(3.3.) 14.9445 Tj
--310 TJm
-(Lo) 11.0689 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
-[1 0 0 1 167.571 576.012] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -172.552 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.045 576.012 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 576.012] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 576.012 Td
-/F128_0 9.963 Tf
-(11) 9.963 Tj
-[1 0 0 1 516.09 576.012] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -0.1] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -11.855] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -564.057] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 564.057 Td
-/F128_0 9.963 Tf
-(3.3.1.) 22.4168 Tj
--310 TJm
-(BZ2_bzCompressInit) 85.7914 Tj
-[1 0 0 1 231.112 564.057] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -236.094 -564.057] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.025 564.057 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 564.057] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -564.057] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 564.057 Td
-/F128_0 9.963 Tf
-(11) 9.963 Tj
-[1 0 0 1 516.09 564.057] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 552.101 Td
-/F128_0 9.963 Tf
-(3.3.2.) 22.4168 Tj
--310 TJm
-(BZ2_bzCompress) 71.9528 Tj
-[1 0 0 1 217.275 552.101] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -222.256 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.464 552.101 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 552.101] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 552.101 Td
-/F128_0 9.963 Tf
-(13) 9.963 Tj
-[1 0 0 1 516.09 552.101] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 540.146 Td
-/F128_0 9.963 Tf
-(3.3.3.) 22.4168 Tj
--310 TJm
-(BZ2_bzCompressEnd) 88.0032 Tj
-[1 0 0 1 233.324 540.146] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -238.306 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-247.131 540.146 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 540.146] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 540.146 Td
-/F128_0 9.963 Tf
-(16) 9.963 Tj
-[1 0 0 1 516.09 540.146] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -528.191] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 528.191 Td
-/F128_0 9.963 Tf
-(3.3.4.) 22.4168 Tj
--310 TJm
-(BZ2_bzDecompressIni) 92.4168 Tj
-1 TJm
-(t) 2.76971 Tj
-[1 0 0 1 240.507 528.191] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -245.488 -528.191] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.15 528.191 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 528.191] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -528.191] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 528.191 Td
-/F128_0 9.963 Tf
-(16) 9.963 Tj
-[1 0 0 1 516.09 528.191] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -516.236] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 516.236 Td
-/F128_0 9.963 Tf
-(3.3.5.) 22.4168 Tj
--310 TJm
-(BZ2_bzDecompress) 81.3479 Tj
-[1 0 0 1 226.669 516.236] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -231.651 -516.236] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-241.589 516.236 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 516.236] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -516.236] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 516.236 Td
-/F128_0 9.963 Tf
-(17) 9.963 Tj
-[1 0 0 1 516.09 516.236] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -504.281] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 504.281 Td
-/F128_0 9.963 Tf
-(3.3.6.) 22.4168 Tj
--310 TJm
-(BZ2_bzDecompressEn) 92.4168 Tj
-1 TJm
-(d) 4.9815 Tj
-[1 0 0 1 242.719 504.281] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -247.7 -504.281] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.256 504.281 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 504.281] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -504.281] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 504.281 Td
-/F128_0 9.963 Tf
-(18) 9.963 Tj
-[1 0 0 1 516.09 504.281] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -492.326] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 492.326 Td
-/F128_0 9.963 Tf
-(3.4.) 14.9445 Tj
--310 TJm
-(High-le) 30.437 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
-[1 0 0 1 169.483 492.326] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -174.465 -492.326] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-184.216 492.326 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 492.326] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -492.326] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 492.326 Td
-/F128_0 9.963 Tf
-(18) 9.963 Tj
-[1 0 0 1 516.09 492.326] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -480.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 480.37 Td
-/F128_0 9.963 Tf
-(3.4.1.) 22.4168 Tj
--310 TJm
-(BZ2_bzReadOpen) 74.1546 Tj
-[1 0 0 1 219.476 480.37] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -224.458 -480.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-233.565 480.37 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 480.37] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -480.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 480.37 Td
-/F128_0 9.963 Tf
-(19) 9.963 Tj
-[1 0 0 1 516.09 480.37] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -468.415] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 468.415 Td
-/F128_0 9.963 Tf
-(3.4.2.) 22.4168 Tj
--310 TJm
-(BZ2_bzRead) 52.5748 Tj
-[1 0 0 1 197.898 468.415] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -202.879 -468.415] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.706 468.415 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 468.415] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -468.415] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 468.415 Td
-/F128_0 9.963 Tf
-(20) 9.963 Tj
-[1 0 0 1 516.09 468.415] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.18] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.775] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -456.46] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 456.46 Td
-/F128_0 9.963 Tf
-(3.4.3.) 22.4168 Tj
--310 TJm
-(BZ2_bzReadGetUnuse) 92.4168 Tj
-1 TJm
-(d) 4.9815 Tj
-[1 0 0 1 242.719 456.46] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -247.7 -456.46] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.256 456.46 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 456.46] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -456.46] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 456.46 Td
-/F128_0 9.963 Tf
-(21) 9.963 Tj
-[1 0 0 1 516.09 456.46] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.181] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.774] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -444.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 444.505 Td
-/F128_0 9.963 Tf
-(3.4.4.) 22.4168 Tj
--310 TJm
-(BZ2_bzReadClose) 75.2705 Tj
-[1 0 0 1 220.592 444.505] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -225.573 -444.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.123 444.505 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 444.505] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -444.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 444.505 Td
-/F128_0 9.963 Tf
-(22) 9.963 Tj
-[1 0 0 1 516.09 444.505] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.181] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.774] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -432.55] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 432.55 Td
-/F128_0 9.963 Tf
-(3.4.5.) 22.4168 Tj
--310 TJm
-(BZ2_bzWriteOpen) 76.3664 Tj
-[1 0 0 1 221.688 432.55] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -226.669 -432.55] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.885 432.55 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 432.55] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -432.55] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 432.55 Td
-/F128_0 9.963 Tf
-(22) 9.963 Tj
-[1 0 0 1 516.09 432.55] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -420.595] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 420.595 Td
-/F128_0 9.963 Tf
-(3.4.6.) 22.4168 Tj
--310 TJm
-(BZ2_bzWrite) 54.7865 Tj
-[1 0 0 1 200.109 420.595] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -205.09 -420.595] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-215.026 420.595 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 420.595] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -420.595] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 420.595 Td
-/F128_0 9.963 Tf
-(23) 9.963 Tj
-[1 0 0 1 516.09 420.595] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.181] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.775] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -408.639] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 408.639 Td
-/F128_0 9.963 Tf
-(3.4.7.) 22.4168 Tj
--310 TJm
-(BZ2_bzWriteClose) 77.4823 Tj
-[1 0 0 1 222.804 408.639] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -227.785 -408.639] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.443 408.639 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 408.639] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -408.639] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 408.639 Td
-/F128_0 9.963 Tf
-(23) 9.963 Tj
-[1 0 0 1 516.09 408.639] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -1.18] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -10.775] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -396.684] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 396.684 Td
-/F128_0 9.963 Tf
-(3.4.8.) 22.4168 Tj
--310 TJm
-(Handling) 37.0823 Tj
--250 TJm
-(embedded) 40.9479 Tj
--250 TJm
-(com) 17.1563 Tj
-1 TJm
-(pressed) 29.879 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(streams) 30.437 Tj
-[1 0 0 1 327.38 396.684] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -332.362 -396.684] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-342.865 396.684 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 396.684] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -396.684] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 396.684 Td
-/F128_0 9.963 Tf
-(24) 9.963 Tj
-[1 0 0 1 516.09 396.684] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -384.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 384.729 Td
-/F128_0 9.963 Tf
-(3.4.9.) 22.4168 Tj
--310 TJm
-(Standard) 35.4185 Tj
--250 TJm
-(\002le-reading/) 48.6991 Tj
-1 TJm
-(writing) 28.7831 Tj
--250 TJm
-(code) 18.8101 Tj
-[1 0 0 1 282.011 384.729] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -286.992 -384.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-295.827 384.729 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 384.729] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -384.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 384.729 Td
-/F128_0 9.963 Tf
-(25) 9.963 Tj
-[1 0 0 1 516.09 384.729] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -372.774] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 372.774 Td
-/F128_0 9.963 Tf
-(3.5.) 14.9445 Tj
--310 TJm
-(Utility) 26.0234 Tj
--250 TJm
-(functions) 37.0823 Tj
-[1 0 0 1 155.625 372.774] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -160.607 -372.774] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.645 372.774 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 372.774] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -372.774] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 372.774 Td
-/F128_0 9.963 Tf
-(26) 9.963 Tj
-[1 0 0 1 516.09 372.774] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -360.819] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 360.819 Td
-/F128_0 9.963 Tf
-(3.5.1.) 22.4168 Tj
--310 TJm
-(BZ2_bzBuf) 47.0453 Tj
-25 TJm
-(fT) 9.40507 Tj
-80 TJm
-(oBuf) 19.926 Tj
-25 TJm
-(fCom) 22.6957 Tj
-1 TJm
-(press) 20.474 Tj
-[1 0 0 1 263.571 360.819] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -268.552 -360.819] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.751 360.819 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 360.819] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -360.819] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 360.819 Td
-/F128_0 9.963 Tf
-(26) 9.963 Tj
-[1 0 0 1 516.09 360.819] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -348.864] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 348.864 Td
-/F128_0 9.963 Tf
-(3.5.2.) 22.4168 Tj
--310 TJm
-(BZ2_bzBuf) 47.0453 Tj
-25 TJm
-(fT) 9.40507 Tj
-80 TJm
-(oBuf) 19.926 Tj
-25 TJm
-(fDeco) 24.3396 Tj
-1 TJm
-(mpress) 28.2252 Tj
-[1 0 0 1 272.965 348.864] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -277.947 -348.864] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-286.876 348.864 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 348.864] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -348.864] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 348.864 Td
-/F128_0 9.963 Tf
-(27) 9.963 Tj
-[1 0 0 1 516.09 348.864] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -72 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 336.908 Td
-/F128_0 9.963 Tf
-(3.6.) 14.9445 Tj
--310 TJm
-(zlib) 14.9445 Tj
--250 TJm
-(compatibility) 53.1426 Tj
--250 TJm
-(funct) 20.474 Tj
-1 TJm
-(ions) 16.6083 Tj
-[1 0 0 1 200.178 336.908] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -205.159 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-215.06 336.908 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 336.908] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 336.908 Td
-/F128_0 9.963 Tf
-(28) 9.963 Tj
-[1 0 0 1 516.09 336.908] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.156] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.799] cm
-0 g
-0 G
-[1 0 0 1 -72 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 324.953 Td
-/F128_0 9.963 Tf
-(3.7.) 14.9445 Tj
--310 TJm
-(Using) 23.8016 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(library) 26.5614 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(std) 11.6268 Tj
-1 TJm
-(io-free) 26.5514 Tj
--250 TJm
-(en) 9.40507 Tj
-40 TJm
-(vironment) 40.9579 Tj
-[1 0 0 1 267.824 324.953] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -272.805 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.092 324.953 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 324.953] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 324.953 Td
-/F128_0 9.963 Tf
-(28) 9.963 Tj
-[1 0 0 1 516.09 324.953] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -312.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 312.998 Td
-/F128_0 9.963 Tf
-(3.7.1.) 22.4168 Tj
--310 TJm
-(Getting) 29.889 Tj
--250 TJm
-(rid) 11.0689 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(stdio) 19.378 Tj
-[1 0 0 1 221.429 312.998] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -226.41 -312.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.755 312.998 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 312.998] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -312.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 312.998 Td
-/F128_0 9.963 Tf
-(29) 9.963 Tj
-[1 0 0 1 516.09 312.998] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 47.821 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -301.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 301.043 Td
-/F128_0 9.963 Tf
-(3.7.2.) 22.4168 Tj
--310 TJm
-(Critical) 29.889 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(handlin) 29.889 Tj
-1 TJm
-(g) 4.9815 Tj
-[1 0 0 1 234.42 301.043] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -239.401 -301.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-249.892 301.043 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 301.043] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -301.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 301.043 Td
-/F128_0 9.963 Tf
-(29) 9.963 Tj
-[1 0 0 1 516.09 301.043] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -289.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 289.088 Td
-/F128_0 9.963 Tf
-(3.8.) 14.9445 Tj
--310 TJm
-(Making) 30.9949 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(W) 9.40507 Tj
-40 TJm
-(indo) 17.7142 Tj
-25 TJm
-(ws) 11.0689 Tj
--250 TJm
-(DLL) 19.3681 Tj
-[1 0 0 1 189.827 289.088] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -194.809 -289.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.243 289.088 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 289.088] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -289.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 289.088 Td
-/F128_0 9.963 Tf
-(29) 9.963 Tj
-[1 0 0 1 516.09 289.088] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -267.006] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 257.207 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--250 TJm
-(chapter) 29.3211 Tj
--250 TJm
-(describes) 37.0723 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(pr) 8.29918 Tj
-1 TJm
-(ogramming) 45.9394 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 282.448 257.207] cm
-0 g
-0 G
-[1 0 0 1 -282.448 -257.207] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.448 257.207 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 330.269 257.207] cm
-0 g
-0 G
-[1 0 0 1 -330.269 -257.207] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.269 257.207 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 255.05] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -245.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 235.289 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--273 TJm
-(general) 29.3211 Tj
--272 TJm
-(background) 47.0353 Tj
--273 TJm
-(informati) 37.0823 Tj
-1 TJm
-(on,) 12.4538 Tj
--279 TJm
-(particularly) 45.9294 Tj
--272 TJm
-(about) 22.1378 Tj
--273 TJm
-(memory) 33.2067 Tj
--272 TJm
-(use) 13.2807 Tj
--273 TJm
-(and) 14.3866 Tj
--273 TJm
-(perfor) 24.3396 Tj
-1 TJm
-(mance) 26.0034 Tj
--273 TJm
-(aspects,) 31.2639 Tj
--278 TJm
-(you') 18.2622 Tj
-50 TJm
-(d) 4.9815 Tj
--273 TJm
-(be) 9.40507 Tj
--272 TJm
-(well) 17.1563 Tj
--273 TJm
-(advised) 30.437 Tj
-72 223.334 Td
-(to) 7.75121 Tj
--250 TJm
-(read) 17.1463 Tj
-[1 0 0 1 101.878 223.334] cm
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -101.878 -223.334] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-101.878 223.334 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 171.636 223.334] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -171.636 -223.334] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-174.126 223.334 Td
-/F128_0 9.963 Tf
-([2]) 11.6169 Tj
-[1 0 0 1 185.743 223.334] cm
-0 0 1 rg
-0 0 1 RG
-0 g
-0 G
-[1 0 0 1 -185.743 -223.334] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.233 223.334 Td
-/F128_0 9.963 Tf
-(as) 8.29918 Tj
--250 TJm
-(well.) 19.647 Tj
-[1 0 0 1 72 221.177] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -211.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 188.581 Td
-/F121_0 20.659 Tf
-(3.1.) 34.4592 Tj
--278 TJm
-(T) 12.6226 Tj
-80 TJm
-(op-le) 49.3544 Tj
-15 TJm
-(vel) 28.716 Tj
--278 TJm
-(structure) 89.5361 Tj
-[1 0 0 1 72 184.305] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -174.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 166.664 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 119.821 166.664] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -166.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.608 166.664 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--380 TJm
-(a) 4.42357 Tj
--380 TJm
-(\003e) 9.963 Tj
-15 TJm
-(xible) 19.926 Tj
--380 TJm
-(library) 26.5614 Tj
--380 TJm
-(for) 11.6169 Tj
--381 TJm
-(com) 17.1563 Tj
-1 TJm
-(pressing) 33.2067 Tj
--381 TJm
-(an) 9.40507 Tj
-1 TJm
-(d) 4.9815 Tj
--381 TJm
-(decompre) 39.2841 Tj
-1 TJm
-(ssing) 20.4839 Tj
--381 TJm
-(data) 16.5984 Tj
--380 TJm
-(in) 7.75121 Tj
--380 TJm
-(the) 12.1748 Tj
-[1 0 0 1 405.291 166.664] cm
-0 g
-0 G
-[1 0 0 1 -405.291 -166.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.291 166.664 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 435.179 166.664] cm
-0 g
-0 G
-[1 0 0 1 -435.179 -166.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.966 166.664 Td
-/F128_0 9.963 Tf
-(data) 16.5984 Tj
--380 TJm
-(format.) 29.0521 Tj
--1401 TJm
-(Although) 37.6402 Tj
-72 154.708 Td
-(packaged) 37.6203 Tj
--285 TJm
-(as) 8.29918 Tj
--284 TJm
-(a) 4.42357 Tj
--285 TJm
-(single) 23.8016 Tj
--284 TJm
-(entity) 22.6957 Tj
-65 TJm
-(,) 2.49075 Tj
--294 TJm
-(it) 5.53943 Tj
--284 TJm
-(helps) 21.0319 Tj
--285 TJm
-(to) 7.75121 Tj
--285 TJm
-(re) 7.74125 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(ard) 12.7228 Tj
--284 TJm
-(the) 12.1748 Tj
--285 TJm
-(library) 26.5614 Tj
--285 TJm
-(a) 4.42357 Tj
-1 TJm
-(s) 3.87561 Tj
--285 TJm
-(three) 19.916 Tj
--285 TJm
-(separate) 32.6388 Tj
--284 TJm
-(parts:) 22.1378 Tj
--380 TJm
-(the) 12.1748 Tj
--284 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w) 7.19329 Tj
--285 TJm
-(le) 7.19329 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--285 TJm
-(i) 2.76971 Tj
-1 TJm
-(nterf) 18.8101 Tj
-10 TJm
-(ace,) 15.7615 Tj
--294 TJm
-(and) 14.3866 Tj
--284 TJm
-(the) 12.1748 Tj
--285 TJm
-(high) 17.7142 Tj
-72 142.753 Td
-(le) 7.19329 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace,) 15.7615 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(some) 21.0319 Tj
--250 TJm
-(uti) 10.5209 Tj
-1 TJm
-(lity) 13.2906 Tj
--250 TJm
-(functions.) 39.573 Tj
-[1 0 0 1 72 140.596] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -130.634] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 120.835 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--349 TJm
-(structure) 34.8605 Tj
--349 TJm
-(of) 8.29918 Tj
-[1 0 0 1 141.082 120.835] cm
-0 g
-0 G
-[1 0 0 1 -141.082 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-141.082 120.835 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 188.903 120.835] cm
-0 g
-0 G
-[1 0 0 1 -188.903 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.903 120.835 Td
-/F128_0 9.963 Tf
-(') 3.31768 Tj
-55 TJm
-(s) 3.87561 Tj
--349 TJm
-(interf) 21.5799 Tj
-10 TJm
-(aces) 17.1463 Tj
--349 TJm
-(is) 6.64532 Tj
--349 TJm
-(similar) 27.6772 Tj
--349 TJm
-(to) 7.75121 Tj
--349 TJm
-(that) 14.9445 Tj
--349 TJm
-(of) 8.29918 Tj
--349 TJm
-(Jean-loup) 38.7361 Tj
--349 TJm
-(Gailly') 28.2252 Tj
-55 TJm
-(s) 3.87561 Tj
--349 TJm
-(an) 9.40507 Tj
-1 TJm
-(d) 4.9815 Tj
--350 TJm
-(M) 8.85711 Tj
-1 TJm
-(ark) 12.7228 Tj
--349 TJm
-(Adler') 26.0034 Tj
-55 TJm
-(s) 3.87561 Tj
--349 TJm
-(e) 4.42357 Tj
-15 TJm
-(xcellent) 31.5429 Tj
-[1 0 0 1 516.09 120.835] cm
-0 g
-0 G
-[1 0 0 1 -516.09 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.09 120.835 Td
-/F130_0 9.963 Tf
-(zlib) 23.9112 Tj
-[1 0 0 1 540 120.835] cm
-0 g
-0 G
-[1 0 0 1 -540 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 108.88 Td
-/F128_0 9.963 Tf
-(library) 26.5614 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 106.723] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -96.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 86.962 Td
-/F128_0 9.963 Tf
-(All) 12.7327 Tj
--242 TJm
-(e) 4.42357 Tj
-15 TJm
-(xternally) 35.4185 Tj
--241 TJm
-(visible) 26.5713 Tj
--242 TJm
-(symbols) 33.2166 Tj
--242 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--241 TJm
-(names) 25.4555 Tj
--242 TJm
-(be) 9.40507 Tj
-15 TJm
-(ginning) 30.4469 Tj
-[1 0 0 1 284.687 86.962] cm
-0 g
-0 G
-[1 0 0 1 -284.687 -86.962] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.687 86.962 Td
-/F130_0 9.963 Tf
-(BZ2_) 23.9112 Tj
-[1 0 0 1 308.597 86.962] cm
-0 g
-0 G
-[1 0 0 1 -308.597 -86.962] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.597 86.962 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--615 TJm
-(T) 6.08739 Tj
-1 TJm
-(his) 11.6268 Tj
--242 TJm
-(is) 6.64532 Tj
--242 TJm
-(ne) 9.40507 Tj
-25 TJm
-(w) 7.19329 Tj
--242 TJm
-(in) 7.75121 Tj
--241 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--242 TJm
-(1.0.) 14.9445 Tj
--615 TJm
-(The) 15.4925 Tj
--241 TJm
-(intention) 35.4284 Tj
--242 TJm
-(is) 6.64532 Tj
--242 TJm
-(to) 7.75121 Tj
--241 TJm
-(minimise) 37.0922 Tj
-72 75.007 Td
-(pollution) 35.9864 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(namespaces) 47.5833 Tj
--249 TJm
-(of) 8.29918 Tj
--250 TJm
-(library) 26.5614 Tj
--250 TJm
-(clients.) 28.5041 Tj
-[1 0 0 1 72 72.85] cm
-0 g
-0 G
-[1 0 0 1 0 -21.998] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 4.384 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.064 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -498.225 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-541.288 50.951 Td
-/F128_0 9.963 Tf
-(8) 4.9815 Tj
-[1 0 0 1 455.161 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.599 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -15.037 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 12 12
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 4.384 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -352.044 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-436.124 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip) 27.6772 Tj
-1 TJm
-(2) 4.9815 Tj
-[1 0 0 1 267.964 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -15.037 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--250 TJm
-(part) 15.4925 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(yo) 9.963 Tj
-1 TJm
-(u) 4.9815 Tj
--250 TJm
-(need) 18.8101 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 240.567 710.037] cm
-0 g
-0 G
-[1 0 0 1 -240.567 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-240.567 710.037 Td
-/F130_0 9.963 Tf
-(#include) 47.8224 Tj
--600 TJm
-(<bzlib.h>) 53.8002 Tj
-[1 0 0 1 348.163 710.037] cm
-0 g
-0 G
-[1 0 0 1 -348.163 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-350.654 710.037 Td
-/F128_0 9.963 Tf
-(into) 15.5024 Tj
--250 TJm
-(your) 18.2622 Tj
--250 TJm
-(sources.) 32.3698 Tj
-[1 0 0 1 72 707.881] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -697.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 679.416 Td
-/F121_0 17.215 Tf
-(3.1.1.) 43.0719 Tj
--278 TJm
-(Lo) 21.0367 Tj
-15 TJm
-(w-le) 33.4832 Tj
-15 TJm
-(vel) 23.9289 Tj
--278 TJm
-(summar) 66.9664 Tj
--10 TJm
-(y) 9.57154 Tj
-[1 0 0 1 72 675.853] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -665.89] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 657.498 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--212 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
--212 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vides) 21.0319 Tj
--211 TJm
-(services) 32.0908 Tj
--212 TJm
-(for) 11.6169 Tj
--212 TJm
-(compressing) 50.363 Tj
--212 TJm
-(and) 14.3866 Tj
--212 TJm
-(decompressi) 49.805 Tj
-1 TJm
-(ng) 9.963 Tj
--212 TJm
-(data) 16.5984 Tj
--212 TJm
-(in) 7.75121 Tj
--212 TJm
-(memory) 33.2067 Tj
-65 TJm
-(.) 2.49075 Tj
--595 TJm
-(There') 26.5514 Tj
-55 TJm
-(s) 3.87561 Tj
--211 TJm
-(no) 9.963 Tj
--212 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vision) 24.3595 Tj
--212 TJm
-(for) 11.6169 Tj
--212 TJm
-(dealing) 29.3311 Tj
-72 645.543 Td
-(with) 17.7142 Tj
--213 TJm
-(\002les,) 19.0991 Tj
--220 TJm
-(streams) 30.437 Tj
--213 TJm
-(or) 8.29918 Tj
--213 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--213 TJm
-(other) 20.474 Tj
--213 TJm
-(I/O) 13.2807 Tj
--213 TJm
-(mechanisms,) 51.7478 Tj
--220 TJm
-(just) 14.3965 Tj
--213 TJm
-(straight) 29.889 Tj
--213 TJm
-(memory-to-memory) 80.7999 Tj
--213 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork.) 15.7714 Tj
--595 TJm
-(In) 8.29918 Tj
--213 TJm
-(f) 3.31768 Tj
-10 TJm
-(act,) 14.1076 Tj
--220 TJm
-(this) 14.3965 Tj
--213 TJm
-(part) 15.4925 Tj
--213 TJm
-(of) 8.29918 Tj
--213 TJm
-(the) 12.1748 Tj
--213 TJm
-(library) 26.5614 Tj
-72 633.588 Td
-(can) 13.8286 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(compiled) 37.0823 Tj
--250 TJm
-(without) 30.4469 Tj
--250 TJm
-(incl) 14.9445 Tj
-1 TJm
-(usion) 21.5898 Tj
--250 TJm
-(of) 8.29918 Tj
-[1 0 0 1 222.534 633.588] cm
-0 g
-0 G
-[1 0 0 1 -222.534 -633.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-222.534 633.588 Td
-/F130_0 9.963 Tf
-(stdio.h) 41.8446 Tj
-[1 0 0 1 264.377 633.588] cm
-0 g
-0 G
-[1 0 0 1 -264.377 -633.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.377 633.588 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(may) 17.1563 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(helpful) 28.2252 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(emb) 17.1563 Tj
-1 TJm
-(edded) 23.7916 Tj
--250 TJm
-(applications.) 50.6419 Tj
-[1 0 0 1 72 631.431] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -621.469] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 611.67 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--250 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(part) 15.4925 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(libra) 18.2622 Tj
-1 TJm
-(ry) 8.29918 Tj
--250 TJm
-(has) 13.2807 Tj
--250 TJm
-(no) 9.963 Tj
--250 TJm
-(global) 24.9075 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(ariables) 30.9849 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(therefore) 35.9565 Tj
--250 TJm
-(thread-safe.) 46.7464 Tj
-[1 0 0 1 72 609.513] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -599.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 589.752 Td
-/F128_0 9.963 Tf
-(Six) 13.2906 Tj
--875 TJm
-(routines) 32.1008 Tj
--876 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--875 TJm
-(up) 9.963 Tj
--875 TJm
-(the) 12.1748 Tj
--876 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w) 7.19329 Tj
--875 TJm
-(le) 7.19329 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--875 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace:) 16.0404 Tj
-[1 0 0 1 308.791 589.752] cm
-0 g
-0 G
-[1 0 0 1 -308.791 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.791 589.752 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 416.387 589.752] cm
-0 g
-0 G
-[1 0 0 1 -416.387 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-416.387 589.752 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 429.158 589.752] cm
-0 g
-0 G
-[1 0 0 1 -429.158 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.158 589.752 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 512.844 589.752] cm
-0 g
-0 G
-[1 0 0 1 -512.844 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-512.844 589.752 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--1032 TJm
-(and) 14.3866 Tj
-[1 0 0 1 72 577.797] cm
-0 g
-0 G
-[1 0 0 1 -72 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 577.797 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressEnd) 101.623 Tj
-[1 0 0 1 173.619 577.797] cm
-0 g
-0 G
-[1 0 0 1 -173.619 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-186.15 577.797 Td
-/F128_0 9.963 Tf
-(for) 11.6169 Tj
--1258 TJm
-(compression,) 52.8537 Tj
--1509 TJm
-(and) 14.3866 Tj
--1258 TJm
-(a) 4.42357 Tj
--1258 TJm
-(correspond) 44.2656 Tj
-1 TJm
-(ing) 12.7327 Tj
--1258 TJm
-(trio) 13.8386 Tj
-[1 0 0 1 417.958 577.797] cm
-0 g
-0 G
-[1 0 0 1 -417.958 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-417.958 577.797 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressInit) 119.556 Tj
-[1 0 0 1 537.509 577.797] cm
-0 g
-0 G
-[1 0 0 1 -537.509 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 577.797 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 72 565.842] cm
-0 g
-0 G
-[1 0 0 1 -72 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 565.842 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 167.641 565.842] cm
-0 g
-0 G
-[1 0 0 1 -167.641 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.707 565.842 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 192.158 565.842] cm
-0 g
-0 G
-[1 0 0 1 -192.158 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.158 565.842 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressEnd) 113.578 Tj
-[1 0 0 1 305.732 565.842] cm
-0 g
-0 G
-[1 0 0 1 -305.732 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.798 565.842 Td
-/F128_0 9.963 Tf
-(for) 11.6169 Tj
--508 TJm
-(decompression.) 62.2588 Tj
--2171 TJm
-(The) 15.4925 Tj
-[1 0 0 1 431.918 565.842] cm
-0 g
-0 G
-[1 0 0 1 -431.918 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.918 565.842 Td
-/F130_0 9.963 Tf
-(*Init) 29.889 Tj
-[1 0 0 1 461.805 565.842] cm
-0 g
-0 G
-[1 0 0 1 -461.805 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-466.871 565.842 Td
-/F128_0 9.963 Tf
-(functions) 37.0823 Tj
--508 TJm
-(allocate) 30.9849 Tj
-72 553.887 Td
-(memory) 33.2067 Tj
--574 TJm
-(f) 3.31768 Tj
-1 TJm
-(or) 8.29918 Tj
--574 TJm
-(compression/decompression) 112.901 Tj
--573 TJm
-(and) 14.3866 Tj
--574 TJm
-(do) 9.963 Tj
--573 TJm
-(other) 20.474 Tj
--574 TJm
-(initialisations,) 56.1913 Tj
--654 TJm
-(whilst) 24.3595 Tj
--574 TJm
-(the) 12.1748 Tj
-[1 0 0 1 419.503 553.887] cm
-0 g
-0 G
-[1 0 0 1 -419.503 -553.887] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.503 553.887 Td
-/F130_0 9.963 Tf
-(*End) 23.9112 Tj
-[1 0 0 1 443.413 553.887] cm
-0 g
-0 G
-[1 0 0 1 -443.413 -553.887] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.128 553.887 Td
-/F128_0 9.963 Tf
-(functions) 37.0823 Tj
--573 TJm
-(close) 20.474 Tj
--574 TJm
-(do) 9.963 Tj
-25 TJm
-(wn) 12.1748 Tj
-72 541.932 Td
-(operations) 41.5059 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(release) 27.6573 Tj
--250 TJm
-(mem) 19.926 Tj
-1 TJm
-(ory) 13.2807 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 539.775] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -529.812] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 520.014 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--303 TJm
-(real) 14.9345 Tj
--303 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--303 TJm
-(is) 6.64532 Tj
--303 TJm
-(done) 19.3681 Tj
--303 TJm
-(by) 9.963 Tj
-[1 0 0 1 176.892 520.014] cm
-0 g
-0 G
-[1 0 0 1 -176.892 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.892 520.014 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 260.578 520.014] cm
-0 g
-0 G
-[1 0 0 1 -260.578 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.598 520.014 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 281.003 520.014] cm
-0 g
-0 G
-[1 0 0 1 -281.003 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-281.003 520.014 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 376.645 520.014] cm
-0 g
-0 G
-[1 0 0 1 -376.645 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-376.645 520.014 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--938 TJm
-(These) 23.7916 Tj
--303 TJm
-(compress) 37.6303 Tj
--303 TJm
-(and) 14.3866 Tj
--303 TJm
-(decompress) 47.0353 Tj
--303 TJm
-(data) 16.5984 Tj
-72 508.059 Td
-(from) 19.3681 Tj
--205 TJm
-(a) 4.42357 Tj
--205 TJm
-(user) 16.5984 Tj
-20 TJm
-(-supplied) 37.0823 Tj
--205 TJm
-(input) 20.4839 Tj
--205 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--205 TJm
-(to) 7.75121 Tj
--205 TJm
-(a) 4.42357 Tj
--206 TJm
-(use) 13.2807 Tj
-1 TJm
-(r) 3.31768 Tj
-20 TJm
-(-supplied) 37.0823 Tj
--205 TJm
-(output) 25.4654 Tj
--206 TJm
-(b) 4.9815 Tj
-20 TJm
-(u) 4.9815 Tj
-1 TJm
-(f) 3.31768 Tj
-25 TJm
-(fer) 11.0589 Tj
-55 TJm
-(.) 2.49075 Tj
--591 TJm
-(T) 6.08739 Tj
-1 TJm
-(hese) 17.7043 Tj
--206 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-1 TJm
-(s) 3.87561 Tj
--206 TJm
-(can) 13.8286 Tj
--205 TJm
-(be) 9.40507 Tj
--205 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--205 TJm
-(size;) 18.2622 Tj
--220 TJm
-(arbitrary) 34.3026 Tj
--205 TJm
-(quantities) 38.7461 Tj
--205 TJm
-(of) 8.29918 Tj
-72 496.104 Td
-(data) 16.5984 Tj
--258 TJm
-(are) 12.1648 Tj
--258 TJm
-(handl) 22.1378 Tj
-1 TJm
-(ed) 9.40507 Tj
--258 TJm
-(by) 9.963 Tj
--258 TJm
-(making) 29.889 Tj
--258 TJm
-(repeated) 33.7447 Tj
--258 TJm
-(cal) 11.6169 Tj
-1 TJm
-(ls) 6.64532 Tj
--258 TJm
-(to) 7.75121 Tj
--258 TJm
-(these) 20.474 Tj
--258 TJm
-(functions.) 39.573 Tj
--667 TJm
-(This) 17.7142 Tj
--258 TJm
-(is) 6.64532 Tj
--257 TJm
-(a) 4.42357 Tj
--258 TJm
-(\003e) 9.963 Tj
-15 TJm
-(xible) 19.926 Tj
--258 TJm
-(mechanism) 45.3815 Tj
--258 TJm
-(allo) 14.9445 Tj
-25 TJm
-(wing) 19.926 Tj
--257 TJm
-(a) 4.42357 Tj
--258 TJm
-(consumer) 38.7361 Tj
-20 TJm
-(-pull) 18.8201 Tj
-72 484.148 Td
-(style) 18.8201 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(acti) 14.3866 Tj
-25 TJm
-(vity) 15.5024 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(producer) 35.4085 Tj
-20 TJm
-(-p) 8.29918 Tj
-1 TJm
-(ush,) 16.3294 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(mixture) 30.9949 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(both.) 20.205 Tj
-[1 0 0 1 72 481.992] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -472.029] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 453.527 Td
-/F121_0 17.215 Tf
-(3.1.2.) 43.0719 Tj
--278 TJm
-(High-le) 58.3416 Tj
-15 TJm
-(vel) 23.9289 Tj
--278 TJm
-(summar) 66.9664 Tj
--10 TJm
-(y) 9.57154 Tj
-[1 0 0 1 72 449.697] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -439.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 431.609 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--284 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
--284 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vides) 21.0319 Tj
--284 TJm
-(some) 21.0319 Tj
--284 TJm
-(handy) 24.3496 Tj
--284 TJm
-(wrappers) 36.5144 Tj
--284 TJm
-(around) 27.6673 Tj
--284 TJm
-(the) 12.1748 Tj
--285 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w-l) 13.2807 Tj
-1 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--285 TJm
-(interf) 21.5799 Tj
-10 TJm
-(a) 4.42357 Tj
-1 TJm
-(ce) 8.84714 Tj
--285 TJm
-(to) 7.75121 Tj
--284 TJm
-(f) 3.31768 Tj
-10 TJm
-(acilitate) 31.5429 Tj
--284 TJm
-(reading) 29.879 Tj
--284 TJm
-(and) 14.3866 Tj
--284 TJm
-(writing) 28.7831 Tj
-[1 0 0 1 510.112 431.609] cm
-0 g
-0 G
-[1 0 0 1 -510.112 -431.609] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 431.609 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 540 431.609] cm
-0 g
-0 G
-[1 0 0 1 -540 -431.609] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 419.654 Td
-/F128_0 9.963 Tf
-(format) 26.5614 Tj
--346 TJm
-(\002les) 16.6083 Tj
--347 TJm
-(\() 3.31768 Tj
-[1 0 0 1 125.391 419.654] cm
-0 g
-0 G
-[1 0 0 1 -125.391 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-125.391 419.654 Td
-/F130_0 9.963 Tf
-(.bz2) 23.9112 Tj
-[1 0 0 1 149.301 419.654] cm
-0 g
-0 G
-[1 0 0 1 -149.301 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.754 419.654 Td
-/F128_0 9.963 Tf
-(\002les\).) 22.4168 Tj
--1199 TJm
-(The) 15.4925 Tj
--347 TJm
-(routines) 32.1008 Tj
--346 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vide) 17.1563 Tj
--347 TJm
-(hooks) 23.8016 Tj
--346 TJm
-(to) 7.75121 Tj
--347 TJm
-(f) 3.31768 Tj
-10 TJm
-(acilitate) 31.5429 Tj
--346 TJm
-(reading) 29.879 Tj
--347 TJm
-(\002les) 16.6083 Tj
--346 TJm
-(in) 7.75121 Tj
--347 TJm
-(which) 24.3496 Tj
--346 TJm
-(the) 12.1748 Tj
-[1 0 0 1 460.049 419.654] cm
-0 g
-0 G
-[1 0 0 1 -460.049 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-460.049 419.654 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 489.937 419.654] cm
-0 g
-0 G
-[1 0 0 1 -489.937 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.39 419.654 Td
-/F128_0 9.963 Tf
-(data) 16.5984 Tj
--346 TJm
-(stream) 26.5614 Tj
-72 407.699 Td
-(is) 6.64532 Tj
--339 TJm
-(embedded) 40.9479 Tj
--339 TJm
-(within) 25.4654 Tj
--339 TJm
-(some) 21.0319 Tj
--339 TJm
-(lar) 10.511 Tj
-18 TJm
-(ger) 12.7228 Tj
-20 TJm
-(-scale) 23.2337 Tj
--339 TJm
-(\002le) 12.7327 Tj
--339 TJm
-(st) 6.64532 Tj
-1 TJm
-(ructure,) 30.706 Tj
--362 TJm
-(or) 8.29918 Tj
--339 TJm
-(where) 24.3396 Tj
--339 TJm
-(there) 19.916 Tj
--339 TJm
-(are) 12.1648 Tj
--339 TJm
-(m) 7.75121 Tj
-1 TJm
-(ultiple) 25.4654 Tj
-[1 0 0 1 400.941 407.699] cm
-0 g
-0 G
-[1 0 0 1 -400.941 -407.699] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-400.941 407.699 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 430.829 407.699] cm
-0 g
-0 G
-[1 0 0 1 -430.829 -407.699] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.207 407.699 Td
-/F128_0 9.963 Tf
-(data) 16.5984 Tj
--339 TJm
-(streams) 30.437 Tj
--339 TJm
-(concatenated) 52.0069 Tj
-72 395.744 Td
-(end-to-end.) 45.6505 Tj
-[1 0 0 1 72 395.644] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -385.682] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 373.826 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--332 TJm
-(reading) 29.879 Tj
--333 TJm
-(\002) 5.53943 Tj
-1 TJm
-(les,) 13.5596 Tj
-[1 0 0 1 144.803 373.826] cm
-0 g
-0 G
-[1 0 0 1 -144.803 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.803 373.826 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadOpen) 83.6892 Tj
-[1 0 0 1 228.489 373.826] cm
-0 g
-0 G
-[1 0 0 1 -228.489 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-228.489 373.826 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 234.496 373.826] cm
-0 g
-0 G
-[1 0 0 1 -234.496 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.496 373.826 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 294.272 373.826] cm
-0 g
-0 G
-[1 0 0 1 -294.272 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.272 373.826 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 300.279 373.826] cm
-0 g
-0 G
-[1 0 0 1 -300.279 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.279 373.826 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 389.942 373.826] cm
-0 g
-0 G
-[1 0 0 1 -389.942 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-393.253 373.826 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 410.951 373.826] cm
-0 g
-0 G
-[1 0 0 1 -410.951 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.951 373.826 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadGetUnused) 113.578 Tj
-[1 0 0 1 524.525 373.826] cm
-0 g
-0 G
-[1 0 0 1 -524.525 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-527.836 373.826 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
-72 361.871 Td
-(supplied.) 36.2554 Tj
--620 TJm
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--250 TJm
-(writing) 28.7831 Tj
--250 TJm
-(\002les,) 19.0991 Tj
-[1 0 0 1 183.471 361.871] cm
-0 g
-0 G
-[1 0 0 1 -183.471 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.471 361.871 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteOpen) 89.667 Tj
-[1 0 0 1 273.135 361.871] cm
-0 g
-0 G
-[1 0 0 1 -273.135 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-273.135 361.871 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 278.116 361.871] cm
-0 g
-0 G
-[1 0 0 1 -278.116 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.116 361.871 Td
-/F130_0 9.963 Tf
-(BZ2_bzWrite) 65.7558 Tj
-[1 0 0 1 343.869 361.871] cm
-0 g
-0 G
-[1 0 0 1 -343.869 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-346.36 361.871 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 363.237 361.871] cm
-0 g
-0 G
-[1 0 0 1 -363.237 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.237 361.871 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteFinish) 101.623 Tj
-[1 0 0 1 464.856 361.871] cm
-0 g
-0 G
-[1 0 0 1 -464.856 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-467.346 361.871 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
--250 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailable.) 29.0521 Tj
-[1 0 0 1 72 359.714] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -349.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 339.953 Td
-/F128_0 9.963 Tf
-(As) 11.0689 Tj
--374 TJm
-(with) 17.7142 Tj
--374 TJm
-(the) 12.1748 Tj
--374 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--374 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--406 TJm
-(n) 4.9815 Tj
-1 TJm
-(o) 4.9815 Tj
--375 TJm
-(global) 24.9075 Tj
--374 TJm
-(v) 4.9815 Tj
-25 TJm
-(ariables) 30.9849 Tj
--374 TJm
-(are) 12.1648 Tj
--374 TJm
-(used) 18.2622 Tj
--374 TJm
-(so) 8.85711 Tj
--374 TJm
-(the) 12.1748 Tj
--374 TJm
-(library) 26.5614 Tj
--374 TJm
-(is) 6.64532 Tj
--374 TJm
-(per) 12.7228 Tj
--375 TJm
-(se) 8.29918 Tj
--374 TJm
-(thread-safe.) 46.7464 Tj
--1365 TJm
-(Ho) 12.1748 Tj
-25 TJm
-(we) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
-40 TJm
-(,) 2.49075 Tj
--405 TJm
-(if) 6.08739 Tj
--374 TJm
-(I/O) 13.2807 Tj
-72 327.998 Td
-(errors) 23.2337 Tj
--267 TJm
-(occur) 22.1278 Tj
--267 TJm
-(whilst) 24.3595 Tj
--267 TJm
-(reading) 29.879 Tj
--267 TJm
-(or) 8.29918 Tj
--267 TJm
-(writing) 28.7831 Tj
--267 TJm
-(the) 12.1748 Tj
--267 TJm
-(underlying) 43.1697 Tj
--267 TJm
-(compressed) 47.0353 Tj
--267 TJm
-(\002les,) 19.0991 Tj
--271 TJm
-(you) 14.9445 Tj
--267 TJm
-(may) 17.1563 Tj
--267 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--267 TJm
-(to) 7.75121 Tj
--267 TJm
-(consult) 28.7831 Tj
-[1 0 0 1 457.199 327.998] cm
-0 g
-0 G
-[1 0 0 1 -457.199 -327.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-457.199 327.998 Td
-/F130_0 9.963 Tf
-(errno) 29.889 Tj
-[1 0 0 1 487.087 327.998] cm
-0 g
-0 G
-[1 0 0 1 -487.087 -327.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-489.748 327.998 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--267 TJm
-(determine) 39.842 Tj
-72 316.043 Td
-(the) 12.1748 Tj
--366 TJm
-(cau) 13.8286 Tj
-1 TJm
-(se) 8.29918 Tj
--366 TJm
-(of) 8.29918 Tj
--366 TJm
-(the) 12.1748 Tj
--365 TJm
-(error) 19.3581 Tj
-55 TJm
-(.) 2.49075 Tj
--1314 TJm
-(In) 8.29918 Tj
--365 TJm
-(that) 14.9445 Tj
--366 TJm
-(case,) 19.6371 Tj
--394 TJm
-(you') 18.2622 Tj
-50 TJm
-(d) 4.9815 Tj
--366 TJm
-(need) 18.8101 Tj
--365 TJm
-(a) 4.42357 Tj
--366 TJm
-(C) 6.64532 Tj
--366 TJm
-(lib) 10.5209 Tj
-1 TJm
-(rary) 16.0404 Tj
--366 TJm
-(which) 24.3496 Tj
--366 TJm
-(corr) 16.0404 Tj
-1 TJm
-(ectly) 19.3681 Tj
--366 TJm
-(supports) 33.7646 Tj
-[1 0 0 1 431.668 316.043] cm
-0 g
-0 G
-[1 0 0 1 -431.668 -316.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.668 316.043 Td
-/F130_0 9.963 Tf
-(errno) 29.889 Tj
-[1 0 0 1 461.556 316.043] cm
-0 g
-0 G
-[1 0 0 1 -461.556 -316.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-465.199 316.043 Td
-/F128_0 9.963 Tf
-(in) 7.75121 Tj
--366 TJm
-(a) 4.42357 Tj
--365 TJm
-(multithreaded) 55.3445 Tj
-72 304.088 Td
-(en) 9.40507 Tj
-40 TJm
-(vironment.) 43.4486 Tj
-[1 0 0 1 72 303.988] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -294.025] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 282.17 Td
-/F128_0 9.963 Tf
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--243 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--242 TJm
-(the) 12.1748 Tj
--243 TJm
-(library) 26.5614 Tj
--243 TJm
-(a) 4.42357 Tj
--242 TJm
-(little) 18.2721 Tj
--243 TJm
-(simpler) 29.889 Tj
--243 TJm
-(and) 14.3866 Tj
--242 TJm
-(more) 20.474 Tj
--243 TJm
-(portable,) 35.1395 Tj
-[1 0 0 1 289.263 282.17] cm
-0 g
-0 G
-[1 0 0 1 -289.263 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.263 282.17 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadOpen) 83.6892 Tj
-[1 0 0 1 372.949 282.17] cm
-0 g
-0 G
-[1 0 0 1 -372.949 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-375.368 282.17 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 392.172 282.17] cm
-0 g
-0 G
-[1 0 0 1 -392.172 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.172 282.17 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteOpen) 89.667 Tj
-[1 0 0 1 481.836 282.17] cm
-0 g
-0 G
-[1 0 0 1 -481.836 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-484.254 282.17 Td
-/F128_0 9.963 Tf
-(require) 28.2152 Tj
--243 TJm
-(you) 14.9445 Tj
--242 TJm
-(to) 7.75121 Tj
-72 270.215 Td
-(pass) 17.1563 Tj
--247 TJm
-(them) 19.926 Tj
--247 TJm
-(\002le) 12.7327 Tj
--248 TJm
-(handles) 30.437 Tj
--247 TJm
-(\() 3.31768 Tj
-[1 0 0 1 165.421 270.215] cm
-0 g
-0 G
-[1 0 0 1 -165.421 -270.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.421 270.215 Td
-/F130_0 9.963 Tf
-(FILE*) 29.889 Tj
-[1 0 0 1 195.309 270.215] cm
-0 g
-0 G
-[1 0 0 1 -195.309 -270.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-195.309 270.215 Td
-/F128_0 9.963 Tf
-(s\)) 7.19329 Tj
--247 TJm
-(which) 24.3496 Tj
--247 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--248 TJm
-(pre) 12.7228 Tj
-25 TJm
-(viously) 29.341 Tj
--247 TJm
-(been) 18.8101 Tj
--247 TJm
-(opened) 28.7731 Tj
--247 TJm
-(for) 11.6169 Tj
--247 TJm
-(reading) 29.879 Tj
--248 TJm
-(or) 8.29918 Tj
--247 TJm
-(writing) 28.7831 Tj
--247 TJm
-(respecti) 30.9849 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ely) 12.1748 Tj
-65 TJm
-(.) 2.49075 Tj
--618 TJm
-(That) 18.2622 Tj
--247 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-20 TJm
-(oids) 16.6083 Tj
-72 258.26 Td
-(portability) 41.5158 Tj
--272 TJm
-(problems) 37.0823 Tj
--272 TJm
-(associated) 40.9479 Tj
--273 TJm
-(wi) 9.963 Tj
-1 TJm
-(th) 7.75121 Tj
--273 TJm
-(\002le) 12.7327 Tj
--272 TJm
-(operations) 41.5059 Tj
--272 TJm
-(and) 14.3866 Tj
--273 TJm
-(\002le) 12.7327 Tj
--272 TJm
-(attrib) 21.0319 Tj
-20 TJm
-(utes,) 18.5411 Tj
--278 TJm
-(whilst) 24.3595 Tj
--272 TJm
-(not) 12.7327 Tj
--272 TJm
-(being) 22.1378 Tj
--273 TJm
-(mu) 12.7327 Tj
-1 TJm
-(ch) 9.40507 Tj
--273 TJm
-(of) 8.29918 Tj
--272 TJm
-(an) 9.40507 Tj
--272 TJm
-(imposition) 42.6317 Tj
--273 TJm
-(on) 9.963 Tj
--272 TJm
-(the) 12.1748 Tj
-72 246.304 Td
-(programmer) 49.2471 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 244.148] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -234.185] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 215.683 Td
-/F121_0 17.215 Tf
-(3.1.3.) 43.0719 Tj
--278 TJm
-(Utility) 47.8233 Tj
--278 TJm
-(functions) 77.4675 Tj
--278 TJm
-(summar) 66.9664 Tj
--10 TJm
-(y) 9.57154 Tj
-[1 0 0 1 72 212.12] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -202.157] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 193.765 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--273 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
--273 TJm
-(simple) 26.5713 Tj
--273 TJm
-(needs,) 25.1765 Tj
-[1 0 0 1 165.929 193.765] cm
-0 g
-0 G
-[1 0 0 1 -165.929 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.929 193.765 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffCompress) 143.467 Tj
-[1 0 0 1 309.391 193.765] cm
-0 g
-0 G
-[1 0 0 1 -309.391 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-312.112 193.765 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 329.219 193.765] cm
-0 g
-0 G
-[1 0 0 1 -329.219 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-329.219 193.765 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffDecompre) 143.467 Tj
-1 TJm
-(ss) 11.9556 Tj
-[1 0 0 1 484.636 193.765] cm
-0 g
-0 G
-[1 0 0 1 -484.636 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-487.357 193.765 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
--273 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vided.) 24.6285 Tj
-72 181.81 Td
-(These) 23.7916 Tj
--373 TJm
-(compress) 37.6303 Tj
--374 TJm
-(data) 16.5984 Tj
--373 TJm
-(in) 7.75121 Tj
--374 TJm
-(memory) 33.2067 Tj
--373 TJm
-(from) 19.3681 Tj
--374 TJm
-(one) 14.3866 Tj
--373 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--374 TJm
-(to) 7.75121 Tj
--373 TJm
-(another) 29.879 Tj
--374 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fe) 7.74125 Tj
-1 TJm
-(r) 3.31768 Tj
--374 TJm
-(in) 7.75121 Tj
--374 TJm
-(a) 4.42357 Tj
--373 TJm
-(single) 23.8016 Tj
--373 TJm
-(function) 33.2067 Tj
--374 TJm
-(call.) 16.8773 Tj
--1361 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--374 TJm
-(should) 26.5713 Tj
--373 TJm
-(assess) 24.3496 Tj
-72 169.855 Td
-(whether) 32.0908 Tj
--344 TJm
-(t) 2.76971 Tj
-1 TJm
-(hese) 17.7043 Tj
--344 TJm
-(functions) 37.0823 Tj
--344 TJm
-(ful\002) 16.6083 Tj
-1 TJm
-(ll) 5.53943 Tj
--344 TJm
-(your) 18.2622 Tj
--344 TJm
-(memory-to) 44.2756 Tj
-1 TJm
-(-memory) 36.5244 Tj
--344 TJm
-(compression/decompressio) 107.919 Tj
-1 TJm
-(n) 4.9815 Tj
--344 TJm
-(requirements) 52.0168 Tj
--344 TJm
-(be) 9.40507 Tj
-1 TJm
-(fore) 16.0404 Tj
--344 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(esting) 23.8016 Tj
-72 157.9 Td
-(ef) 7.74125 Tj
-25 TJm
-(fort) 14.3866 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(understanding) 56.4504 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(m) 7.75121 Tj
-1 TJm
-(ore) 12.7228 Tj
--250 TJm
-(general) 29.3211 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(more) 20.474 Tj
--250 TJm
-(comple) 29.3311 Tj
-15 TJm
-(x) 4.9815 Tj
--250 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace.) 15.7615 Tj
-[1 0 0 1 72 155.743] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -145.78] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 135.982 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(oshioka) 30.9949 Tj
--531 TJm
-(Tsuneo) 29.3311 Tj
--531 TJm
-(\() 3.31768 Tj
-[1 0 0 1 152.317 135.982] cm
-0 g
-0 G
-[1 0 0 1 -152.317 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.317 135.982 Td
-/F130_0 9.963 Tf
-(QWF00133@niftyserve.or.jp) 149.445 Tj
-[1 0 0 1 301.757 135.982] cm
-0 g
-0 G
-[1 0 0 1 -301.757 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-307.046 135.982 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 315.105 135.982] cm
-0 g
-0 G
-[1 0 0 1 -315.105 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.105 135.982 Td
-/F130_0 9.963 Tf
-(tsuneo-y@is.aist-nara.ac.j) 155.423 Tj
-1 TJm
-(p) 5.9778 Tj
-[1 0 0 1 476.5 135.982] cm
-0 g
-0 G
-[1 0 0 1 -476.5 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-476.5 135.982 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--531 TJm
-(has) 13.2807 Tj
--531 TJm
-(contrib) 28.2252 Tj
-20 TJm
-(u-) 8.29918 Tj
-72 124.027 Td
-(ted) 12.1748 Tj
--486 TJm
-(s) 3.87561 Tj
-1 TJm
-(ome) 17.1563 Tj
--486 TJm
-(functions) 37.0823 Tj
--485 TJm
-(to) 7.75121 Tj
--486 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--485 TJm
-(better) 22.6858 Tj
-[1 0 0 1 218.504 124.027] cm
-0 g
-0 G
-[1 0 0 1 -218.504 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-218.504 124.027 Td
-/F130_0 9.963 Tf
-(zlib) 23.9112 Tj
-[1 0 0 1 242.415 124.027] cm
-0 g
-0 G
-[1 0 0 1 -242.415 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-247.252 124.027 Td
-/F128_0 9.963 Tf
-(compatibility) 53.1426 Tj
-65 TJm
-(.) 2.49075 Tj
--2033 TJm
-(These) 23.7916 Tj
--486 TJm
-(functions) 37.0823 Tj
--485 TJm
-(are) 12.1648 Tj
-[1 0 0 1 410.043 124.027] cm
-0 g
-0 G
-[1 0 0 1 -410.043 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.043 124.027 Td
-/F130_0 9.963 Tf
-(BZ2_bzopen) 59.778 Tj
-[1 0 0 1 469.818 124.027] cm
-0 g
-0 G
-[1 0 0 1 -469.818 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-469.818 124.027 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 477.734 124.027] cm
-0 g
-0 G
-[1 0 0 1 -477.734 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.734 124.027 Td
-/F130_0 9.963 Tf
-(BZ2_bzread) 59.778 Tj
-[1 0 0 1 537.509 124.027] cm
-0 g
-0 G
-[1 0 0 1 -537.509 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 124.027 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 72 112.072] cm
-0 g
-0 G
-[1 0 0 1 -72 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 112.072 Td
-/F130_0 9.963 Tf
-(BZ2_bzwrite) 65.7558 Tj
-[1 0 0 1 137.753 112.072] cm
-0 g
-0 G
-[1 0 0 1 -137.753 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.753 112.072 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 143.886 112.072] cm
-0 g
-0 G
-[1 0 0 1 -143.886 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.886 112.072 Td
-/F130_0 9.963 Tf
-(BZ2_bzflush) 65.7558 Tj
-[1 0 0 1 209.64 112.072] cm
-0 g
-0 G
-[1 0 0 1 -209.64 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-209.64 112.072 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 215.773 112.072] cm
-0 g
-0 G
-[1 0 0 1 -215.773 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-215.773 112.072 Td
-/F130_0 9.963 Tf
-(BZ2_bzclose) 65.7558 Tj
-[1 0 0 1 281.526 112.072] cm
-0 g
-0 G
-[1 0 0 1 -281.526 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-281.526 112.072 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 287.659 112.072] cm
-0 g
-0 G
-[1 0 0 1 -287.659 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-287.659 112.072 Td
-/F130_0 9.963 Tf
-(BZ2_bzerror) 65.7558 Tj
-[1 0 0 1 353.413 112.072] cm
-0 g
-0 G
-[1 0 0 1 -353.413 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-356.824 112.072 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 374.622 112.072] cm
-0 g
-0 G
-[1 0 0 1 -374.622 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.622 112.072 Td
-/F130_0 9.963 Tf
-(BZ2_bzlibVersion) 95.6448 Tj
-[1 0 0 1 470.264 112.072] cm
-0 g
-0 G
-[1 0 0 1 -470.264 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-470.264 112.072 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1175 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--342 TJm
-(may) 17.1563 Tj
--343 TJm
-(\002nd) 15.5024 Tj
-72 100.117 Td
-(these) 20.474 Tj
--333 TJm
-(functions) 37.0823 Tj
--334 TJm
-(more) 20.474 Tj
--333 TJm
-(con) 14.3866 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(enient) 24.3496 Tj
--333 TJm
-(for) 11.6169 Tj
--334 TJm
-(simple) 26.5713 Tj
--333 TJm
-(\002le) 12.7327 Tj
--334 TJm
-(r) 3.31768 Tj
-1 TJm
-(eading) 26.5614 Tj
--334 TJm
-(and) 14.3866 Tj
--333 TJm
-(writing,) 31.2739 Tj
--354 TJm
-(than) 17.1563 Tj
--334 TJm
-(those) 21.0319 Tj
--333 TJm
-(in) 7.75121 Tj
--334 TJm
-(the) 12.1748 Tj
--333 TJm
-(high-le) 28.2252 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--333 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace.) 15.7615 Tj
--1121 TJm
-(These) 23.7916 Tj
-72 88.161 Td
-(functions) 37.0823 Tj
--229 TJm
-(are) 12.1648 Tj
--228 TJm
-(not) 12.7327 Tj
--229 TJm
-(\(yet\)) 18.8101 Tj
--229 TJm
-(of) 8.29918 Tj
-25 TJm
-(\002cially) 27.6772 Tj
--229 TJm
-(pa) 9.40507 Tj
-1 TJm
-(rt) 6.08739 Tj
--229 TJm
-(of) 8.29918 Tj
--229 TJm
-(the) 12.1748 Tj
--229 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--233 TJm
-(and) 14.3866 Tj
--228 TJm
-(are) 12.1648 Tj
--229 TJm
-(minimally) 40.9679 Tj
--229 TJm
-(documented) 48.6991 Tj
--228 TJm
-(here.) 19.6371 Tj
--606 TJm
-(If) 6.63536 Tj
--229 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--229 TJm
-(break,) 24.6186 Tj
--233 TJm
-(you) 14.9445 Tj
--228 TJm
-(get) 12.1748 Tj
--229 TJm
-(to) 7.75121 Tj
--229 TJm
-(k) 4.9815 Tj
-10 TJm
-(eep) 13.8286 Tj
-72 76.206 Td
-(all) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(pieces.) 27.3883 Tj
--310 TJm
-(I) 3.31768 Tj
--250 TJm
-(hope) 19.3681 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(docum) 27.1193 Tj
-1 TJm
-(ent) 12.1748 Tj
--250 TJm
-(them) 19.926 Tj
--250 TJm
-(properly) 33.7546 Tj
--250 TJm
-(when) 21.5799 Tj
--250 TJm
-(time) 17.7142 Tj
--250 TJm
-(permits.) 32.3798 Tj
-[1 0 0 1 72 74.049] cm
-0 g
-0 G
-[1 0 0 1 0 -23.197] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 4.384 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.974] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 43.064 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -498.225 -51.071] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-541.288 51.071 Td
-/F128_0 9.963 Tf
-(9) 4.9815 Tj
-[1 0 0 1 455.161 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.599 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -15.037 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 13 13
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(oshioka) 30.9949 Tj
--250 TJm
-(also) 16.0504 Tj
--250 TJm
-(contrib) 28.2252 Tj
-20 TJm
-(uted) 17.1563 Tj
--250 TJm
-(mo) 12.7327 Tj
-1 TJm
-(di\002cations) 41.5158 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(allo) 14.9445 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(library) 26.5614 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(uilt) 13.2906 Tj
--250 TJm
-(as) 8.29918 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(W) 9.40507 Tj
-40 TJm
-(indo) 17.7142 Tj
-25 TJm
-(ws) 11.0689 Tj
--250 TJm
-(D) 7.19329 Tj
-1 TJm
-(LL.) 14.6655 Tj
-[1 0 0 1 72 707.881] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -698.137] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 675.504 Td
-/F121_0 20.659 Tf
-(3.2.) 34.4592 Tj
--278 TJm
-(Err) 29.8523 Tj
-20 TJm
-(or) 20.659 Tj
--278 TJm
-(handling) 86.0861 Tj
-[1 0 0 1 72 670.907] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.743] cm
-0 g
-0 G
-[1 0 0 1 -72 -661.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 653.805 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--214 TJm
-(library) 26.5614 Tj
--215 TJm
-(is) 6.64532 Tj
--214 TJm
-(designed) 35.4185 Tj
--215 TJm
-(to) 7.75121 Tj
--214 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--214 TJm
-(cleanly) 28.7731 Tj
--215 TJm
-(in) 7.75121 Tj
--214 TJm
-(all) 9.963 Tj
--215 TJm
-(situati) 24.3595 Tj
-1 TJm
-(ons,) 16.3294 Tj
--222 TJm
-(including) 37.6402 Tj
--214 TJm
-(the) 12.1748 Tj
--215 TJm
-(w) 7.19329 Tj
-10 TJm
-(orst-case) 35.4085 Tj
--214 TJm
-(situation) 34.3225 Tj
--214 TJm
-(of) 8.29918 Tj
--215 TJm
-(decompressing) 59.768 Tj
--214 TJm
-(random) 30.437 Tj
-72 641.85 Td
-(data.) 19.0891 Tj
--764 TJm
-(I'm) 14.3866 Tj
--274 TJm
-(not) 12.7327 Tj
--274 TJm
-(100%) 23.2437 Tj
--274 TJm
-(sure) 16.5984 Tj
--274 TJm
-(that) 14.9445 Tj
--274 TJm
-(it) 5.53943 Tj
--274 TJm
-(can) 13.8286 Tj
--274 TJm
-(al) 7.19329 Tj
-10 TJm
-(w) 7.19329 Tj
-10 TJm
-(ays) 13.2807 Tj
--274 TJm
-(do) 9.963 Tj
--274 TJm
-(this,) 16.8873 Tj
--280 TJm
-(so) 8.85711 Tj
--274 TJm
-(you) 14.9445 Tj
--274 TJm
-(might) 23.2536 Tj
--274 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--274 TJm
-(to) 7.75121 Tj
--274 TJm
-(add) 14.3866 Tj
--274 TJm
-(a) 4.42357 Tj
--274 TJm
-(signal) 23.8016 Tj
--274 TJm
-(handler) 29.879 Tj
--274 TJm
-(to) 7.75121 Tj
--274 TJm
-(catch) 21.0219 Tj
--274 TJm
-(se) 8.29918 Tj
-15 TJm
-(gmentation) 44.8335 Tj
-72 629.895 Td
-(violations) 39.304 Tj
--273 TJm
-(during) 26.0134 Tj
--273 TJm
-(decompression) 59.768 Tj
--273 TJm
-(if) 6.08739 Tj
--273 TJm
-(you) 14.9445 Tj
--273 TJm
-(are) 12.1648 Tj
--273 TJm
-(feeling) 27.6673 Tj
--273 TJm
-(especially) 39.842 Tj
--273 TJm
-(paranoid.) 37.3513 Tj
--758 TJm
-(I) 3.31768 Tj
--273 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--273 TJm
-(be) 9.40507 Tj
--273 TJm
-(interested) 38.7361 Tj
--273 TJm
-(in) 7.75121 Tj
--273 TJm
-(hearing) 29.879 Tj
--273 TJm
-(more) 20.474 Tj
--273 TJm
-(about) 22.1378 Tj
-72 617.939 Td
-(the) 12.1748 Tj
--250 TJm
-(rob) 13.2807 Tj
-20 TJm
-(ustness) 28.7831 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(library) 26.5614 Tj
--250 TJm
-(t) 2.76971 Tj
-1 TJm
-(o) 4.9815 Tj
--250 TJm
-(corrupted) 38.1782 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(data.) 19.0891 Tj
-[1 0 0 1 72 615.783] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-[1 0 0 1 -72 -606.039] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 596.241 Td
-/F128_0 9.963 Tf
-(V) 7.19329 Tj
-111 TJm
-(ersion) 24.3496 Tj
--251 TJm
-(1.0.3) 19.926 Tj
--251 TJm
-(more) 20.474 Tj
--251 TJm
-(rob) 13.2807 Tj
-20 TJm
-(ust) 11.6268 Tj
--251 TJm
-(in) 7.75121 Tj
--251 TJm
-(this) 14.3965 Tj
--251 TJm
-(respect) 28.2152 Tj
--251 TJm
-(than) 17.1563 Tj
--251 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--251 TJm
-(pre) 12.7228 Tj
-25 TJm
-(vious) 21.5898 Tj
--251 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion.) 26.8403 Tj
--626 TJm
-(In) 8.29918 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(estig) 18.8201 Tj
-5 TJm
-(ations) 23.8016 Tj
--251 TJm
-(with) 17.7142 Tj
--251 TJm
-(V) 7.19329 Tj
-111 TJm
-(algrind) 28.2252 Tj
--251 TJm
-(\(a) 7.74125 Tj
--251 TJm
-(tool) 15.5024 Tj
--251 TJm
-(for) 11.6169 Tj
--251 TJm
-(detecting) 36.5244 Tj
-72 584.285 Td
-(problems) 37.0823 Tj
--421 TJm
-(with) 17.7142 Tj
--422 TJm
-(memory) 33.2067 Tj
--421 TJm
-(management\)) 54.2286 Tj
--422 TJm
-(indicat) 27.1193 Tj
-1 TJm
-(e) 4.42357 Tj
--422 TJm
-(that,) 17.4353 Tj
--464 TJm
-(at) 7.19329 Tj
--422 TJm
-(least) 18.2622 Tj
--421 TJm
-(for) 11.6169 Tj
--422 TJm
-(the) 12.1748 Tj
--421 TJm
-(fe) 7.74125 Tj
-25 TJm
-(w) 7.19329 Tj
--422 TJm
-(\002les) 16.6083 Tj
--421 TJm
-(I) 3.31768 Tj
--422 TJm
-(tested,) 25.7344 Tj
--464 TJm
-(all) 9.963 Tj
--422 TJm
-(single) 23.8016 Tj
-1 TJm
-(-bit) 13.8386 Tj
--422 TJm
-(errors) 23.2337 Tj
--421 TJm
-(in) 7.75121 Tj
--422 TJm
-(the) 12.1748 Tj
-72 572.33 Td
-(decompressed) 56.4404 Tj
--342 TJm
-(d) 4.9815 Tj
-1 TJm
-(ata) 11.6169 Tj
--342 TJm
-(are) 12.1648 Tj
--342 TJm
-(caught) 26.5614 Tj
--342 TJm
-(pro) 13.2807 Tj
-1 TJm
-(perly) 20.474 Tj
-65 TJm
-(,) 2.49075 Tj
--365 TJm
-(with) 17.7142 Tj
--342 TJm
-(no) 9.963 Tj
--342 TJm
-(s) 3.87561 Tj
-1 TJm
-(e) 4.42357 Tj
-15 TJm
-(gmentation) 44.8335 Tj
--342 TJm
-(f) 3.31768 Tj
-10 TJm
-(aults,) 21.3109 Tj
--365 TJm
-(no) 9.963 Tj
--341 TJm
-(uses) 17.1563 Tj
--342 TJm
-(of) 8.29918 Tj
--342 TJm
-(uninitialise) 44.2855 Tj
-1 TJm
-(d) 4.9815 Tj
--342 TJm
-(data,) 19.0891 Tj
--365 TJm
-(no) 9.963 Tj
--342 TJm
-(out) 12.7327 Tj
--341 TJm
-(of) 8.29918 Tj
--342 TJm
-(range) 22.1278 Tj
-72 560.375 Td
-(reads) 21.0219 Tj
--260 TJm
-(or) 8.29918 Tj
--261 TJm
-(writes,) 26.8403 Tj
--263 TJm
-(and) 14.3866 Tj
--261 TJm
-(no) 9.963 Tj
--260 TJm
-(in\002nite) 28.2351 Tj
--261 TJm
-(looping) 30.4469 Tj
--260 TJm
-(in) 7.75121 Tj
--261 TJm
-(the) 12.1748 Tj
--260 TJm
-(decompressor) 55.3345 Tj
-55 TJm
-(.) 2.49075 Tj
--342 TJm
-(So) 10.5209 Tj
--260 TJm
-(it') 8.85711 Tj
-55 TJm
-(s) 3.87561 Tj
--261 TJm
-(certainly) 34.8605 Tj
--260 TJm
-(pretty) 23.2437 Tj
--261 TJm
-(rob) 13.2807 Tj
-21 TJm
-(ust,) 14.1176 Tj
--264 TJm
-(although) 34.8705 Tj
--260 TJm
-(I) 3.31768 Tj
--261 TJm
-(w) 7.19329 Tj
-10 TJm
-(ouldn') 26.0134 Tj
-18 TJm
-(t) 2.76971 Tj
--260 TJm
-(claim) 22.1378 Tj
-72 548.42 Td
-(it) 5.53943 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(totally) 25.4654 Tj
--250 TJm
-(bombproof.) 46.7663 Tj
-[1 0 0 1 72 546.263] cm
-0 g
-0 G
-[1 0 0 1 0 -9.743] cm
-0 g
-0 G
-[1 0 0 1 -72 -536.52] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 526.721 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--282 TJm
-(\002le) 12.7327 Tj
-[1 0 0 1 105.84 526.721] cm
-0 g
-0 G
-[1 0 0 1 -105.84 -526.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.84 526.721 Td
-/F130_0 9.963 Tf
-(bzlib.h) 41.8446 Tj
-[1 0 0 1 147.683 526.721] cm
-0 g
-0 G
-[1 0 0 1 -147.683 -526.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.491 526.721 Td
-/F128_0 9.963 Tf
-(contains) 33.2067 Tj
--282 TJm
-(all) 9.963 Tj
--282 TJm
-(d) 4.9815 Tj
-1 TJm
-(e\002nitions) 37.0922 Tj
--282 TJm
-(needed) 28.2152 Tj
--282 TJm
-(to) 7.75121 Tj
--282 TJm
-(use) 13.2807 Tj
--282 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--282 TJm
-(library) 26.5614 Tj
-65 TJm
-(.) 2.49075 Tj
--811 TJm
-(In) 8.29918 Tj
--282 TJm
-(particular) 38.1782 Tj
-40 TJm
-(,) 2.49075 Tj
--290 TJm
-(you) 14.9445 Tj
--282 TJm
-(shou) 18.8201 Tj
-1 TJm
-(ld) 7.75121 Tj
--282 TJm
-(de\002nitely) 37.6402 Tj
--282 TJm
-(not) 12.7327 Tj
--282 TJm
-(include) 29.3311 Tj
-[1 0 0 1 72 514.766] cm
-0 g
-0 G
-[1 0 0 1 -72 -514.766] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 514.766 Td
-/F130_0 9.963 Tf
-(bzlib_private.h) 89.667 Tj
-[1 0 0 1 161.664 514.766] cm
-0 g
-0 G
-[1 0 0 1 -161.664 -514.766] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.664 514.766 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 513.202] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-[1 0 0 1 -72 -503.458] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 493.067 Td
-/F128_0 9.963 Tf
-(In) 8.29918 Tj
-[1 0 0 1 82.807 493.067] cm
-0 g
-0 G
-[1 0 0 1 -82.807 -493.067] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-82.807 493.067 Td
-/F130_0 9.963 Tf
-(bzlib.h) 41.8446 Tj
-[1 0 0 1 124.651 493.067] cm
-0 g
-0 G
-[1 0 0 1 -124.651 -493.067] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.651 493.067 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--252 TJm
-(the) 12.1748 Tj
--252 TJm
-(v) 4.9815 Tj
-25 TJm
-(arious) 24.3496 Tj
--252 TJm
-(return) 23.7916 Tj
--251 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues) 20.474 Tj
--252 TJm
-(are) 12.1648 Tj
--252 TJm
-(de\002ned.) 31.8218 Tj
--630 TJm
-(The) 15.4925 Tj
--252 TJm
-(follo) 18.8201 Tj
-25 TJm
-(wing) 19.926 Tj
--252 TJm
-(list) 12.1847 Tj
--251 TJm
-(is) 6.64532 Tj
--252 TJm
-(not) 12.7327 Tj
--252 TJm
-(intended) 34.3126 Tj
--252 TJm
-(as) 8.29918 Tj
--251 TJm
-(an) 9.40507 Tj
--252 TJm
-(e) 4.42357 Tj
-15 TJm
-(xhausti) 28.7831 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--252 TJm
-(description) 44.2756 Tj
--251 TJm
-(of) 8.29918 Tj
-72 481.112 Td
-(the) 12.1748 Tj
--236 TJm
-(circumstances) 56.4404 Tj
--236 TJm
-(in) 7.75121 Tj
--236 TJm
-(which) 24.3496 Tj
--236 TJm
-(a) 4.42357 Tj
--236 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--237 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--236 TJm
-(may) 17.1563 Tj
--236 TJm
-(be) 9.40507 Tj
--236 TJm
-(returned) 33.1967 Tj
--236 TJm
-(--) 6.63536 Tj
--236 TJm
-(those) 21.0319 Tj
--236 TJm
-(descriptions) 48.1512 Tj
--236 TJm
-(are) 12.1648 Tj
--236 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--236 TJm
-(later) 17.7043 Tj
-55 TJm
-(.) 2.49075 Tj
--306 TJm
-(Rather) 26.5614 Tj
-40 TJm
-(,) 2.49075 Tj
--239 TJm
-(it) 5.53943 Tj
--236 TJm
-(is) 6.64532 Tj
--236 TJm
-(intended) 34.3126 Tj
--236 TJm
-(to) 7.75121 Tj
-72 469.157 Td
-(con) 14.3866 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-15 TJm
-(y) 4.9815 Tj
--266 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--266 TJm
-(rough) 23.2437 Tj
--266 TJm
-(me) 12.1748 Tj
-1 TJm
-(aning) 22.1378 Tj
--266 TJm
-(of) 8.29918 Tj
--266 TJm
-(ea) 8.84714 Tj
-1 TJm
-(ch) 9.40507 Tj
--266 TJm
-(return) 23.7916 Tj
--266 TJm
-(v) 4.9815 Tj
-26 TJm
-(alue.) 19.0891 Tj
--714 TJm
-(The) 15.4925 Tj
--265 TJm
-(\002rst) 15.5024 Tj
--266 TJm
-(\002) 5.53943 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--266 TJm
-(a) 4.42357 Tj
-1 TJm
-(ctions) 23.8016 Tj
--266 TJm
-(are) 12.1648 Tj
--265 TJm
-(normal) 28.2252 Tj
--266 TJm
-(and) 14.3866 Tj
--265 TJm
-(not) 12.7327 Tj
--266 TJm
-(intended) 34.3126 Tj
--265 TJm
-(to) 7.75121 Tj
--266 TJm
-(denote) 26.5614 Tj
--265 TJm
-(an) 9.40507 Tj
--266 TJm
-(error) 19.3581 Tj
-72 457.202 Td
-(situation.) 36.8133 Tj
-[1 0 0 1 72 457.102] cm
-0 g
-0 G
-[1 0 0 1 0 -9.743] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -437.615] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 425.759 Td
-/F130_0 9.963 Tf
-(BZ_OK) 29.889 Tj
-[1 0 0 1 101.888 425.759] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -32.379 -1.165] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -424.594] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 413.804 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--250 TJm
-(requested) 38.1782 Tj
--250 TJm
-(action) 24.3496 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--250 TJm
-(com) 17.1563 Tj
-1 TJm
-(pleted) 24.3496 Tj
--250 TJm
-(successfully) 48.6991 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 411.647] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.765] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -398.138] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 388.34 Td
-/F130_0 9.963 Tf
-(BZ_RUN_OK,) 59.778 Tj
--600 TJm
-(BZ_FLUSH_OK,) 71.7336 Tj
--600 TJm
-(BZ) 11.9556 Tj
-1 TJm
-(_FINISH_OK) 59.778 Tj
-[1 0 0 1 287.193 388.34] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -217.684 -1.166] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -387.174] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 376.384 Td
-/F128_0 9.963 Tf
-(In) 8.29918 Tj
-[1 0 0 1 118.789 376.384] cm
-0 g
-0 G
-[1 0 0 1 -118.789 -376.384] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.789 376.384 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 202.476 376.384] cm
-0 g
-0 G
-[1 0 0 1 -202.476 -376.384] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-202.476 376.384 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(requested) 38.1782 Tj
--250 TJm
-(\003ush/\002nish/) 47.0652 Tj
-1 TJm
-(nothing-special) 61.4319 Tj
--250 TJm
-(action) 24.3496 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--250 TJm
-(completed) 41.5059 Tj
--250 TJm
-(successfully) 48.6991 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 374.228] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.766] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -360.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 350.92 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 149.709 350.92] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -80.199 -1.166] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -349.754] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 338.965 Td
-/F128_0 9.963 Tf
-(Compression) 52.5847 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--250 TJm
-(com) 17.1563 Tj
-1 TJm
-(pleted,) 26.8403 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(logical) 27.1193 Tj
--250 TJm
-(stream) 26.5614 Tj
--250 TJm
-(end) 14.3866 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--250 TJm
-(detected) 33.1967 Tj
--250 TJm
-(during) 26.0134 Tj
--250 TJm
-(de) 9.40507 Tj
-1 TJm
-(compression.) 52.8537 Tj
-[1 0 0 1 72 336.808] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.766] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-[1 0 0 1 0 -9.743] cm
-0 g
-0 G
-[1 0 0 1 -72 -313.555] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 303.756 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--250 TJm
-(follo) 18.8201 Tj
-25 TJm
-(wing) 19.926 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues) 20.474 Tj
--250 TJm
-(i) 2.76971 Tj
-1 TJm
-(ndicate) 28.7731 Tj
--250 TJm
-(an) 9.40507 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(some) 21.0319 Tj
--250 TJm
-(kind.) 20.205 Tj
-[1 0 0 1 72 301.6] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -282.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 272.314 Td
-/F130_0 9.963 Tf
-(BZ_CONFIG_ERROR) 89.667 Tj
-[1 0 0 1 161.664 272.314] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -92.154 -1.165] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -271.149] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 260.359 Td
-/F128_0 9.963 Tf
-(Indicates) 35.9664 Tj
--386 TJm
-(that) 14.9445 Tj
--385 TJm
-(the) 12.1748 Tj
--386 TJm
-(library) 26.5614 Tj
--386 TJm
-(has) 13.2807 Tj
--385 TJm
-(been) 18.8101 Tj
--386 TJm
-(improperly) 44.2756 Tj
--385 TJm
-(compiled) 37.0823 Tj
--386 TJm
-(on) 9.963 Tj
--386 TJm
-(your) 18.2622 Tj
--385 TJm
-(platform) 34.3126 Tj
--386 TJm
-(--) 6.63536 Tj
--386 TJm
-(a) 4.42357 Tj
--385 TJm
-(major) 23.2437 Tj
--386 TJm
-(con\002guration) 53.1327 Tj
--386 TJm
-(error) 19.3581 Tj
-55 TJm
-(.) 2.49075 Tj
-108 248.404 Td
-(Speci\002cally) 47.0453 Tj
-65 TJm
-(,) 2.49075 Tj
--481 TJm
-(it) 5.53943 Tj
--435 TJm
-(means) 25.4555 Tj
--434 TJm
-(that) 14.9445 Tj
-[1 0 0 1 220.614 248.404] cm
-0 g
-0 G
-[1 0 0 1 -220.614 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.614 248.404 Td
-/F130_0 9.963 Tf
-(sizeof\(char\)) 71.7336 Tj
-[1 0 0 1 292.345 248.404] cm
-0 g
-0 G
-[1 0 0 1 -292.345 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.345 248.404 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 299.628 248.404] cm
-0 g
-0 G
-[1 0 0 1 -299.628 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.628 248.404 Td
-/F130_0 9.963 Tf
-(sizeof\(short\)) 77.7114 Tj
-[1 0 0 1 377.337 248.404] cm
-0 g
-0 G
-[1 0 0 1 -377.337 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-381.669 248.404 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 400.388 248.404] cm
-0 g
-0 G
-[1 0 0 1 -400.388 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-400.388 248.404 Td
-/F130_0 9.963 Tf
-(sizeof\(int\)) 65.7558 Tj
-[1 0 0 1 466.141 248.404] cm
-0 g
-0 G
-[1 0 0 1 -466.141 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-470.474 248.404 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
--435 TJm
-(not) 12.7327 Tj
--435 TJm
-(1,) 7.47225 Tj
--481 TJm
-(2) 4.9815 Tj
--434 TJm
-(and) 14.3866 Tj
-108 236.449 Td
-(4) 4.9815 Tj
--389 TJm
-(respecti) 30.9849 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ely) 12.1748 Tj
-65 TJm
-(,) 2.49075 Tj
--424 TJm
-(as) 8.29918 Tj
--389 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--389 TJm
-(should) 26.5713 Tj
--390 TJm
-(be.) 11.8958 Tj
--1455 TJm
-(Note) 19.3681 Tj
--389 TJm
-(that) 14.9445 Tj
--389 TJm
-(the) 12.1748 Tj
--390 TJm
-(library) 26.5614 Tj
--389 TJm
-(should) 26.5713 Tj
--389 TJm
-(still) 14.9545 Tj
--389 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--389 TJm
-(properly) 33.7546 Tj
--389 TJm
-(on) 9.963 Tj
--390 TJm
-(64-bi) 21.0319 Tj
-1 TJm
-(t) 2.76971 Tj
--390 TJm
-(platforms) 38.1882 Tj
-108 224.493 Td
-(which) 24.3496 Tj
--292 TJm
-(follo) 18.8201 Tj
-25 TJm
-(w) 7.19329 Tj
--292 TJm
-(the) 12.1748 Tj
--292 TJm
-(LP64) 21.5898 Tj
--292 TJm
-(programming) 54.2386 Tj
--292 TJm
-(model) 24.9075 Tj
--292 TJm
-(--) 6.63536 Tj
--292 TJm
-(that) 14.9445 Tj
--292 TJm
-(is,) 9.13607 Tj
--303 TJm
-(where) 24.3396 Tj
-[1 0 0 1 355.279 224.493] cm
-0 g
-0 G
-[1 0 0 1 -355.279 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-355.279 224.493 Td
-/F130_0 9.963 Tf
-(sizeof\(long\)) 71.7336 Tj
-[1 0 0 1 427.01 224.493] cm
-0 g
-0 G
-[1 0 0 1 -427.01 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.92 224.493 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 447.217 224.493] cm
-0 g
-0 G
-[1 0 0 1 -447.217 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-447.217 224.493 Td
-/F130_0 9.963 Tf
-(sizeof\(void*\)) 77.7114 Tj
-[1 0 0 1 524.925 224.493] cm
-0 g
-0 G
-[1 0 0 1 -524.925 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-527.836 224.493 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
-108 212.538 Td
-(8.) 7.47225 Tj
--620 TJm
-(Under) 24.8975 Tj
--250 TJm
-(LP64,) 24.0806 Tj
-[1 0 0 1 175.606 212.538] cm
-0 g
-0 G
-[1 0 0 1 -175.606 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-175.606 212.538 Td
-/F130_0 9.963 Tf
-(sizeof\(int\)) 65.7558 Tj
-[1 0 0 1 241.36 212.538] cm
-0 g
-0 G
-[1 0 0 1 -241.36 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.85 212.538 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(still) 14.9545 Tj
--250 TJm
-(4,) 7.47225 Tj
--250 TJm
-(so) 8.85711 Tj
-[1 0 0 1 291.74 212.538] cm
-0 g
-0 G
-[1 0 0 1 -291.74 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-291.74 212.538 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 339.561 212.538] cm
-0 g
-0 G
-[1 0 0 1 -339.561 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.561 212.538 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(the) 12.1748 Tj
-[1 0 0 1 433.458 212.538] cm
-0 g
-0 G
-[1 0 0 1 -433.458 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-433.458 212.538 Td
-/F130_0 9.963 Tf
-(long) 23.9112 Tj
-[1 0 0 1 457.368 212.538] cm
-0 g
-0 G
-[1 0 0 1 -457.368 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-459.859 212.538 Td
-/F128_0 9.963 Tf
-(type,) 19.647 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(OK.) 16.8773 Tj
-[1 0 0 1 72 210.381] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.765] cm
-0 g
-0 G
-[1 0 0 1 0 -9.744] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -196.872] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 187.074 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-[1 0 0 1 173.619 187.074] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -104.11 -1.42] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -185.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 175.118 Td
-/F128_0 9.963 Tf
-(When) 23.7916 Tj
--290 TJm
-(using) 21.5898 Tj
--291 TJm
-(the) 12.1748 Tj
--290 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--301 TJm
-(it) 5.53943 Tj
--290 TJm
-(is) 6.64532 Tj
--291 TJm
-(important) 38.7461 Tj
--290 TJm
-(to) 7.75121 Tj
--291 TJm
-(ca) 8.84714 Tj
-1 TJm
-(ll) 5.53943 Tj
--291 TJm
-(the) 12.1748 Tj
--290 TJm
-(functions) 37.0823 Tj
--291 TJm
-(in) 7.75121 Tj
--290 TJm
-(the) 12.1748 Tj
--291 TJm
-(correct) 27.6573 Tj
--290 TJm
-(sequence) 36.5144 Tj
--290 TJm
-(and) 14.3866 Tj
--291 TJm
-(with) 17.7142 Tj
--290 TJm
-(data) 16.5984 Tj
--291 TJm
-(structures) 38.7361 Tj
-108 163.163 Td
-(\(b) 8.29918 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fers) 14.9345 Tj
--205 TJm
-(etc\)) 14.9345 Tj
--206 TJm
-(in) 7.75121 Tj
--206 TJm
-(the) 12.1748 Tj
--205 TJm
-(correct) 27.6573 Tj
--206 TJm
-(states.) 24.6285 Tj
-[1 0 0 1 239.409 163.163] cm
-0 g
-0 G
-[1 0 0 1 -239.409 -163.163] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-239.409 163.163 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 287.23 163.163] cm
-0 g
-0 G
-[1 0 0 1 -287.23 -163.163] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.278 163.163 Td
-/F128_0 9.963 Tf
-(checks) 27.1093 Tj
--206 TJm
-(as) 8.29918 Tj
--205 TJm
-(much) 22.1378 Tj
--206 TJm
-(as) 8.29918 Tj
--205 TJm
-(it) 5.53943 Tj
--206 TJm
-(can) 13.8286 Tj
--205 TJm
-(to) 7.75121 Tj
--206 TJm
-(ensure) 26.0034 Tj
--205 TJm
-(this) 14.3965 Tj
--206 TJm
-(is) 6.64532 Tj
--206 TJm
-(happeni) 31.5429 Tj
-1 TJm
-(ng,) 12.4538 Tj
--215 TJm
-(and) 14.3866 Tj
--206 TJm
-(re) 7.74125 Tj
-1 TJm
-(turns) 19.926 Tj
-[1 0 0 1 108 151.208] cm
-0 g
-0 G
-[1 0 0 1 -108 -151.208] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 151.208 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-[1 0 0 1 209.619 151.208] cm
-0 g
-0 G
-[1 0 0 1 -209.619 -151.208] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.27 151.208 Td
-/F128_0 9.963 Tf
-(if) 6.08739 Tj
--367 TJm
-(not) 12.7327 Tj
-1 TJm
-(.) 2.49075 Tj
--660 TJm
-(Code) 21.0319 Tj
--367 TJm
-(which) 24.3496 Tj
--366 TJm
-(complies) 35.9764 Tj
--367 TJm
-(precisel) 30.9849 Tj
-1 TJm
-(y) 4.9815 Tj
--367 TJm
-(with) 17.7142 Tj
--367 TJm
-(the) 12.1748 Tj
--366 TJm
-(function) 33.2067 Tj
--367 TJm
-(s) 3.87561 Tj
-1 TJm
-(emantics,) 37.9092 Tj
--396 TJm
-(as) 8.29918 Tj
--367 TJm
-(deta) 16.5984 Tj
-1 TJm
-(iled) 14.9445 Tj
-108 139.253 Td
-(belo) 17.1563 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(ne) 9.40507 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--250 TJm
-(recei) 19.3581 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(this) 14.3965 Tj
--249 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue;) 19.3681 Tj
--250 TJm
-(such) 18.2622 Tj
--250 TJm
-(an) 9.40507 Tj
--250 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ent) 12.1748 Tj
--250 TJm
-(denotes) 30.437 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(uggy) 19.926 Tj
--250 TJm
-(code) 18.8101 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(i) 2.76971 Tj
-1 TJm
-(n) 4.9815 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(estig) 18.8201 Tj
-5 TJm
-(ate.) 14.1076 Tj
-[1 0 0 1 72 137.096] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.766] cm
-0 g
-0 G
-[1 0 0 1 0 -9.743] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -123.587] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 113.788 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-[1 0 0 1 155.686 113.788] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -86.177 -1.165] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -112.623] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 101.833 Td
-/F128_0 9.963 Tf
-(Returned) 36.5244 Tj
--434 TJm
-(when) 21.5799 Tj
--434 TJm
-(a) 4.42357 Tj
--433 TJm
-(parameter) 39.8321 Tj
--434 TJm
-(to) 7.75121 Tj
--434 TJm
-(a) 4.42357 Tj
--434 TJm
-(function) 33.2067 Tj
--434 TJm
-(call) 14.3866 Tj
--434 TJm
-(is) 6.64532 Tj
--433 TJm
-(out) 12.7327 Tj
--434 TJm
-(of) 8.29918 Tj
--434 TJm
-(range) 22.1278 Tj
--434 TJm
-(or) 8.29918 Tj
--434 TJm
-(otherwise) 38.7361 Tj
--434 TJm
-(man) 17.1563 Tj
-1 TJm
-(ifestly) 24.9075 Tj
--434 TJm
-(incorrect.) 37.8993 Tj
--1724 TJm
-(As) 11.0689 Tj
-108 89.878 Td
-(with) 17.7142 Tj
-[1 0 0 1 131.644 89.878] cm
-0 g
-0 G
-[1 0 0 1 -131.644 -89.878] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.644 89.878 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-[1 0 0 1 233.263 89.878] cm
-0 g
-0 G
-[1 0 0 1 -233.263 -89.878] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-233.263 89.878 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--595 TJm
-(this) 14.3965 Tj
--596 TJm
-(d) 4.9815 Tj
-1 TJm
-(enotes) 25.4555 Tj
--596 TJm
-(a) 4.42357 Tj
--595 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--595 TJm
-(in) 7.75121 Tj
--595 TJm
-(the) 12.1748 Tj
--596 TJm
-(client) 22.1378 Tj
--595 TJm
-(code.) 21.3009 Tj
--2692 TJm
-(T) 6.08739 Tj
-1 TJm
-(he) 9.40507 Tj
--596 TJm
-(distinction) 42.0737 Tj
--595 TJm
-(between) 33.1967 Tj
-[1 0 0 1 108 77.923] cm
-0 g
-0 G
-[1 0 0 1 -108 -77.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 77.923 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-[1 0 0 1 191.686 77.923] cm
-0 g
-0 G
-[1 0 0 1 -191.686 -77.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.177 77.923 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 211.053 77.923] cm
-0 g
-0 G
-[1 0 0 1 -211.053 -77.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.053 77.923 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-[1 0 0 1 312.672 77.923] cm
-0 g
-0 G
-[1 0 0 1 -312.672 -77.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.163 77.923 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(bit) 10.5209 Tj
--250 TJm
-(hazy) 18.8101 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(still) 14.9545 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(orth) 16.0504 Tj
--250 TJm
-(m) 7.75121 Tj
-1 TJm
-(aking.) 24.6285 Tj
-[1 0 0 1 72 75.766] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.766] cm
-0 g
-0 G
-[1 0 0 1 0 -21.148] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(10) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 14 14
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.963 Tf
-(BZ_MEM_ERROR) 71.7336 Tj
-[1 0 0 1 143.731 710.037] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -74.222 -1.165] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -708.872] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 698.082 Td
-/F128_0 9.963 Tf
-(Returned) 36.5244 Tj
--227 TJm
-(when) 21.5799 Tj
--228 TJm
-(a) 4.42357 Tj
--228 TJm
-(reque) 22.1278 Tj
-1 TJm
-(st) 6.64532 Tj
--228 TJm
-(to) 7.75121 Tj
--228 TJm
-(allocate) 30.9849 Tj
--227 TJm
-(memory) 33.2067 Tj
--228 TJm
-(f) 3.31768 Tj
-10 TJm
-(aile) 14.3866 Tj
-1 TJm
-(d.) 7.47225 Tj
--606 TJm
-(N) 7.19329 Tj
-1 TJm
-(ote) 12.1748 Tj
--228 TJm
-(that) 14.9445 Tj
--228 TJm
-(the) 12.1748 Tj
--227 TJm
-(quantity) 32.6587 Tj
--228 TJm
-(of) 8.29918 Tj
--227 TJm
-(memory) 33.2067 Tj
--228 TJm
-(needed) 28.2152 Tj
--227 TJm
-(to) 7.75121 Tj
--228 TJm
-(decompress) 47.0353 Tj
-108 686.127 Td
-(a) 4.42357 Tj
--351 TJm
-(stream) 26.5614 Tj
--352 TJm
-(cannot) 26.5614 Tj
--351 TJm
-(be) 9.40507 Tj
--351 TJm
-(determined) 44.8235 Tj
--352 TJm
-(until) 18.2721 Tj
--351 TJm
-(the) 12.1748 Tj
--351 TJm
-(stream') 29.879 Tj
-55 TJm
-(s) 3.87561 Tj
--352 TJm
-(heade) 23.2337 Tj
-1 TJm
-(r) 3.31768 Tj
--352 TJm
-(has) 13.2807 Tj
--351 TJm
-(been) 18.8101 Tj
--352 TJm
-(read.) 19.6371 Tj
--1228 TJm
-(So) 10.5209 Tj
-[1 0 0 1 426.471 686.127] cm
-0 g
-0 G
-[1 0 0 1 -426.471 -686.127] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-426.471 686.127 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 522.113 686.127] cm
-0 g
-0 G
-[1 0 0 1 -522.113 -686.127] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 686.127 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 108 674.172] cm
-0 g
-0 G
-[1 0 0 1 -108 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 674.172 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 167.776 674.172] cm
-0 g
-0 G
-[1 0 0 1 -167.776 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.13 674.172 Td
-/F128_0 9.963 Tf
-(may) 17.1563 Tj
--437 TJm
-(return) 23.7916 Tj
-[1 0 0 1 221.784 674.172] cm
-0 g
-0 G
-[1 0 0 1 -221.784 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.784 674.172 Td
-/F130_0 9.963 Tf
-(BZ_MEM_ERROR) 71.7336 Tj
-[1 0 0 1 293.515 674.172] cm
-0 g
-0 G
-[1 0 0 1 -293.515 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.867 674.172 Td
-/F128_0 9.963 Tf
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--437 TJm
-(though) 27.6772 Tj
--437 TJm
-(some) 21.0319 Tj
--437 TJm
-(of) 8.29918 Tj
--437 TJm
-(the) 12.1748 Tj
--437 TJm
-(compressed) 47.0353 Tj
--437 TJm
-(da) 9.40507 Tj
-1 TJm
-(ta) 7.19329 Tj
--437 TJm
-(has) 13.2807 Tj
--437 TJm
-(been) 18.8101 Tj
--437 TJm
-(read.) 19.6371 Tj
-108 662.217 Td
-(The) 15.4925 Tj
--479 TJm
-(sam) 16.0504 Tj
-1 TJm
-(e) 4.42357 Tj
--479 TJm
-(is) 6.64532 Tj
--479 TJm
-(not) 12.7327 Tj
--478 TJm
-(true) 15.4925 Tj
--479 TJm
-(for) 11.6169 Tj
--478 TJm
-(compression;) 53.1327 Tj
--593 TJm
-(once) 18.8101 Tj
-[1 0 0 1 301.675 662.217] cm
-0 g
-0 G
-[1 0 0 1 -301.675 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-301.675 662.217 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 409.272 662.217] cm
-0 g
-0 G
-[1 0 0 1 -409.272 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.04 662.217 Td
-/F128_0 9.963 Tf
-(or) 8.29918 Tj
-[1 0 0 1 427.107 662.217] cm
-0 g
-0 G
-[1 0 0 1 -427.107 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.107 662.217 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteOpen) 89.667 Tj
-[1 0 0 1 516.771 662.217] cm
-0 g
-0 G
-[1 0 0 1 -516.771 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-521.539 662.217 Td
-/F128_0 9.963 Tf
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-108 650.262 Td
-(successfully) 48.6991 Tj
--250 TJm
-(completed,) 43.9966 Tj
-[1 0 0 1 205.672 650.262] cm
-0 g
-0 G
-[1 0 0 1 -205.672 -650.262] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-205.672 650.262 Td
-/F130_0 9.963 Tf
-(BZ_MEM_ERROR) 71.7336 Tj
-[1 0 0 1 277.403 650.262] cm
-0 g
-0 G
-[1 0 0 1 -277.403 -650.262] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-279.894 650.262 Td
-/F128_0 9.963 Tf
-(cannot) 26.5614 Tj
--250 TJm
-(occur) 22.1278 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 648.105] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -634.157] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 624.359 Td
-/F130_0 9.963 Tf
-(BZ_DATA_ERROR) 77.7114 Tj
-[1 0 0 1 149.709 624.359] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -80.199 -1.166] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -623.193] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 612.404 Td
-/F128_0 9.963 Tf
-(Returned) 36.5244 Tj
--265 TJm
-(when) 21.5799 Tj
--266 TJm
-(a) 4.42357 Tj
--266 TJm
-(da) 9.40507 Tj
-1 TJm
-(ta) 7.19329 Tj
--266 TJm
-(inte) 14.9445 Tj
-15 TJm
-(grity) 18.8201 Tj
--265 TJm
-(error) 19.3581 Tj
--266 TJm
-(is) 6.64532 Tj
--266 TJm
-(dete) 16.5984 Tj
-1 TJm
-(cted) 16.5984 Tj
--266 TJm
-(during) 26.0134 Tj
--266 TJm
-(d) 4.9815 Tj
-1 TJm
-(ecompression.) 57.2773 Tj
--714 TJm
-(Most) 20.4839 Tj
--265 TJm
-(importantly) 46.4973 Tj
-65 TJm
-(,) 2.49075 Tj
--270 TJm
-(this) 14.3965 Tj
--265 TJm
-(means) 25.4555 Tj
--266 TJm
-(when) 21.5799 Tj
-108 600.448 Td
-(stored) 24.3496 Tj
--222 TJm
-(and) 14.3866 Tj
--222 TJm
-(computed) 39.2941 Tj
--222 TJm
-(CRCs) 23.8116 Tj
--223 TJm
-(for) 11.6169 Tj
--222 TJm
-(the) 12.1748 Tj
--222 TJm
-(data) 16.5984 Tj
--222 TJm
-(do) 9.963 Tj
--222 TJm
-(not) 12.7327 Tj
--223 TJm
-(match.) 26.8403 Tj
--601 TJm
-(This) 17.7142 Tj
--222 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--222 TJm
-(is) 6.64532 Tj
--223 TJm
-(also) 16.0504 Tj
--222 TJm
-(returned) 33.1967 Tj
--222 TJm
-(upon) 19.926 Tj
--222 TJm
-(detection) 36.5244 Tj
--222 TJm
-(of) 8.29918 Tj
--222 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--223 TJm
-(other) 20.474 Tj
-108 588.493 Td
-(anomaly) 34.3126 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(d) 4.9815 Tj
-1 TJm
-(ata.) 14.1076 Tj
-[1 0 0 1 72 586.336] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -572.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 562.59 Td
-/F130_0 9.963 Tf
-(BZ_DATA_ERROR_MAGIC) 113.578 Tj
-[1 0 0 1 185.574 562.59] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -116.065 -1.165] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -561.425] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 550.635 Td
-/F128_0 9.963 Tf
-(As) 11.0689 Tj
--306 TJm
-(a) 4.42357 Tj
--306 TJm
-(special) 27.6673 Tj
--306 TJm
-(case) 17.1463 Tj
--306 TJm
-(of) 8.29918 Tj
-[1 0 0 1 191.852 550.635] cm
-0 g
-0 G
-[1 0 0 1 -191.852 -550.635] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-191.852 550.635 Td
-/F130_0 9.963 Tf
-(BZ_DATA_ERROR) 77.7114 Tj
-[1 0 0 1 269.561 550.635] cm
-0 g
-0 G
-[1 0 0 1 -269.561 -550.635] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.561 550.635 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--306 TJm
-(it) 5.53943 Tj
--306 TJm
-(is) 6.64532 Tj
--306 TJm
-(sometimes) 42.6217 Tj
--306 TJm
-(useful) 24.3496 Tj
--306 TJm
-(to) 7.75121 Tj
--306 TJm
-(kno) 14.9445 Tj
-25 TJm
-(w) 7.19329 Tj
--306 TJm
-(when) 21.5799 Tj
--306 TJm
-(the) 12.1748 Tj
--307 TJm
-(com) 17.1563 Tj
-1 TJm
-(pressed) 29.879 Tj
--306 TJm
-(stream) 26.5614 Tj
--306 TJm
-(does) 18.2622 Tj
-108 538.68 Td
-(not) 12.7327 Tj
--250 TJm
-(start) 17.1563 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(correct) 27.6573 Tj
--250 TJm
-(m) 7.75121 Tj
-1 TJm
-(agic) 16.5984 Tj
--250 TJm
-(bytes) 21.0319 Tj
--250 TJm
-(\() 3.31768 Tj
-[1 0 0 1 261.562 538.68] cm
-0 g
-0 G
-[1 0 0 1 -261.562 -538.68] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.562 538.68 Td
-/F130_0 9.963 Tf
-('B') 17.9334 Tj
--600 TJm
-('Z') 17.9334 Tj
--600 TJm
-('h') 17.9334 Tj
-[1 0 0 1 327.316 538.68] cm
-0 g
-0 G
-[1 0 0 1 -327.316 -538.68] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-327.316 538.68 Td
-/F128_0 9.963 Tf
-(\).) 5.80843 Tj
-[1 0 0 1 72 536.523] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -522.576] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 512.777 Td
-/F130_0 9.963 Tf
-(BZ_IO_ERROR) 65.7558 Tj
-[1 0 0 1 137.753 512.777] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -68.244 -1.165] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -511.612] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 500.822 Td
-/F128_0 9.963 Tf
-(Returned) 36.5244 Tj
--233 TJm
-(by) 9.963 Tj
-[1 0 0 1 159.123 500.822] cm
-0 g
-0 G
-[1 0 0 1 -159.123 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.123 500.822 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 218.899 500.822] cm
-0 g
-0 G
-[1 0 0 1 -218.899 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.218 500.822 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 237.922 500.822] cm
-0 g
-0 G
-[1 0 0 1 -237.922 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.922 500.822 Td
-/F130_0 9.963 Tf
-(BZ2_bzWrite) 65.7558 Tj
-[1 0 0 1 303.676 500.822] cm
-0 g
-0 G
-[1 0 0 1 -303.676 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.995 500.822 Td
-/F128_0 9.963 Tf
-(when) 21.5799 Tj
--233 TJm
-(there) 19.916 Tj
--232 TJm
-(is) 6.64532 Tj
--233 TJm
-(an) 9.40507 Tj
--233 TJm
-(error) 19.3581 Tj
--232 TJm
-(reading) 29.879 Tj
--233 TJm
-(or) 8.29918 Tj
--233 TJm
-(writing) 28.7831 Tj
--232 TJm
-(in) 7.75121 Tj
--233 TJm
-(the) 12.1748 Tj
--233 TJm
-(compress) 37.6303 Tj
-1 TJm
-(ed) 9.40507 Tj
-108 488.867 Td
-(\002le,) 15.2235 Tj
--384 TJm
-(and) 14.3866 Tj
--357 TJm
-(by) 9.963 Tj
-[1 0 0 1 158.511 488.867] cm
-0 g
-0 G
-[1 0 0 1 -158.511 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.511 488.867 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadOpen) 83.6892 Tj
-[1 0 0 1 242.197 488.867] cm
-0 g
-0 G
-[1 0 0 1 -242.197 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.755 488.867 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 263.698 488.867] cm
-0 g
-0 G
-[1 0 0 1 -263.698 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.698 488.867 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteOpen) 89.667 Tj
-[1 0 0 1 353.362 488.867] cm
-0 g
-0 G
-[1 0 0 1 -353.362 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-356.92 488.867 Td
-/F128_0 9.963 Tf
-(for) 11.6169 Tj
--357 TJm
-(attempts) 33.7646 Tj
--357 TJm
-(to) 7.75121 Tj
--357 TJm
-(use) 13.2807 Tj
--357 TJm
-(a) 4.42357 Tj
--357 TJm
-(\002le) 12.7327 Tj
--357 TJm
-(for) 11.6169 Tj
--357 TJm
-(which) 24.3496 Tj
--357 TJm
-(the) 12.1748 Tj
--357 TJm
-(error) 19.3581 Tj
-108 476.912 Td
-(indicator) 35.4185 Tj
--260 TJm
-(\(viz,) 17.9832 Tj
-[1 0 0 1 166.603 476.912] cm
-0 g
-0 G
-[1 0 0 1 -166.603 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.603 476.912 Td
-/F130_0 9.963 Tf
-(ferror\(f\)) 53.8002 Tj
-[1 0 0 1 220.401 476.912] cm
-0 g
-0 G
-[1 0 0 1 -220.401 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.401 476.912 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--260 TJm
-(is) 6.64532 Tj
--260 TJm
-(set.) 13.5596 Tj
--679 TJm
-(On) 12.1748 Tj
--260 TJm
-(receipt) 27.1093 Tj
--260 TJm
-(of) 8.29918 Tj
-[1 0 0 1 311.223 476.912] cm
-0 g
-0 G
-[1 0 0 1 -311.223 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-311.223 476.912 Td
-/F130_0 9.963 Tf
-(BZ_IO_ERROR) 65.7558 Tj
-[1 0 0 1 376.976 476.912] cm
-0 g
-0 G
-[1 0 0 1 -376.976 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-376.976 476.912 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--260 TJm
-(the) 12.1748 Tj
--260 TJm
-(caller) 22.1278 Tj
--260 TJm
-(should) 26.5713 Tj
--259 TJm
-(consult) 28.7831 Tj
-[1 0 0 1 482.068 476.912] cm
-0 g
-0 G
-[1 0 0 1 -482.068 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.068 476.912 Td
-/F130_0 9.963 Tf
-(errno) 29.889 Tj
-[1 0 0 1 511.956 476.912] cm
-0 g
-0 G
-[1 0 0 1 -511.956 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-514.546 476.912 Td
-/F128_0 9.963 Tf
-(and/or) 25.4555 Tj
-[1 0 0 1 108 464.957] cm
-0 g
-0 G
-[1 0 0 1 -108 -464.957] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 464.957 Td
-/F130_0 9.963 Tf
-(perror) 35.8668 Tj
-[1 0 0 1 143.865 464.957] cm
-0 g
-0 G
-[1 0 0 1 -143.865 -464.957] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.356 464.957 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(acquire) 29.3211 Tj
--250 TJm
-(operating-system) 68.6251 Tj
--249 TJm
-(speci\002c) 30.437 Tj
--250 TJm
-(information) 47.0453 Tj
--250 TJm
-(about) 22.1378 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(problem.) 35.6974 Tj
-[1 0 0 1 72 462.8] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -448.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.054 Td
-/F130_0 9.963 Tf
-(BZ_UNEXPECTED_EOF) 101.623 Tj
-[1 0 0 1 173.619 439.054] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -104.11 -1.166] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -437.888] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 427.099 Td
-/F128_0 9.963 Tf
-(Returned) 36.5244 Tj
--250 TJm
-(by) 9.963 Tj
-[1 0 0 1 159.467 427.099] cm
-0 g
-0 G
-[1 0 0 1 -159.467 -427.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.467 427.099 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 219.242 427.099] cm
-0 g
-0 G
-[1 0 0 1 -219.242 -427.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.733 427.099 Td
-/F128_0 9.963 Tf
-(when) 21.5799 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(\002nis) 17.1662 Tj
-1 TJm
-(hes) 13.2807 Tj
--250 TJm
-(before) 25.4455 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(logical) 27.1193 Tj
--250 TJm
-(end) 14.3866 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(stream) 26.5614 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(detected.) 35.6875 Tj
-[1 0 0 1 72 424.942] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -410.994] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 401.196 Td
-/F130_0 9.963 Tf
-(BZ_OUTBUFF_FULL) 89.667 Tj
-[1 0 0 1 161.664 401.196] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -92.154 -1.166] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -400.03] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 389.241 Td
-/F128_0 9.963 Tf
-(Returned) 36.5244 Tj
--258 TJm
-(by) 9.963 Tj
-[1 0 0 1 159.632 389.241] cm
-0 g
-0 G
-[1 0 0 1 -159.632 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.632 389.241 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffCompress) 143.467 Tj
-[1 0 0 1 303.094 389.241] cm
-0 g
-0 G
-[1 0 0 1 -303.094 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.667 389.241 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 322.627 389.241] cm
-0 g
-0 G
-[1 0 0 1 -322.627 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-322.627 389.241 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffDecompres) 149.445 Tj
-1 TJm
-(s) 5.9778 Tj
-[1 0 0 1 478.044 389.241] cm
-0 g
-0 G
-[1 0 0 1 -478.044 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-480.617 389.241 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--258 TJm
-(indicate) 31.5429 Tj
--258 TJm
-(that) 14.9445 Tj
-108 377.285 Td
-(the) 12.1748 Tj
--250 TJm
-(output) 25.4654 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(will) 15.5024 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(\002t) 8.30914 Tj
--250 TJm
-(in) 7.75121 Tj
-1 TJm
-(to) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(output) 25.4654 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--250 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vided.) 24.6285 Tj
-[1 0 0 1 72 375.129] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -3.985] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -351.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 328.585 Td
-/F121_0 20.659 Tf
-(3.3.) 34.4592 Tj
--278 TJm
-(Lo) 25.2453 Tj
-15 TJm
-(w-le) 40.1818 Tj
-15 TJm
-(vel) 28.716 Tj
--278 TJm
-(interface) 86.1067 Tj
-[1 0 0 1 72 328.327] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -318.364] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 297.964 Td
-/F121_0 17.215 Tf
-(3.3.1.) 43.0719 Tj
-[1 0 0 1 119.858 297.964] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -297.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 297.964 Td
-/F387_0 17.215 Tf
-(BZ2_bzCompressInit) 185.922 Tj
-[1 0 0 1 305.785 297.964] cm
-0 g
-0 G
-[1 0 0 1 -233.785 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -244.779] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.852 Td
-/F128_0 9.963 Tf
-(11) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 15 15
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -296.523] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 274.969 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 271.382] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(typedef) 41.8446 Tj
--426 TJm
-(struct) 35.8668 Tj
--426 TJm
-({) 5.9778 Tj
-98.488 699.676 Td
-(char) 23.9112 Tj
--426 TJm
-(*next_in;) 53.8002 Tj
-98.488 687.721 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(avail_in;) 53.8002 Tj
-98.488 675.766 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(total_in_lo3) 71.7336 Tj
-1 TJm
-(2;) 11.9556 Tj
-98.488 663.811 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(total_in_hi3) 71.7336 Tj
-1 TJm
-(2;) 11.9556 Tj
-98.488 639.9 Td
-(char) 23.9112 Tj
--426 TJm
-(*next_out;) 59.778 Tj
-98.488 627.945 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(avail_out;) 59.778 Tj
-98.488 615.99 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(total_out_lo) 71.7336 Tj
-1 TJm
-(32;) 17.9334 Tj
-98.488 604.035 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(total_out_hi) 71.7336 Tj
-1 TJm
-(32;) 17.9334 Tj
-98.488 580.124 Td
-(void) 23.9112 Tj
--426 TJm
-(*state;) 41.8446 Tj
-98.488 556.214 Td
-(void) 23.9112 Tj
--426 TJm
-(*\(*bzalloc\)\(void) 95.6448 Tj
--426 TJm
-(*,i) 17.9334 Tj
-1 TJm
-(nt,int\);) 47.8224 Tj
-98.488 544.259 Td
-(void) 23.9112 Tj
--426 TJm
-(\(*bzfree\)\(void) 83.6892 Tj
--426 TJm
-(*,voi) 29.889 Tj
-1 TJm
-(d) 5.9778 Tj
--426 TJm
-(*\);) 17.9334 Tj
-98.488 532.304 Td
-(void) 23.9112 Tj
--426 TJm
-(*opaque;) 47.8224 Tj
-90 520.349 Td
-(}) 5.9778 Tj
--426 TJm
-(bz_stream;) 59.778 Tj
-90 496.438 Td
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzCompressInit) 107.6 Tj
--426 TJm
-(\() 5.9778 Tj
--425 TJm
-(bz_stream) 53.8002 Tj
--426 TJm
-(*strm,) 35.8668 Tj
-196.099 484.483 Td
-(int) 17.9334 Tj
--426 TJm
-(blockSize100k,) 83.6892 Tj
-196.099 472.528 Td
-(int) 17.9334 Tj
--426 TJm
-(verbosity,) 59.778 Tj
-196.099 460.573 Td
-(int) 17.9334 Tj
--426 TJm
-(workFactor) 59.778 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 445.031] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -435.068] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 423.113 Td
-/F128_0 9.963 Tf
-(Prepares) 34.3026 Tj
--356 TJm
-(for) 11.6169 Tj
--356 TJm
-(compressi) 40.4 Tj
-1 TJm
-(on.) 12.4538 Tj
--1256 TJm
-(The) 15.4925 Tj
-[1 0 0 1 209.409 423.113] cm
-0 g
-0 G
-[1 0 0 1 -209.409 -423.113] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-209.409 423.113 Td
-/F130_0 9.963 Tf
-(bz_stream) 53.8002 Tj
-[1 0 0 1 263.208 423.113] cm
-0 g
-0 G
-[1 0 0 1 -263.208 -423.113] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.754 423.113 Td
-/F128_0 9.963 Tf
-(structure) 34.8605 Tj
--356 TJm
-(holds) 21.5898 Tj
--356 TJm
-(all) 9.963 Tj
--356 TJm
-(d) 4.9815 Tj
-1 TJm
-(ata) 11.6169 Tj
--356 TJm
-(pertaining) 40.4 Tj
--356 TJm
-(to) 7.75121 Tj
--356 TJm
-(the) 12.1748 Tj
--356 TJm
-(compression) 50.363 Tj
--356 TJm
-(acti) 14.3866 Tj
-25 TJm
-(vit) 10.5209 Tj
-1 TJm
-(y) 4.9815 Tj
-65 TJm
-(.) 2.49075 Tj
--1256 TJm
-(A) 7.19329 Tj
-[1 0 0 1 72 411.158] cm
-0 g
-0 G
-[1 0 0 1 -72 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 411.158 Td
-/F130_0 9.963 Tf
-(bz_stream) 53.8002 Tj
-[1 0 0 1 125.798 411.158] cm
-0 g
-0 G
-[1 0 0 1 -125.798 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.581 411.158 Td
-/F128_0 9.963 Tf
-(structure) 34.8605 Tj
--279 TJm
-(should) 26.5713 Tj
--279 TJm
-(be) 9.40507 Tj
--280 TJm
-(allocate) 30.9849 Tj
-1 TJm
-(d) 4.9815 Tj
--280 TJm
-(and) 14.3866 Tj
--279 TJm
-(initialised) 39.304 Tj
--279 TJm
-(prior) 19.3681 Tj
--279 TJm
-(to) 7.75121 Tj
--280 TJm
-(the) 12.1748 Tj
--279 TJm
-(call.) 16.8773 Tj
--796 TJm
-(The) 15.4925 Tj
--279 TJm
-(\002elds) 21.5898 Tj
--279 TJm
-(of) 8.29918 Tj
-[1 0 0 1 431.939 411.158] cm
-0 g
-0 G
-[1 0 0 1 -431.939 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.939 411.158 Td
-/F130_0 9.963 Tf
-(bz_stream) 53.8002 Tj
-[1 0 0 1 485.738 411.158] cm
-0 g
-0 G
-[1 0 0 1 -485.738 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-488.52 411.158 Td
-/F128_0 9.963 Tf
-(comprise) 36.5244 Tj
--279 TJm
-(the) 12.1748 Tj
-72 399.203 Td
-(entirety) 30.437 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(user) 16.5984 Tj
-20 TJm
-(-visible) 29.889 Tj
--250 TJm
-(d) 4.9815 Tj
-1 TJm
-(ata.) 14.1076 Tj
-[1 0 0 1 204.422 399.203] cm
-0 g
-0 G
-[1 0 0 1 -204.422 -399.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.422 399.203 Td
-/F130_0 9.963 Tf
-(state) 29.889 Tj
-[1 0 0 1 234.31 399.203] cm
-0 g
-0 G
-[1 0 0 1 -234.31 -399.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.8 399.203 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(pointer) 28.2252 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(pri) 11.0689 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ate) 11.6169 Tj
--250 TJm
-(data) 16.5984 Tj
--249 TJm
-(structures) 38.7361 Tj
--250 TJm
-(required) 33.1967 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(compression.) 52.8537 Tj
-[1 0 0 1 72 397.046] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -387.084] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 377.285 Td
-/F128_0 9.963 Tf
-(Custom) 31.0049 Tj
--372 TJm
-(memory) 33.2067 Tj
--372 TJm
-(allocators) 38.7361 Tj
--372 TJm
-(are) 12.1648 Tj
--372 TJm
-(supported,) 41.7848 Tj
--402 TJm
-(via) 12.1748 Tj
--372 TJm
-(\002elds) 21.5898 Tj
-[1 0 0 1 288.908 377.285] cm
-0 g
-0 G
-[1 0 0 1 -288.908 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-288.908 377.285 Td
-/F130_0 9.963 Tf
-(bzalloc) 41.8446 Tj
-[1 0 0 1 330.751 377.285] cm
-0 g
-0 G
-[1 0 0 1 -330.751 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.751 377.285 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 337.253 377.285] cm
-0 g
-0 G
-[1 0 0 1 -337.253 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-337.253 377.285 Td
-/F130_0 9.963 Tf
-(bzfree) 35.8668 Tj
-[1 0 0 1 373.118 377.285] cm
-0 g
-0 G
-[1 0 0 1 -373.118 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-373.118 377.285 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--403 TJm
-(and) 14.3866 Tj
-[1 0 0 1 397.714 377.285] cm
-0 g
-0 G
-[1 0 0 1 -397.714 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-397.714 377.285 Td
-/F130_0 9.963 Tf
-(opaque) 35.8668 Tj
-[1 0 0 1 433.579 377.285] cm
-0 g
-0 G
-[1 0 0 1 -433.579 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-433.579 377.285 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1353 TJm
-(The) 15.4925 Tj
--372 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
-[1 0 0 1 493.782 377.285] cm
-0 g
-0 G
-[1 0 0 1 -493.782 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.782 377.285 Td
-/F130_0 9.963 Tf
-(opaque) 35.8668 Tj
-[1 0 0 1 529.648 377.285] cm
-0 g
-0 G
-[1 0 0 1 -529.648 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 377.285 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
-72 365.33 Td
-(passed) 26.5614 Tj
--306 TJm
-(to) 7.75121 Tj
--306 TJm
-(as) 8.29918 Tj
--306 TJm
-(the) 12.1748 Tj
--306 TJm
-(\002) 5.53943 Tj
-1 TJm
-(rst) 9.963 Tj
--306 TJm
-(ar) 7.74125 Tj
-18 TJm
-(gument) 29.889 Tj
--306 TJm
-(to) 7.75121 Tj
--306 TJm
-(all) 9.963 Tj
--306 TJm
-(calls) 18.2622 Tj
--306 TJm
-(to) 7.75121 Tj
-[1 0 0 1 253.941 365.33] cm
-0 g
-0 G
-[1 0 0 1 -253.941 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.941 365.33 Td
-/F130_0 9.963 Tf
-(bzalloc) 41.8446 Tj
-[1 0 0 1 295.784 365.33] cm
-0 g
-0 G
-[1 0 0 1 -295.784 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-298.832 365.33 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 316.266 365.33] cm
-0 g
-0 G
-[1 0 0 1 -316.266 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-316.266 365.33 Td
-/F130_0 9.963 Tf
-(bzfree) 35.8668 Tj
-[1 0 0 1 352.132 365.33] cm
-0 g
-0 G
-[1 0 0 1 -352.132 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-352.132 365.33 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--320 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--306 TJm
-(is) 6.64532 Tj
--306 TJm
-(otherwise) 38.7361 Tj
--305 TJm
-(ignored) 30.437 Tj
--306 TJm
-(by) 9.963 Tj
--306 TJm
-(the) 12.1748 Tj
--306 TJm
-(library) 26.5614 Tj
-65 TJm
-(.) 2.49075 Tj
--956 TJm
-(The) 15.4925 Tj
-72 353.375 Td
-(call) 14.3866 Tj
-[1 0 0 1 89.431 353.375] cm
-0 g
-0 G
-[1 0 0 1 -89.431 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-89.431 353.375 Td
-/F130_0 9.963 Tf
-(bzalloc) 41.8446 Tj
--600 TJm
-(\() 5.9778 Tj
--600 TJm
-(opaque,) 41.8446 Tj
--600 TJm
-(n,) 11.9556 Tj
--600 TJm
-(m) 5.9778 Tj
--600 TJm
-(\)) 5.9778 Tj
-[1 0 0 1 232.893 353.375] cm
-0 g
-0 G
-[1 0 0 1 -232.893 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.938 353.375 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--306 TJm
-(e) 4.42357 Tj
-15 TJm
-(xpect) 21.5799 Tj
-1 TJm
-(ed) 9.40507 Tj
--306 TJm
-(to) 7.75121 Tj
--306 TJm
-(return) 23.7916 Tj
--305 TJm
-(a) 4.42357 Tj
--306 TJm
-(pointer) 28.2252 Tj
-[1 0 0 1 360.3 353.375] cm
-0 g
-0 G
-[1 0 0 1 -360.3 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.3 353.375 Td
-/F130_0 9.963 Tf
-(p) 5.9778 Tj
-[1 0 0 1 366.277 353.375] cm
-0 g
-0 G
-[1 0 0 1 -366.277 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-369.322 353.375 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
-[1 0 0 1 380.118 353.375] cm
-0 g
-0 G
-[1 0 0 1 -380.118 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-380.118 353.375 Td
-/F130_0 9.963 Tf
-(n) 5.9778 Tj
--600 TJm
-(*) 5.9778 Tj
--600 TJm
-(m) 5.9778 Tj
-[1 0 0 1 410.006 353.375] cm
-0 g
-0 G
-[1 0 0 1 -410.006 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-413.051 353.375 Td
-/F128_0 9.963 Tf
-(bytes) 21.0319 Tj
--306 TJm
-(of) 8.29918 Tj
--305 TJm
-(memory) 33.2067 Tj
-65 TJm
-(,) 2.49075 Tj
--320 TJm
-(and) 14.3866 Tj
-[1 0 0 1 504.135 353.375] cm
-0 g
-0 G
-[1 0 0 1 -504.135 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-504.135 353.375 Td
-/F130_0 9.963 Tf
-(bzfree) 35.8668 Tj
-72 341.42 Td
-(\() 5.9778 Tj
--600 TJm
-(opaque,) 41.8446 Tj
--600 TJm
-(p) 5.9778 Tj
--600 TJm
-(\)) 5.9778 Tj
-[1 0 0 1 149.709 341.42] cm
-0 g
-0 G
-[1 0 0 1 -149.709 -341.42] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.199 341.42 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--250 TJm
-(free) 15.4825 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(memory) 33.2067 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 339.263] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -329.3] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 319.502 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--280 TJm
-(you) 14.9445 Tj
--280 TJm
-(don') 18.2622 Tj
-18 TJm
-(t) 2.76971 Tj
--279 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--280 TJm
-(to) 7.75121 Tj
--280 TJm
-(use) 13.2807 Tj
--280 TJm
-(a) 4.42357 Tj
--279 TJm
-(custom) 28.7831 Tj
--280 TJm
-(memory) 33.2067 Tj
--280 TJm
-(allocator) 34.8605 Tj
-40 TJm
-(,) 2.49075 Tj
--287 TJm
-(set) 11.0689 Tj
-[1 0 0 1 299.9 319.502] cm
-0 g
-0 G
-[1 0 0 1 -299.9 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.9 319.502 Td
-/F130_0 9.963 Tf
-(bzalloc) 41.8446 Tj
-[1 0 0 1 341.743 319.502] cm
-0 g
-0 G
-[1 0 0 1 -341.743 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.743 319.502 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 347.096 319.502] cm
-0 g
-0 G
-[1 0 0 1 -347.096 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-347.096 319.502 Td
-/F130_0 9.963 Tf
-(bzfree) 35.8668 Tj
-[1 0 0 1 382.961 319.502] cm
-0 g
-0 G
-[1 0 0 1 -382.961 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-385.749 319.502 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 402.923 319.502] cm
-0 g
-0 G
-[1 0 0 1 -402.923 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-402.923 319.502 Td
-/F130_0 9.963 Tf
-(opaque) 35.8668 Tj
-[1 0 0 1 438.788 319.502] cm
-0 g
-0 G
-[1 0 0 1 -438.788 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.576 319.502 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
-[1 0 0 1 452.115 319.502] cm
-0 g
-0 G
-[1 0 0 1 -452.115 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-452.115 319.502 Td
-/F130_0 9.963 Tf
-(NULL) 23.9112 Tj
-[1 0 0 1 476.025 319.502] cm
-0 g
-0 G
-[1 0 0 1 -476.025 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-476.025 319.502 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--280 TJm
-(and) 14.3866 Tj
--280 TJm
-(the) 12.1748 Tj
--279 TJm
-(library) 26.5614 Tj
-72 307.547 Td
-(will) 15.5024 Tj
--250 TJm
-(then) 17.1563 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(standard) 33.7546 Tj
-[1 0 0 1 176.318 307.547] cm
-0 g
-0 G
-[1 0 0 1 -176.318 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.318 307.547 Td
-/F130_0 9.963 Tf
-(malloc) 35.8668 Tj
-[1 0 0 1 212.183 307.547] cm
-0 g
-0 G
-[1 0 0 1 -212.183 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.674 307.547 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 219.934 307.547] cm
-0 g
-0 G
-[1 0 0 1 -219.934 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-219.934 307.547 Td
-/F130_0 9.963 Tf
-(free) 23.9112 Tj
-[1 0 0 1 243.844 307.547] cm
-0 g
-0 G
-[1 0 0 1 -243.844 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.335 307.547 Td
-/F128_0 9.963 Tf
-(routines.) 34.5915 Tj
-[1 0 0 1 72 307.338] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -297.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 285.629 Td
-/F128_0 9.963 Tf
-(Before) 27.1093 Tj
--362 TJm
-(calling) 27.1193 Tj
-[1 0 0 1 133.438 285.629] cm
-0 g
-0 G
-[1 0 0 1 -133.438 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-133.438 285.629 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 241.035 285.629] cm
-0 g
-0 G
-[1 0 0 1 -241.035 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-241.035 285.629 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--390 TJm
-(\002elds) 21.5898 Tj
-[1 0 0 1 272.606 285.629] cm
-0 g
-0 G
-[1 0 0 1 -272.606 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.606 285.629 Td
-/F130_0 9.963 Tf
-(bzalloc) 41.8446 Tj
-[1 0 0 1 314.449 285.629] cm
-0 g
-0 G
-[1 0 0 1 -314.449 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-314.449 285.629 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 320.825 285.629] cm
-0 g
-0 G
-[1 0 0 1 -320.825 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-320.825 285.629 Td
-/F130_0 9.963 Tf
-(bzfree) 35.8668 Tj
-[1 0 0 1 356.69 285.629] cm
-0 g
-0 G
-[1 0 0 1 -356.69 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.296 285.629 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 378.288 285.629] cm
-0 g
-0 G
-[1 0 0 1 -378.288 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-378.288 285.629 Td
-/F130_0 9.963 Tf
-(opaque) 35.8668 Tj
-[1 0 0 1 414.154 285.629] cm
-0 g
-0 G
-[1 0 0 1 -414.154 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-417.76 285.629 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--362 TJm
-(be) 9.40507 Tj
--362 TJm
-(\002lled) 20.4839 Tj
--362 TJm
-(appropriat) 40.9479 Tj
-1 TJm
-(ely) 12.1748 Tj
-65 TJm
-(,) 2.49075 Tj
-72 273.674 Td
-(as) 8.29918 Tj
--322 TJm
-(just) 14.3965 Tj
--323 TJm
-(described.) 40.669 Tj
--1055 TJm
-(U) 7.19329 Tj
-1 TJm
-(pon) 14.9445 Tj
--323 TJm
-(return,) 26.2824 Tj
--340 TJm
-(the) 12.1748 Tj
--323 TJm
-(internal) 30.437 Tj
--322 TJm
-(state) 18.2622 Tj
--322 TJm
-(will) 15.5024 Tj
--323 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--322 TJm
-(been) 18.8101 Tj
--323 TJm
-(allocated) 35.9664 Tj
--322 TJm
-(and) 14.3866 Tj
--322 TJm
-(initialised,) 41.7948 Tj
--341 TJm
-(and) 14.3866 Tj
-[1 0 0 1 459.801 273.674] cm
-0 g
-0 G
-[1 0 0 1 -459.801 -273.674] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-459.801 273.674 Td
-/F130_0 9.963 Tf
-(total_in_lo32) 77.7114 Tj
-[1 0 0 1 537.509 273.674] cm
-0 g
-0 G
-[1 0 0 1 -537.509 -273.674] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 273.674 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 72 261.719] cm
-0 g
-0 G
-[1 0 0 1 -72 -261.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 261.719 Td
-/F130_0 9.963 Tf
-(total_in_hi32) 77.7114 Tj
-[1 0 0 1 149.709 261.719] cm
-0 g
-0 G
-[1 0 0 1 -149.709 -261.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-149.709 261.719 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 155.006 261.719] cm
-0 g
-0 G
-[1 0 0 1 -155.006 -261.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.006 261.719 Td
-/F130_0 9.963 Tf
-(total_out_lo32) 83.6892 Tj
-[1 0 0 1 238.692 261.719] cm
-0 g
-0 G
-[1 0 0 1 -238.692 -261.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-241.435 261.719 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 258.564 261.719] cm
-0 g
-0 G
-[1 0 0 1 -258.564 -261.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.564 261.719 Td
-/F130_0 9.963 Tf
-(total_out_hi32) 83.6892 Tj
-[1 0 0 1 342.25 261.719] cm
-0 g
-0 G
-[1 0 0 1 -342.25 -261.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-344.994 261.719 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--275 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--276 TJm
-(b) 4.9815 Tj
-1 TJm
-(een) 13.8286 Tj
--276 TJm
-(set) 11.0689 Tj
--275 TJm
-(to) 7.75121 Tj
--275 TJm
-(zero.) 19.6371 Tj
--772 TJm
-(These) 23.7916 Tj
--276 TJm
-(four) 16.5984 Tj
--275 TJm
-(\002elds) 21.5898 Tj
--275 TJm
-(are) 12.1648 Tj
-72 249.763 Td
-(used) 18.2622 Tj
--339 TJm
-(by) 9.963 Tj
--340 TJm
-(the) 12.1748 Tj
--339 TJm
-(library) 26.5614 Tj
--340 TJm
-(to) 7.75121 Tj
--339 TJm
-(inform) 27.1193 Tj
--340 TJm
-(the) 12.1748 Tj
--339 TJm
-(caller) 22.1278 Tj
--340 TJm
-(of) 8.29918 Tj
--339 TJm
-(the) 12.1748 Tj
--340 TJm
-(total) 17.7142 Tj
--339 TJm
-(amount) 29.889 Tj
--340 TJm
-(of) 8.29918 Tj
--339 TJm
-(data) 16.5984 Tj
--339 TJm
-(passed) 26.5614 Tj
--340 TJm
-(into) 15.5024 Tj
--339 TJm
-(and) 14.3866 Tj
--340 TJm
-(out) 12.7327 Tj
--339 TJm
-(of) 8.29918 Tj
--340 TJm
-(the) 12.1748 Tj
--339 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--362 TJm
-(respecti) 30.9849 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ely) 12.1748 Tj
-65 TJm
-(.) 2.49075 Tj
-72 237.808 Td
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--376 TJm
-(should) 26.5713 Tj
--377 TJm
-(not) 12.7327 Tj
--376 TJm
-(try) 11.0689 Tj
--376 TJm
-(to) 7.75121 Tj
--377 TJm
-(c) 4.42357 Tj
-1 TJm
-(hange) 23.7916 Tj
--377 TJm
-(them.) 22.4168 Tj
--1378 TJm
-(As) 11.0689 Tj
--376 TJm
-(of) 8.29918 Tj
--377 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-1 TJm
-(rsion) 19.926 Tj
--377 TJm
-(1.0,) 14.9445 Tj
--408 TJm
-(64-bit) 23.8016 Tj
--376 TJm
-(counts) 26.0134 Tj
--376 TJm
-(are) 12.1648 Tj
--376 TJm
-(maintained,) 46.7663 Tj
--408 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--377 TJm
-(on) 9.963 Tj
--376 TJm
-(32-bit) 23.8016 Tj
--376 TJm
-(platforms,) 40.6789 Tj
-72 225.853 Td
-(using) 21.5898 Tj
--371 TJm
-(the) 12.1748 Tj
-[1 0 0 1 113.148 225.853] cm
-0 g
-0 G
-[1 0 0 1 -113.148 -225.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.148 225.853 Td
-/F130_0 9.963 Tf
-(_hi32) 29.889 Tj
-[1 0 0 1 143.036 225.853] cm
-0 g
-0 G
-[1 0 0 1 -143.036 -225.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.729 225.853 Td
-/F128_0 9.963 Tf
-(\002elds) 21.5898 Tj
--371 TJm
-(to) 7.75121 Tj
--370 TJm
-(store) 19.3681 Tj
--371 TJm
-(the) 12.1748 Tj
--370 TJm
-(upper) 22.6858 Tj
--371 TJm
-(32) 9.963 Tj
--370 TJm
-(bits) 14.3965 Tj
--371 TJm
-(of) 8.29918 Tj
--371 TJm
-(the) 12.1748 Tj
--370 TJm
-(count.) 24.6285 Tj
--1344 TJm
-(So,) 13.0117 Tj
--401 TJm
-(for) 11.6169 Tj
--370 TJm
-(e) 4.42357 Tj
-15 TJm
-(xample,) 31.8218 Tj
--401 TJm
-(the) 12.1748 Tj
--370 TJm
-(total) 17.7142 Tj
--371 TJm
-(amount) 29.889 Tj
--371 TJm
-(of) 8.29918 Tj
--370 TJm
-(data) 16.5984 Tj
--371 TJm
-(in) 7.75121 Tj
--370 TJm
-(is) 6.64532 Tj
-[1 0 0 1 72 213.898] cm
-0 g
-0 G
-[1 0 0 1 -72 -213.898] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 213.898 Td
-/F130_0 9.963 Tf
-(\(total_in_hi32) 83.6892 Tj
--600 TJm
-(<<) 11.9556 Tj
--600 TJm
-(32\)) 17.9334 Tj
--600 TJm
-(+) 5.9778 Tj
--600 TJm
-(to) 11.9556 Tj
-1 TJm
-(tal_in_lo32) 65.7558 Tj
-[1 0 0 1 293.171 213.898] cm
-0 g
-0 G
-[1 0 0 1 -293.171 -213.898] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.171 213.898 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 212.732] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -202.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 191.98 Td
-/F128_0 9.963 Tf
-(P) 5.53943 Tj
-15 TJm
-(arameter) 34.8506 Tj
-[1 0 0 1 115.367 191.98] cm
-0 g
-0 G
-[1 0 0 1 -115.367 -191.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-115.367 191.98 Td
-/F130_0 9.963 Tf
-(blockSize100k) 77.7114 Tj
-[1 0 0 1 193.076 191.98] cm
-0 g
-0 G
-[1 0 0 1 -193.076 -191.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.205 191.98 Td
-/F128_0 9.963 Tf
-(speci\002es) 34.3126 Tj
--314 TJm
-(the) 12.1748 Tj
--314 TJm
-(block) 22.1378 Tj
--314 TJm
-(size) 15.4925 Tj
--314 TJm
-(to) 7.75121 Tj
--314 TJm
-(be) 9.40507 Tj
--314 TJm
-(used) 18.2622 Tj
--314 TJm
-(for) 11.6169 Tj
--314 TJm
-(comp) 22.1378 Tj
-1 TJm
-(ression.) 30.7159 Tj
--1005 TJm
-(It) 6.08739 Tj
--314 TJm
-(sh) 8.85711 Tj
-1 TJm
-(ould) 17.7142 Tj
--314 TJm
-(be) 9.40507 Tj
--314 TJm
-(a) 4.42357 Tj
--314 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--314 TJm
-(between) 33.1967 Tj
--314 TJm
-(1) 4.9815 Tj
-72 180.025 Td
-(and) 14.3866 Tj
--289 TJm
-(9) 4.9815 Tj
--289 TJm
-(inclusi) 26.5713 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e,) 6.91432 Tj
--299 TJm
-(and) 14.3866 Tj
--289 TJm
-(the) 12.1748 Tj
--289 TJm
-(actua) 21.0219 Tj
-1 TJm
-(l) 2.76971 Tj
--290 TJm
-(b) 4.9815 Tj
-1 TJm
-(lock) 17.1563 Tj
--289 TJm
-(size) 15.4925 Tj
--289 TJm
-(used) 18.2622 Tj
--289 TJm
-(is) 6.64532 Tj
--289 TJm
-(100000) 29.889 Tj
--289 TJm
-(x) 4.9815 Tj
--289 TJm
-(this) 14.3965 Tj
--289 TJm
-(\002gure.) 25.7344 Tj
--854 TJm
-(9) 4.9815 Tj
--289 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--289 TJm
-(the) 12.1748 Tj
--289 TJm
-(best) 16.0504 Tj
--289 TJm
-(compression) 50.363 Tj
--289 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--289 TJm
-(tak) 12.1748 Tj
-10 TJm
-(es) 8.29918 Tj
--289 TJm
-(most) 19.378 Tj
-72 168.07 Td
-(memory) 33.2067 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 165.913] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -155.95] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 146.152 Td
-/F128_0 9.963 Tf
-(P) 5.53943 Tj
-15 TJm
-(arameter) 34.8506 Tj
-[1 0 0 1 115.095 146.152] cm
-0 g
-0 G
-[1 0 0 1 -115.095 -146.152] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-115.095 146.152 Td
-/F130_0 9.963 Tf
-(verbosity) 53.8002 Tj
-[1 0 0 1 168.894 146.152] cm
-0 g
-0 G
-[1 0 0 1 -168.894 -146.152] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.75 146.152 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--287 TJm
-(be) 9.40507 Tj
--286 TJm
-(set) 11.0689 Tj
--287 TJm
-(to) 7.75121 Tj
--287 TJm
-(a) 4.42357 Tj
--286 TJm
-(number) 30.437 Tj
--287 TJm
-(between) 33.1967 Tj
--287 TJm
-(0) 4.9815 Tj
--286 TJm
-(and) 14.3866 Tj
--287 TJm
-(4) 4.9815 Tj
--287 TJm
-(inclusi) 26.5713 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e.) 6.91432 Tj
--840 TJm
-(0) 4.9815 Tj
--287 TJm
-(is) 6.64532 Tj
--286 TJm
-(silent,) 24.0806 Tj
--296 TJm
-(and) 14.3866 Tj
--287 TJm
-(greater) 27.6573 Tj
--286 TJm
-(numbers) 34.3126 Tj
--287 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-72 134.197 Td
-(increasingly) 48.6991 Tj
--342 TJm
-(v) 4.9815 Tj
-15 TJm
-(erbose) 26.0034 Tj
--342 TJm
-(monitoring/deb) 61.4418 Tj
-20 TJm
-(ugging) 27.6772 Tj
--342 TJm
-(output.) 27.9562 Tj
--1173 TJm
-(If) 6.63536 Tj
--342 TJm
-(the) 12.1748 Tj
--342 TJm
-(library) 26.5614 Tj
--342 TJm
-(has) 13.2807 Tj
--342 TJm
-(been) 18.8101 Tj
--342 TJm
-(compiled) 37.0823 Tj
--342 TJm
-(with) 17.7142 Tj
-[1 0 0 1 446.429 134.197] cm
-0 g
-0 G
-[1 0 0 1 -446.429 -134.197] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.429 134.197 Td
-/F130_0 9.963 Tf
-(-DBZ_NO_STDIO) 77.7114 Tj
-[1 0 0 1 524.138 134.197] cm
-0 g
-0 G
-[1 0 0 1 -524.138 -134.197] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-524.138 134.197 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--342 TJm
-(no) 9.963 Tj
-72 122.242 Td
-(such) 18.2622 Tj
--250 TJm
-(output) 25.4654 Tj
--250 TJm
-(will) 15.5024 Tj
--250 TJm
-(appear) 26.5514 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--249 TJm
-(v) 4.9815 Tj
-15 TJm
-(erbosity) 32.1008 Tj
--250 TJm
-(setting.) 29.0621 Tj
-[1 0 0 1 72 120.085] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -110.122] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 100.324 Td
-/F128_0 9.963 Tf
-(P) 5.53943 Tj
-15 TJm
-(arameter) 34.8506 Tj
-[1 0 0 1 116.619 100.324] cm
-0 g
-0 G
-[1 0 0 1 -116.619 -100.324] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.619 100.324 Td
-/F130_0 9.963 Tf
-(workFactor) 59.778 Tj
-[1 0 0 1 176.395 100.324] cm
-0 g
-0 G
-[1 0 0 1 -176.395 -100.324] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-180.775 100.324 Td
-/F128_0 9.963 Tf
-(controls) 32.1008 Tj
--439 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--440 TJm
-(the) 12.1748 Tj
--440 TJm
-(compr) 25.4555 Tj
-1 TJm
-(ession) 24.9075 Tj
--440 TJm
-(phase) 22.6858 Tj
--440 TJm
-(be) 9.40507 Tj
-1 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--440 TJm
-(when) 21.5799 Tj
--440 TJm
-(presen) 26.0034 Tj
-1 TJm
-(ted) 12.1748 Tj
--440 TJm
-(with) 17.7142 Tj
--440 TJm
-(w) 7.19329 Tj
-10 TJm
-(orst) 14.9445 Tj
--439 TJm
-(case,) 19.6371 Tj
--487 TJm
-(highly) 25.4654 Tj
-72 88.369 Td
-(repetiti) 28.2252 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e,) 6.91432 Tj
--432 TJm
-(input) 20.4839 Tj
--396 TJm
-(data.) 19.0891 Tj
--1497 TJm
-(If) 6.63536 Tj
--396 TJm
-(compression) 50.363 Tj
--396 TJm
-(runs) 17.1563 Tj
--396 TJm
-(into) 15.5024 Tj
--396 TJm
-(dif) 11.0689 Tj
-25 TJm
-(\002culties) 31.5528 Tj
--396 TJm
-(caused) 27.1093 Tj
--396 TJm
-(by) 9.963 Tj
--396 TJm
-(repetiti) 28.2252 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--396 TJm
-(data,) 19.0891 Tj
--432 TJm
-(the) 12.1748 Tj
--396 TJm
-(library) 26.5614 Tj
--396 TJm
-(switches) 34.3126 Tj
--396 TJm
-(from) 19.3681 Tj
-[1 0 0 1 72 50.852] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.852 Td
-/F128_0 9.963 Tf
-(12) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 16 16
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(the) 12.1748 Tj
--255 TJm
-(stan) 16.0504 Tj
-1 TJm
-(dard) 17.7043 Tj
--255 TJm
-(sorting) 27.6772 Tj
--255 TJm
-(alg) 12.1748 Tj
-1 TJm
-(orithm) 26.5713 Tj
--255 TJm
-(to) 7.75121 Tj
--255 TJm
-(a) 4.42357 Tj
--254 TJm
-(f) 3.31768 Tj
-10 TJm
-(allback) 28.7731 Tj
--255 TJm
-(algorithm) 38.7461 Tj
-1 TJm
-(.) 2.49075 Tj
--648 TJm
-(The) 15.4925 Tj
--255 TJm
-(f) 3.31768 Tj
-10 TJm
-(allback) 28.7731 Tj
--254 TJm
-(is) 6.64532 Tj
--255 TJm
-(slo) 11.6268 Tj
-25 TJm
-(wer) 14.9345 Tj
--254 TJm
-(than) 17.1563 Tj
--255 TJm
-(the) 12.1748 Tj
--255 TJm
-(st) 6.64532 Tj
-1 TJm
-(andard) 27.1093 Tj
--255 TJm
-(algorithm) 38.7461 Tj
--254 TJm
-(by) 9.963 Tj
--255 TJm
-(perhaps) 30.9849 Tj
-72 698.082 Td
-(a) 4.42357 Tj
--250 TJm
-(f) 3.31768 Tj
-10 TJm
-(actor) 19.916 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(three,) 22.4068 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(al) 7.19329 Tj
-10 TJm
-(w) 7.19329 Tj
-10 TJm
-(ays) 13.2807 Tj
--250 TJm
-(b) 4.9815 Tj
-1 TJm
-(eha) 13.8286 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--250 TJm
-(reasonably) 43.1597 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(no) 9.963 Tj
--250 TJm
-(matter) 25.4555 Tj
--250 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(bad) 14.3866 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(input.) 22.9747 Tj
-[1 0 0 1 72 695.925] cm
-0 g
-0 G
-[1 0 0 1 0 -9.961] cm
-0 g
-0 G
-[1 0 0 1 -72 -685.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 676.165 Td
-/F128_0 9.963 Tf
-(Lo) 11.0689 Tj
-25 TJm
-(wer) 14.9345 Tj
--240 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
-1 TJm
-(s) 3.87561 Tj
--240 TJm
-(of) 8.29918 Tj
-[1 0 0 1 138.421 676.165] cm
-0 g
-0 G
-[1 0 0 1 -138.421 -676.165] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.421 676.165 Td
-/F130_0 9.963 Tf
-(workFactor) 59.778 Tj
-[1 0 0 1 198.197 676.165] cm
-0 g
-0 G
-[1 0 0 1 -198.197 -676.165] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.585 676.165 Td
-/F128_0 9.963 Tf
-(reduce) 26.5514 Tj
--240 TJm
-(the) 12.1748 Tj
--239 TJm
-(amount) 29.889 Tj
--240 TJm
-(of) 8.29918 Tj
--239 TJm
-(ef) 7.74125 Tj
-25 TJm
-(fort) 14.3866 Tj
--240 TJm
-(the) 12.1748 Tj
--240 TJm
-(standard) 33.7546 Tj
--239 TJm
-(algorithm) 38.7461 Tj
--240 TJm
-(will) 15.5024 Tj
--239 TJm
-(e) 4.42357 Tj
-15 TJm
-(xpend) 24.3496 Tj
--240 TJm
-(before) 25.4455 Tj
--240 TJm
-(re) 7.74125 Tj
-1 TJm
-(sorting) 27.6772 Tj
--240 TJm
-(to) 7.75121 Tj
--240 TJm
-(the) 12.1748 Tj
-72 664.21 Td
-(f) 3.31768 Tj
-10 TJm
-(allback.) 31.2639 Tj
--618 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--248 TJm
-(should) 26.5713 Tj
--247 TJm
-(set) 11.0689 Tj
--248 TJm
-(this) 14.3965 Tj
--247 TJm
-(parameter) 39.8321 Tj
--247 TJm
-(carefully;) 38.1782 Tj
--249 TJm
-(too) 12.7327 Tj
--247 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(,) 2.49075 Tj
--248 TJm
-(and) 14.3866 Tj
--247 TJm
-(man) 17.1563 Tj
-15 TJm
-(y) 4.9815 Tj
--248 TJm
-(inputs) 24.3595 Tj
--247 TJm
-(will) 15.5024 Tj
--248 TJm
-(be) 9.40507 Tj
--247 TJm
-(handled) 31.5429 Tj
--248 TJm
-(by) 9.963 Tj
--247 TJm
-(the) 12.1748 Tj
--248 TJm
-(f) 3.31768 Tj
-10 TJm
-(allback) 28.7731 Tj
--247 TJm
-(algorithm) 38.7461 Tj
-72 652.255 Td
-(and) 14.3866 Tj
--308 TJm
-(so) 8.85711 Tj
--308 TJm
-(compress) 37.6303 Tj
--308 TJm
-(rather) 23.2337 Tj
--308 TJm
-(slo) 11.6268 Tj
-25 TJm
-(wly) 14.9445 Tj
-65 TJm
-(,) 2.49075 Tj
--323 TJm
-(too) 12.7327 Tj
--308 TJm
-(high,) 20.205 Tj
--323 TJm
-(and) 14.3866 Tj
--308 TJm
-(your) 18.2622 Tj
--308 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(erage-to-w) 43.1498 Tj
-10 TJm
-(orst) 14.9445 Tj
--308 TJm
-(case) 17.1463 Tj
--308 TJm
-(compression) 50.363 Tj
--308 TJm
-(times) 21.5898 Tj
--308 TJm
-(can) 13.8286 Tj
--308 TJm
-(become) 30.9849 Tj
--308 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
--308 TJm
-(lar) 10.511 Tj
-18 TJm
-(ge.) 11.8958 Tj
-72 640.3 Td
-(The) 15.4925 Tj
--250 TJm
-(def) 12.7228 Tj
-10 TJm
-(ault) 14.9445 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(30) 9.963 Tj
--250 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--250 TJm
-(re) 7.74125 Tj
-1 TJm
-(asonable) 34.8605 Tj
--250 TJm
-(beha) 18.8101 Tj
-20 TJm
-(viour) 21.0319 Tj
--250 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(wide) 19.3681 Tj
--250 TJm
-(range) 22.1278 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(circumstances.) 58.9311 Tj
-[1 0 0 1 72 638.143] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -628.181] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 618.383 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues) 20.474 Tj
--250 TJm
-(range) 22.1278 Tj
--250 TJm
-(from) 19.3681 Tj
--249 TJm
-(0) 4.9815 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(250) 14.9445 Tj
--250 TJm
-(inclusi) 26.5713 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e.) 6.91432 Tj
--620 TJm
-(0) 4.9815 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(special) 27.6673 Tj
--250 TJm
-(case,) 19.6371 Tj
--250 TJm
-(equi) 17.1563 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(alent) 19.3681 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(usi) 11.6268 Tj
-1 TJm
-(ng) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(def) 12.7228 Tj
-10 TJm
-(ault) 14.9445 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(30.) 12.4538 Tj
-[1 0 0 1 72 616.226] cm
-0 g
-0 G
-[1 0 0 1 0 -9.961] cm
-0 g
-0 G
-[1 0 0 1 -72 -606.265] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 596.466 Td
-/F128_0 9.963 Tf
-(Note) 19.3681 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(out) 12.7327 Tj
-1 TJm
-(put) 12.7327 Tj
--250 TJm
-(generated) 38.7262 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(same) 20.474 Tj
--250 TJm
-(re) 7.74125 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(ardless) 27.6673 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(whether) 32.0908 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(the) 12.1748 Tj
--249 TJm
-(f) 3.31768 Tj
-10 TJm
-(allback) 28.7731 Tj
--250 TJm
-(algorithm) 38.7461 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(used.) 20.7529 Tj
-[1 0 0 1 72 594.309] cm
-0 g
-0 G
-[1 0 0 1 0 -9.961] cm
-0 g
-0 G
-[1 0 0 1 -72 -584.348] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 574.549 Td
-/F128_0 9.963 Tf
-(Be) 11.0689 Tj
--303 TJm
-(a) 4.42357 Tj
-15 TJm
-(w) 7.19329 Tj
-10 TJm
-(are) 12.1648 Tj
--303 TJm
-(also) 16.0504 Tj
--303 TJm
-(that) 14.9445 Tj
--303 TJm
-(this) 14.3965 Tj
--303 TJm
-(parameter) 39.8321 Tj
--303 TJm
-(may) 17.1563 Tj
--303 TJm
-(disappear) 38.1782 Tj
--303 TJm
-(entirely) 30.437 Tj
--303 TJm
-(in) 7.75121 Tj
--303 TJm
-(future) 23.7916 Tj
--303 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--303 TJm
-(of) 8.29918 Tj
--303 TJm
-(the) 12.1748 Tj
--303 TJm
-(library) 26.5614 Tj
-65 TJm
-(.) 2.49075 Tj
--939 TJm
-(In) 8.29918 Tj
--303 TJm
-(principle) 35.4185 Tj
--303 TJm
-(it) 5.53943 Tj
--303 TJm
-(should) 26.5713 Tj
--303 TJm
-(be) 9.40507 Tj
-72 562.594 Td
-(possible) 32.6587 Tj
--270 TJm
-(to) 7.75121 Tj
--270 TJm
-(de) 9.40507 Tj
-25 TJm
-(vise) 16.0504 Tj
--270 TJm
-(a) 4.42357 Tj
--270 TJm
-(good) 19.926 Tj
--270 TJm
-(w) 7.19329 Tj
-10 TJm
-(ay) 9.40507 Tj
--270 TJm
-(to) 7.75121 Tj
--270 TJm
-(automatically) 54.2386 Tj
--270 TJm
-(choose) 27.6673 Tj
--270 TJm
-(which) 24.3496 Tj
--270 TJm
-(algorithm) 38.7461 Tj
--270 TJm
-(to) 7.75121 Tj
--270 TJm
-(use.) 15.7714 Tj
--740 TJm
-(Such) 19.926 Tj
--270 TJm
-(a) 4.42357 Tj
--270 TJm
-(mechanism) 45.3815 Tj
--270 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--270 TJm
-(render) 25.4455 Tj
--270 TJm
-(the) 12.1748 Tj
-72 550.639 Td
-(parameter) 39.8321 Tj
--250 TJm
-(obsolete.) 35.6974 Tj
-[1 0 0 1 72 548.482] cm
-0 g
-0 G
-[1 0 0 1 0 -9.961] cm
-0 g
-0 G
-[1 0 0 1 -72 -538.521] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 528.722 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 528.623] cm
-0 g
-0 G
-[1 0 0 1 0 -144.458] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 143.462 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 139.876] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -519.258] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 519.258 Td
-/F130_0 9.963 Tf
-(BZ_CONFIG_ERROR) 89.667 Tj
-98.488 507.303 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(library) 41.8446 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--425 TJm
-(mis-compiled) 71.7336 Tj
-90 495.348 Td
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 483.392 Td
-(if) 11.9556 Tj
--426 TJm
-(strm) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-98.488 471.437 Td
-(or) 11.9556 Tj
--426 TJm
-(blockSize) 53.8002 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(1) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(bloc) 23.9112 Tj
-1 TJm
-(kSize) 29.889 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(9) 5.9778 Tj
-98.488 459.482 Td
-(or) 11.9556 Tj
--426 TJm
-(verbosity) 53.8002 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(verb) 23.9112 Tj
-1 TJm
-(osity) 29.889 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(4) 5.9778 Tj
-98.488 447.527 Td
-(or) 11.9556 Tj
--426 TJm
-(workFactor) 59.778 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(wor) 17.9334 Tj
-1 TJm
-(kFactor) 41.8446 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(250) 17.9334 Tj
-90 435.572 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 423.617 Td
-(if) 11.9556 Tj
--426 TJm
-(not) 17.9334 Tj
--426 TJm
-(enough) 35.8668 Tj
--426 TJm
-(memory) 35.8668 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(available) 53.8002 Tj
-90 411.661 Td
-(BZ_OK) 29.889 Tj
-98.488 399.706 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 384.165] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.548] cm
-0 g
-0 G
-[1 0 0 1 -72 -374.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 362.248 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 362.148] cm
-0 g
-0 G
-[1 0 0 1 0 -48.817] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 47.821 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 44.234] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -352.783] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 352.783 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-98.488 340.828 Td
-(if) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(returned) 47.8224 Tj
-98.488 328.873 Td
-(no) 11.9556 Tj
--426 TJm
-(specific) 47.8224 Tj
--426 TJm
-(action) 35.8668 Tj
--426 TJm
-(needed) 35.8668 Tj
--425 TJm
-(in) 11.9556 Tj
--426 TJm
-(case) 23.9112 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(error) 29.889 Tj
-[1 0 0 1 72 313.331] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.961] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -303.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 282.711 Td
-/F121_0 17.215 Tf
-(3.3.2.) 43.0719 Tj
-[1 0 0 1 119.858 282.711] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -282.711] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 282.711 Td
-/F387_0 17.215 Tf
-(BZ2_bzCompress) 144.606 Tj
-[1 0 0 1 264.468 282.711] cm
-0 g
-0 G
-[1 0 0 1 -192.468 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.906] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -271.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 271.014 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzCompress) 83.6892 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(bz_s) 23.9112 Tj
-1 TJm
-(tream) 29.889 Tj
--426 TJm
-(*strm,) 35.8668 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(action) 35.8668 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 255.472] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.548] cm
-0 g
-0 G
-[1 0 0 1 -72 -245.51] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 233.555 Td
-/F128_0 9.963 Tf
-(Pro) 13.8386 Tj
-15 TJm
-(vides) 21.0319 Tj
--222 TJm
-(mor) 16.0504 Tj
-1 TJm
-(e) 4.42357 Tj
--222 TJm
-(input) 20.4839 Tj
--222 TJm
-(and/or) 25.4555 Tj
--221 TJm
-(output) 25.4654 Tj
--222 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--222 TJm
-(space) 22.1278 Tj
--221 TJm
-(for) 11.6169 Tj
--222 TJm
-(the) 12.1748 Tj
--222 TJm
-(li) 5.53943 Tj
-1 TJm
-(brary) 21.0219 Tj
-65 TJm
-(.) 2.49075 Tj
--602 TJm
-(T) 6.08739 Tj
-1 TJm
-(he) 9.40507 Tj
--222 TJm
-(caller) 22.1278 Tj
--222 TJm
-(maintains) 38.7461 Tj
--221 TJm
-(input) 20.4839 Tj
--222 TJm
-(and) 14.3866 Tj
--222 TJm
-(ou) 9.963 Tj
-1 TJm
-(tput) 15.5024 Tj
--222 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fers,) 17.4253 Tj
--227 TJm
-(and) 14.3866 Tj
--222 TJm
-(calls) 18.2622 Tj
-[1 0 0 1 72 221.6] cm
-0 g
-0 G
-[1 0 0 1 -72 -221.6] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 221.6 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 155.686 221.6] cm
-0 g
-0 G
-[1 0 0 1 -155.686 -221.6] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.177 221.6 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(transfer) 30.427 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(between) 33.1967 Tj
--250 TJm
-(the) 12.1748 Tj
-1 TJm
-(m.) 10.242 Tj
-[1 0 0 1 72 220.036] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -210.074] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 199.683 Td
-/F128_0 9.963 Tf
-(Before) 27.1093 Tj
--212 TJm
-(each) 18.2522 Tj
--213 TJm
-(call) 14.3866 Tj
--212 TJm
-(to) 7.75121 Tj
-[1 0 0 1 147.961 199.683] cm
-0 g
-0 G
-[1 0 0 1 -147.961 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.961 199.683 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 231.647 199.683] cm
-0 g
-0 G
-[1 0 0 1 -231.647 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-231.647 199.683 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 236.329 199.683] cm
-0 g
-0 G
-[1 0 0 1 -236.329 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.329 199.683 Td
-/F130_0 9.963 Tf
-(next_in) 41.8446 Tj
-[1 0 0 1 278.172 199.683] cm
-0 g
-0 G
-[1 0 0 1 -278.172 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-280.289 199.683 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--212 TJm
-(point) 20.4839 Tj
--213 TJm
-(at) 7.19329 Tj
--212 TJm
-(the) 12.1748 Tj
--212 TJm
-(data) 16.5984 Tj
--213 TJm
-(to) 7.75121 Tj
--212 TJm
-(be) 9.40507 Tj
--212 TJm
-(compressed,) 49.5261 Tj
--220 TJm
-(and) 14.3866 Tj
-[1 0 0 1 463.493 199.683] cm
-0 g
-0 G
-[1 0 0 1 -463.493 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-463.493 199.683 Td
-/F130_0 9.963 Tf
-(avail_in) 47.8224 Tj
-[1 0 0 1 511.314 199.683] cm
-0 g
-0 G
-[1 0 0 1 -511.314 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-513.43 199.683 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
-72 187.728 Td
-(indicate) 31.5429 Tj
--246 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--246 TJm
-(man) 17.1563 Tj
-15 TJm
-(y) 4.9815 Tj
--246 TJm
-(bytes) 21.0319 Tj
--247 TJm
-(the) 12.1748 Tj
--246 TJm
-(library) 26.5614 Tj
--246 TJm
-(may) 17.1563 Tj
--246 TJm
-(read.) 19.6371 Tj
-[1 0 0 1 259.242 187.728] cm
-0 g
-0 G
-[1 0 0 1 -259.242 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.242 187.728 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 342.929 187.728] cm
-0 g
-0 G
-[1 0 0 1 -342.929 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-345.382 187.728 Td
-/F128_0 9.963 Tf
-(updates) 30.437 Tj
-[1 0 0 1 378.271 187.728] cm
-0 g
-0 G
-[1 0 0 1 -378.271 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-378.271 187.728 Td
-/F130_0 9.963 Tf
-(next_in) 41.8446 Tj
-[1 0 0 1 420.114 187.728] cm
-0 g
-0 G
-[1 0 0 1 -420.114 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-420.114 187.728 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 425.066 187.728] cm
-0 g
-0 G
-[1 0 0 1 -425.066 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.066 187.728 Td
-/F130_0 9.963 Tf
-(avail_in) 47.8224 Tj
-[1 0 0 1 472.886 187.728] cm
-0 g
-0 G
-[1 0 0 1 -472.886 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-475.34 187.728 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 492.179 187.728] cm
-0 g
-0 G
-[1 0 0 1 -492.179 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-492.179 187.728 Td
-/F130_0 9.963 Tf
-(total_in) 47.8224 Tj
-[1 0 0 1 540 187.728] cm
-0 g
-0 G
-[1 0 0 1 -540 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 175.773 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(re\003ect) 24.8975 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(number) 30.437 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(bytes) 21.0319 Tj
--249 TJm
-(it) 5.53943 Tj
--250 TJm
-(has) 13.2807 Tj
--250 TJm
-(read.) 19.6371 Tj
-[1 0 0 1 72 173.616] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -163.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 153.856 Td
-/F128_0 9.963 Tf
-(Similarly) 37.0922 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 113.148 153.856] cm
-0 g
-0 G
-[1 0 0 1 -113.148 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.148 153.856 Td
-/F130_0 9.963 Tf
-(next_out) 47.8224 Tj
-[1 0 0 1 160.968 153.856] cm
-0 g
-0 G
-[1 0 0 1 -160.968 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-163.114 153.856 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--215 TJm
-(point) 20.4839 Tj
--215 TJm
-(to) 7.75121 Tj
--216 TJm
-(a) 4.42357 Tj
--215 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--215 TJm
-(in) 7.75121 Tj
--216 TJm
-(whi) 14.9445 Tj
-1 TJm
-(ch) 9.40507 Tj
--216 TJm
-(the) 12.1748 Tj
--215 TJm
-(compressed) 47.0353 Tj
--215 TJm
-(data) 16.5984 Tj
--215 TJm
-(is) 6.64532 Tj
--216 TJm
-(to) 7.75121 Tj
--215 TJm
-(be) 9.40507 Tj
--215 TJm
-(placed,) 28.4942 Tj
--222 TJm
-(with) 17.7142 Tj
-[1 0 0 1 456.391 153.856] cm
-0 g
-0 G
-[1 0 0 1 -456.391 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-456.391 153.856 Td
-/F130_0 9.963 Tf
-(avail_out) 53.8002 Tj
-[1 0 0 1 510.189 153.856] cm
-0 g
-0 G
-[1 0 0 1 -510.189 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-512.334 153.856 Td
-/F128_0 9.963 Tf
-(indica-) 27.6673 Tj
-72 141.901 Td
-(ting) 15.5024 Tj
--280 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--281 TJm
-(muc) 17.1563 Tj
-1 TJm
-(h) 4.9815 Tj
--281 TJm
-(output) 25.4654 Tj
--280 TJm
-(space) 22.1278 Tj
--280 TJm
-(is) 6.64532 Tj
--281 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailabl) 22.1378 Tj
-1 TJm
-(e.) 6.91432 Tj
-[1 0 0 1 239.543 141.901] cm
-0 g
-0 G
-[1 0 0 1 -239.543 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-239.543 141.901 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 323.229 141.901] cm
-0 g
-0 G
-[1 0 0 1 -323.229 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-326.022 141.901 Td
-/F128_0 9.963 Tf
-(updates) 30.437 Tj
-[1 0 0 1 359.251 141.901] cm
-0 g
-0 G
-[1 0 0 1 -359.251 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-359.251 141.901 Td
-/F130_0 9.963 Tf
-(next_out) 47.8224 Tj
-[1 0 0 1 407.072 141.901] cm
-0 g
-0 G
-[1 0 0 1 -407.072 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-407.072 141.901 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 412.431 141.901] cm
-0 g
-0 G
-[1 0 0 1 -412.431 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-412.431 141.901 Td
-/F130_0 9.963 Tf
-(avail_out) 53.8002 Tj
-[1 0 0 1 466.229 141.901] cm
-0 g
-0 G
-[1 0 0 1 -466.229 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-469.023 141.901 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 486.202 141.901] cm
-0 g
-0 G
-[1 0 0 1 -486.202 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 141.901 Td
-/F130_0 9.963 Tf
-(total_out) 53.8002 Tj
-[1 0 0 1 540 141.901] cm
-0 g
-0 G
-[1 0 0 1 -540 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 129.946 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(re\003ect) 24.8975 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(number) 30.437 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(bytes) 21.0319 Tj
--249 TJm
-(output.) 27.9562 Tj
-[1 0 0 1 72 127.789] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -117.827] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 108.029 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--272 TJm
-(may) 17.1563 Tj
--272 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vide) 17.1563 Tj
--272 TJm
-(and) 14.3866 Tj
--271 TJm
-(remo) 20.474 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--272 TJm
-(as) 8.29918 Tj
--272 TJm
-(little) 18.2721 Tj
--272 TJm
-(or) 8.29918 Tj
--272 TJm
-(as) 8.29918 Tj
--272 TJm
-(much) 22.1378 Tj
--272 TJm
-(data) 16.5984 Tj
--272 TJm
-(as) 8.29918 Tj
--271 TJm
-(you) 14.9445 Tj
--272 TJm
-(lik) 10.5209 Tj
-10 TJm
-(e) 4.42357 Tj
--272 TJm
-(on) 9.963 Tj
--272 TJm
-(each) 18.2522 Tj
--272 TJm
-(call) 14.3866 Tj
--272 TJm
-(of) 8.29918 Tj
-[1 0 0 1 399.123 108.029] cm
-0 g
-0 G
-[1 0 0 1 -399.123 -108.029] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-399.123 108.029 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 482.809 108.029] cm
-0 g
-0 G
-[1 0 0 1 -482.809 -108.029] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.809 108.029 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--752 TJm
-(In) 8.29918 Tj
--272 TJm
-(the) 12.1748 Tj
--271 TJm
-(limit,) 21.3208 Tj
-72 96.074 Td
-(it) 5.53943 Tj
--266 TJm
-(is) 6.64532 Tj
--265 TJm
-(acceptable) 42.0439 Tj
--266 TJm
-(to) 7.75121 Tj
--266 TJm
-(su) 8.85711 Tj
-1 TJm
-(pply) 17.7142 Tj
--266 TJm
-(and) 14.3866 Tj
--266 TJm
-(remo) 20.474 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--265 TJm
-(data) 16.5984 Tj
--266 TJm
-(one) 14.3866 Tj
--266 TJm
-(byte) 17.1563 Tj
--265 TJm
-(at) 7.19329 Tj
--266 TJm
-(a) 4.42357 Tj
--266 TJm
-(time,) 20.205 Tj
--269 TJm
-(although) 34.8705 Tj
--266 TJm
-(this) 14.3965 Tj
--265 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--266 TJm
-(be) 9.40507 Tj
--266 TJm
-(terribly) 29.3311 Tj
--265 TJm
-(inef) 15.4925 Tj
-25 TJm
-(\002cient.) 27.3983 Tj
--714 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--266 TJm
-(should) 26.5713 Tj
-72 84.118 Td
-(al) 7.19329 Tj
-10 TJm
-(w) 7.19329 Tj
-10 TJm
-(ays) 13.2807 Tj
--250 TJm
-(ensure) 26.0034 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(at) 7.19329 Tj
--250 TJm
-(least) 18.2622 Tj
--249 TJm
-(one) 14.3866 Tj
--250 TJm
-(byte) 17.1563 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(output) 25.4654 Tj
--250 TJm
-(space) 22.1278 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailable) 26.5614 Tj
--250 TJm
-(at) 7.19329 Tj
--250 TJm
-(each) 18.2522 Tj
--250 TJm
-(call.) 16.8773 Tj
-[1 0 0 1 72 81.962] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 0 -21.148] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(13) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 17 17
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(A) 7.19329 Tj
--250 TJm
-(second) 27.6673 Tj
--250 TJm
-(purpose) 31.5429 Tj
--250 TJm
-(of) 8.29918 Tj
-[1 0 0 1 156.662 710.037] cm
-0 g
-0 G
-[1 0 0 1 -156.662 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-156.662 710.037 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 240.348 710.037] cm
-0 g
-0 G
-[1 0 0 1 -240.348 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-242.839 710.037 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(request) 28.7731 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(change) 28.2152 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(mod) 17.7142 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 72 707.881] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -697.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 688.12 Td
-/F128_0 9.963 Tf
-(Conceptually) 53.1327 Tj
-65 TJm
-(,) 2.49075 Tj
--217 TJm
-(a) 4.42357 Tj
--209 TJm
-(compressed) 47.0353 Tj
--209 TJm
-(stream) 26.5614 Tj
--210 TJm
-(can) 13.8286 Tj
--209 TJm
-(be) 9.40507 Tj
--209 TJm
-(in) 7.75121 Tj
--209 TJm
-(one) 14.3866 Tj
--209 TJm
-(of) 8.29918 Tj
--210 TJm
-(four) 16.5984 Tj
--209 TJm
-(states:) 24.9075 Tj
--289 TJm
-(IDLE,) 25.1765 Tj
--209 TJm
-(R) 6.64532 Tj
-40 TJm
-(UNNING,) 41.7749 Tj
--209 TJm
-(FLUSHING) 49.2571 Tj
--209 TJm
-(and) 14.3866 Tj
--210 TJm
-(FINISHING) 49.805 Tj
-1 TJm
-(.) 2.49075 Tj
--419 TJm
-(Be-) 14.3866 Tj
-72 676.164 Td
-(fore) 16.0404 Tj
--264 TJm
-(initialis) 29.899 Tj
-1 TJm
-(ation) 19.926 Tj
--264 TJm
-(\() 3.31768 Tj
-[1 0 0 1 146.434 676.164] cm
-0 g
-0 G
-[1 0 0 1 -146.434 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.434 676.164 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 254.031 676.164] cm
-0 g
-0 G
-[1 0 0 1 -254.031 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-254.031 676.164 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--264 TJm
-(and) 14.3866 Tj
--263 TJm
-(after) 18.2522 Tj
--264 TJm
-(termination) 45.9394 Tj
--264 TJm
-(\() 3.31768 Tj
-[1 0 0 1 349.75 676.164] cm
-0 g
-0 G
-[1 0 0 1 -349.75 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-349.75 676.164 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressEnd) 101.623 Tj
-[1 0 0 1 451.369 676.164] cm
-0 g
-0 G
-[1 0 0 1 -451.369 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-451.369 676.164 Td
-/F128_0 9.963 Tf
-(\),) 5.80843 Tj
--267 TJm
-(a) 4.42357 Tj
--264 TJm
-(stream) 26.5614 Tj
--263 TJm
-(is) 6.64532 Tj
--264 TJm
-(re) 7.74125 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(arded) 22.1278 Tj
-72 664.209 Td
-(as) 8.29918 Tj
--250 TJm
-(IDLE.) 25.1765 Tj
-[1 0 0 1 72 664.11] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -654.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 642.291 Td
-/F128_0 9.963 Tf
-(Upon) 22.1378 Tj
--389 TJm
-(initialisation) 49.825 Tj
--389 TJm
-(\() 3.31768 Tj
-[1 0 0 1 155.036 642.291] cm
-0 g
-0 G
-[1 0 0 1 -155.036 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.036 642.291 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 262.632 642.291] cm
-0 g
-0 G
-[1 0 0 1 -262.632 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-262.632 642.291 Td
-/F128_0 9.963 Tf
-(\),) 5.80843 Tj
--424 TJm
-(the) 12.1748 Tj
--390 TJm
-(stream) 26.5614 Tj
--389 TJm
-(is) 6.64532 Tj
--389 TJm
-(placed) 26.0034 Tj
--390 TJm
-(in) 7.75121 Tj
--389 TJm
-(the) 12.1748 Tj
--389 TJm
-(R) 6.64532 Tj
-40 TJm
-(UNNING) 39.2841 Tj
--389 TJm
-(state.) 20.7529 Tj
--1457 TJm
-(Subsequent) 45.9394 Tj
--389 TJm
-(calls) 18.2622 Tj
-72 630.336 Td
-(to) 7.75121 Tj
-[1 0 0 1 83.818 630.336] cm
-0 g
-0 G
-[1 0 0 1 -83.818 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.818 630.336 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 167.504 630.336] cm
-0 g
-0 G
-[1 0 0 1 -167.504 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.571 630.336 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--408 TJm
-(pass) 17.1563 Tj
-[1 0 0 1 223.431 630.336] cm
-0 g
-0 G
-[1 0 0 1 -223.431 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-223.431 630.336 Td
-/F130_0 9.963 Tf
-(BZ_RUN) 35.8668 Tj
-[1 0 0 1 259.297 630.336] cm
-0 g
-0 G
-[1 0 0 1 -259.297 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.362 630.336 Td
-/F128_0 9.963 Tf
-(as) 8.29918 Tj
--408 TJm
-(the) 12.1748 Tj
--408 TJm
-(requested) 38.1782 Tj
--408 TJm
-(action;) 27.1193 Tj
--488 TJm
-(other) 20.474 Tj
--408 TJm
-(actions) 28.2252 Tj
--408 TJm
-(are) 12.1648 Tj
--408 TJm
-(ille) 12.7327 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(al) 7.19329 Tj
--408 TJm
-(and) 14.3866 Tj
--408 TJm
-(will) 15.5024 Tj
--409 TJm
-(re) 7.74125 Tj
-1 TJm
-(sult) 14.3965 Tj
--409 TJm
-(in) 7.75121 Tj
-[1 0 0 1 72 618.381] cm
-0 g
-0 G
-[1 0 0 1 -72 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 618.381 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-[1 0 0 1 173.619 618.381] cm
-0 g
-0 G
-[1 0 0 1 -173.619 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.619 618.381 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 616.961] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -606.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 596.463 Td
-/F128_0 9.963 Tf
-(At) 9.963 Tj
--279 TJm
-(some) 21.0319 Tj
--279 TJm
-(point,) 22.9747 Tj
--286 TJm
-(the) 12.1748 Tj
--279 TJm
-(call) 14.3866 Tj
-1 TJm
-(ing) 12.7327 Tj
--279 TJm
-(program) 33.7546 Tj
--279 TJm
-(will) 15.5024 Tj
--279 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--279 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vided) 22.1378 Tj
--279 TJm
-(all) 9.963 Tj
--278 TJm
-(the) 12.1748 Tj
--279 TJm
-(input) 20.4839 Tj
--279 TJm
-(data) 16.5984 Tj
--279 TJm
-(it) 5.53943 Tj
--279 TJm
-(w) 7.19329 Tj
-10 TJm
-(ants) 16.0504 Tj
--279 TJm
-(to.) 10.242 Tj
--793 TJm
-(It) 6.08739 Tj
--279 TJm
-(will) 15.5024 Tj
--279 TJm
-(then) 17.1563 Tj
--279 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--278 TJm
-(to) 7.75121 Tj
--279 TJm
-(\002nish) 22.1477 Tj
--279 TJm
-(up) 9.963 Tj
--279 TJm
-(--) 6.63536 Tj
-72 584.508 Td
-(in) 7.75121 Tj
--287 TJm
-(ef) 7.74125 Tj
-25 TJm
-(fect,) 17.4253 Tj
--297 TJm
-(asking) 26.0134 Tj
--287 TJm
-(the) 12.1748 Tj
--288 TJm
-(library) 26.5614 Tj
--287 TJm
-(to) 7.75121 Tj
--287 TJm
-(process) 29.879 Tj
--288 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--287 TJm
-(data) 16.5984 Tj
--287 TJm
-(it) 5.53943 Tj
--288 TJm
-(might) 23.2536 Tj
--287 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--287 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fered) 20.464 Tj
--288 TJm
-(inte) 14.9445 Tj
-1 TJm
-(rnally) 23.2437 Tj
-65 TJm
-(.) 2.49075 Tj
--845 TJm
-(In) 8.29918 Tj
--287 TJm
-(this) 14.3965 Tj
--288 TJm
-(sta) 11.0689 Tj
-1 TJm
-(te,) 9.68404 Tj
-[1 0 0 1 456.314 584.508] cm
-0 g
-0 G
-[1 0 0 1 -456.314 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-456.314 584.508 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 540 584.508] cm
-0 g
-0 G
-[1 0 0 1 -540 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 572.553 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--258 TJm
-(no) 9.963 Tj
--257 TJm
-(longer) 25.4555 Tj
--258 TJm
-(attempt) 29.889 Tj
--257 TJm
-(to) 7.75121 Tj
--258 TJm
-(read) 17.1463 Tj
--258 TJm
-(data) 16.5984 Tj
--257 TJm
-(from) 19.3681 Tj
-[1 0 0 1 234.207 572.553] cm
-0 g
-0 G
-[1 0 0 1 -234.207 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.207 572.553 Td
-/F130_0 9.963 Tf
-(next_in) 41.8446 Tj
-[1 0 0 1 276.051 572.553] cm
-0 g
-0 G
-[1 0 0 1 -276.051 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-276.051 572.553 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--260 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--257 TJm
-(it) 5.53943 Tj
--258 TJm
-(will) 15.5024 Tj
--258 TJm
-(w) 7.19329 Tj
-10 TJm
-(an) 9.40507 Tj
-1 TJm
-(t) 2.76971 Tj
--258 TJm
-(to) 7.75121 Tj
--258 TJm
-(write) 20.474 Tj
--257 TJm
-(data) 16.5984 Tj
--258 TJm
-(to) 7.75121 Tj
-[1 0 0 1 407.082 572.553] cm
-0 g
-0 G
-[1 0 0 1 -407.082 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-407.082 572.553 Td
-/F130_0 9.963 Tf
-(next_out) 47.8224 Tj
-[1 0 0 1 454.902 572.553] cm
-0 g
-0 G
-[1 0 0 1 -454.902 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-454.902 572.553 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--666 TJm
-(Because) 33.1967 Tj
--258 TJm
-(the) 12.1748 Tj
--258 TJm
-(ou) 9.963 Tj
-1 TJm
-(tput) 15.5024 Tj
-72 560.598 Td
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--228 TJm
-(supplied) 33.7646 Tj
--228 TJm
-(by) 9.963 Tj
--228 TJm
-(the) 12.1748 Tj
--228 TJm
-(user) 16.5984 Tj
--229 TJm
-(can) 13.8286 Tj
--228 TJm
-(be) 9.40507 Tj
--228 TJm
-(arbitrarily) 39.842 Tj
--228 TJm
-(small,) 24.0806 Tj
--232 TJm
-(the) 12.1748 Tj
--228 TJm
-(\002nishing-up) 48.1611 Tj
--228 TJm
-(operation) 37.6303 Tj
--228 TJm
-(cannot) 26.5614 Tj
--229 TJm
-(n) 4.9815 Tj
-1 TJm
-(ecessarily) 39.2841 Tj
--228 TJm
-(be) 9.40507 Tj
--229 TJm
-(done) 19.3681 Tj
--228 TJm
-(with) 17.7142 Tj
--228 TJm
-(a) 4.42357 Tj
--228 TJm
-(single) 23.8016 Tj
-72 548.643 Td
-(call) 14.3866 Tj
--250 TJm
-(of) 8.29918 Tj
-[1 0 0 1 99.666 548.643] cm
-0 g
-0 G
-[1 0 0 1 -99.666 -548.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-99.666 548.643 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 183.352 548.643] cm
-0 g
-0 G
-[1 0 0 1 -183.352 -548.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.352 548.643 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 547.079] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -537.116] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 526.725 Td
-/F128_0 9.963 Tf
-(Instead,) 31.2639 Tj
--346 TJm
-(the) 12.1748 Tj
--327 TJm
-(ca) 8.84714 Tj
-1 TJm
-(lling) 18.2721 Tj
--327 TJm
-(program) 33.7546 Tj
--327 TJm
-(passes) 25.4555 Tj
-[1 0 0 1 218.231 526.725] cm
-0 g
-0 G
-[1 0 0 1 -218.231 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-218.231 526.725 Td
-/F130_0 9.963 Tf
-(BZ_FINISH) 53.8002 Tj
-[1 0 0 1 272.029 526.725] cm
-0 g
-0 G
-[1 0 0 1 -272.029 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.284 526.725 Td
-/F128_0 9.963 Tf
-(as) 8.29918 Tj
--327 TJm
-(an) 9.40507 Tj
--326 TJm
-(action) 24.3496 Tj
--327 TJm
-(to) 7.75121 Tj
-[1 0 0 1 338.109 526.725] cm
-0 g
-0 G
-[1 0 0 1 -338.109 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-338.109 526.725 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 421.795 526.725] cm
-0 g
-0 G
-[1 0 0 1 -421.795 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-421.795 526.725 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1081 TJm
-(This) 17.7142 Tj
--326 TJm
-(changes) 32.0908 Tj
--327 TJm
-(the) 12.1748 Tj
--327 TJm
-(strea) 18.8101 Tj
-1 TJm
-(m') 11.0689 Tj
-55 TJm
-(s) 3.87561 Tj
-72 514.77 Td
-(state) 18.2622 Tj
--290 TJm
-(to) 7.75121 Tj
--291 TJm
-(FINISHING.) 52.2958 Tj
--581 TJm
-(An) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--290 TJm
-(remaining) 40.4 Tj
--291 TJm
-(input) 20.4839 Tj
--290 TJm
-(\(ie,) 13.0017 Tj
-[1 0 0 1 264.452 514.77] cm
-0 g
-0 G
-[1 0 0 1 -264.452 -514.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.452 514.77 Td
-/F130_0 9.963 Tf
-(next_in[0) 53.8002 Tj
--600 TJm
-(..) 11.9556 Tj
--1200 TJm
-(avail_in-1]) 65.7558 Tj
-[1 0 0 1 413.892 514.77] cm
-0 g
-0 G
-[1 0 0 1 -413.892 -514.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-413.892 514.77 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--291 TJm
-(is) 6.64532 Tj
--290 TJm
-(compressed) 47.0353 Tj
--290 TJm
-(and) 14.3866 Tj
--291 TJm
-(transferred) 43.1498 Tj
-72 502.814 Td
-(to) 7.75121 Tj
--421 TJm
-(the) 12.1748 Tj
--421 TJm
-(output) 25.4654 Tj
--421 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-55 TJm
-(.) 2.49075 Tj
--1646 TJm
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--421 TJm
-(do) 9.963 Tj
--421 TJm
-(this,) 16.8873 Tj
-[1 0 0 1 222.339 502.814] cm
-0 g
-0 G
-[1 0 0 1 -222.339 -502.814] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-222.339 502.814 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 306.025 502.814] cm
-0 g
-0 G
-[1 0 0 1 -306.025 -502.814] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.22 502.814 Td
-/F128_0 9.963 Tf
-(must) 19.378 Tj
--421 TJm
-(be) 9.40507 Tj
--421 TJm
-(called) 23.7916 Tj
--421 TJm
-(repeatedly) 41.4959 Tj
--421 TJm
-(until) 18.2721 Tj
--421 TJm
-(all) 9.963 Tj
--421 TJm
-(the) 12.1748 Tj
--421 TJm
-(outp) 17.7142 Tj
-1 TJm
-(ut) 7.75121 Tj
--421 TJm
-(has) 13.2807 Tj
--421 TJm
-(been) 18.8101 Tj
-72 490.859 Td
-(consumed.) 42.8907 Tj
--1396 TJm
-(At) 9.963 Tj
--380 TJm
-(that) 14.9445 Tj
--379 TJm
-(point,) 22.9747 Tj
-[1 0 0 1 188.346 490.859] cm
-0 g
-0 G
-[1 0 0 1 -188.346 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.346 490.859 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 272.033 490.859] cm
-0 g
-0 G
-[1 0 0 1 -272.033 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.813 490.859 Td
-/F128_0 9.963 Tf
-(returns) 27.6673 Tj
-[1 0 0 1 307.259 490.859] cm
-0 g
-0 G
-[1 0 0 1 -307.259 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-307.259 490.859 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 384.968 490.859] cm
-0 g
-0 G
-[1 0 0 1 -384.968 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.968 490.859 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--379 TJm
-(and) 14.3866 Tj
--380 TJm
-(the) 12.1748 Tj
--379 TJm
-(stream') 29.879 Tj
-55 TJm
-(s) 3.87561 Tj
--379 TJm
-(state) 18.2622 Tj
--380 TJm
-(is) 6.64532 Tj
--379 TJm
-(set) 11.0689 Tj
--379 TJm
-(back) 18.8101 Tj
--380 TJm
-(to) 7.75121 Tj
-72 478.904 Td
-(IDLE.) 25.1765 Tj
-[1 0 0 1 99.666 478.904] cm
-0 g
-0 G
-[1 0 0 1 -99.666 -478.904] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-99.666 478.904 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressEnd) 101.623 Tj
-[1 0 0 1 201.285 478.904] cm
-0 g
-0 G
-[1 0 0 1 -201.285 -478.904] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.776 478.904 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--250 TJm
-(then) 17.1563 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(called.) 26.2824 Tj
-[1 0 0 1 72 477.34] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -467.377] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 456.986 Td
-/F128_0 9.963 Tf
-(Just) 15.5024 Tj
--380 TJm
-(to) 7.75121 Tj
--379 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--380 TJm
-(sure) 16.5984 Tj
--380 TJm
-(the) 12.1748 Tj
--380 TJm
-(c) 4.42357 Tj
-1 TJm
-(alling) 22.6957 Tj
--380 TJm
-(program) 33.7546 Tj
--380 TJm
-(does) 18.2622 Tj
--379 TJm
-(not) 12.7327 Tj
--380 TJm
-(cheat,) 23.5127 Tj
--412 TJm
-(the) 12.1748 Tj
--380 TJm
-(library) 26.5614 Tj
--380 TJm
-(mak) 17.1563 Tj
-10 TJm
-(es) 8.29918 Tj
--379 TJm
-(a) 4.42357 Tj
--380 TJm
-(note) 17.1563 Tj
--380 TJm
-(of) 8.29918 Tj
-[1 0 0 1 415.708 456.986] cm
-0 g
-0 G
-[1 0 0 1 -415.708 -456.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-415.708 456.986 Td
-/F130_0 9.963 Tf
-(avail_in) 47.8224 Tj
-[1 0 0 1 463.528 456.986] cm
-0 g
-0 G
-[1 0 0 1 -463.528 -456.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-467.312 456.986 Td
-/F128_0 9.963 Tf
-(at) 7.19329 Tj
--380 TJm
-(the) 12.1748 Tj
--379 TJm
-(time) 17.7142 Tj
--380 TJm
-(of) 8.29918 Tj
--380 TJm
-(the) 12.1748 Tj
-72 445.031 Td
-(\002rst) 15.5024 Tj
--286 TJm
-(call) 14.3866 Tj
--285 TJm
-(to) 7.75121 Tj
-[1 0 0 1 118.179 445.031] cm
-0 g
-0 G
-[1 0 0 1 -118.179 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.179 445.031 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 201.866 445.031] cm
-0 g
-0 G
-[1 0 0 1 -201.866 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.713 445.031 Td
-/F128_0 9.963 Tf
-(which) 24.3496 Tj
--286 TJm
-(has) 13.2807 Tj
-[1 0 0 1 248.035 445.031] cm
-0 g
-0 G
-[1 0 0 1 -248.035 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.035 445.031 Td
-/F130_0 9.963 Tf
-(BZ_FINISH) 53.8002 Tj
-[1 0 0 1 301.834 445.031] cm
-0 g
-0 G
-[1 0 0 1 -301.834 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-304.68 445.031 Td
-/F128_0 9.963 Tf
-(as) 8.29918 Tj
--286 TJm
-(an) 9.40507 Tj
--285 TJm
-(action) 24.3496 Tj
--286 TJm
-(\(ie,) 13.0017 Tj
--295 TJm
-(at) 7.19329 Tj
--285 TJm
-(the) 12.1748 Tj
--286 TJm
-(time) 17.7142 Tj
--286 TJm
-(the) 12.1748 Tj
--286 TJm
-(progr) 21.5799 Tj
-1 TJm
-(am) 12.1748 Tj
--286 TJm
-(has) 13.2807 Tj
--286 TJm
-(announced) 43.1597 Tj
--286 TJm
-(i) 2.76971 Tj
-1 TJm
-(ts) 6.64532 Tj
-72 433.076 Td
-(intention) 35.4284 Tj
--292 TJm
-(to) 7.75121 Tj
--291 TJm
-(not) 12.7327 Tj
--292 TJm
-(supply) 26.5713 Tj
--292 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--291 TJm
-(more) 20.474 Tj
--292 TJm
-(input\).) 26.2924 Tj
--871 TJm
-(By) 11.6268 Tj
--291 TJm
-(comparing) 42.6118 Tj
--292 TJm
-(this) 14.3965 Tj
--292 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--291 TJm
-(with) 17.7142 Tj
--292 TJm
-(that) 14.9445 Tj
--292 TJm
-(of) 8.29918 Tj
-[1 0 0 1 392.861 433.076] cm
-0 g
-0 G
-[1 0 0 1 -392.861 -433.076] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.861 433.076 Td
-/F130_0 9.963 Tf
-(avail_in) 47.8224 Tj
-[1 0 0 1 440.682 433.076] cm
-0 g
-0 G
-[1 0 0 1 -440.682 -433.076] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-443.589 433.076 Td
-/F128_0 9.963 Tf
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--292 TJm
-(subsequent) 44.2756 Tj
--291 TJm
-(calls) 18.2622 Tj
--292 TJm
-(to) 7.75121 Tj
-[1 0 0 1 72 421.121] cm
-0 g
-0 G
-[1 0 0 1 -72 -421.121] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 421.121 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 155.686 421.121] cm
-0 g
-0 G
-[1 0 0 1 -155.686 -421.121] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.686 421.121 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--247 TJm
-(the) 12.1748 Tj
--247 TJm
-(libra) 18.2622 Tj
-1 TJm
-(ry) 8.29918 Tj
--247 TJm
-(can) 13.8286 Tj
--246 TJm
-(detect) 23.7916 Tj
--247 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--246 TJm
-(attempts) 33.7646 Tj
--246 TJm
-(to) 7.75121 Tj
--247 TJm
-(slip) 14.3965 Tj
--246 TJm
-(in) 7.75121 Tj
--247 TJm
-(more) 20.474 Tj
--246 TJm
-(data) 16.5984 Tj
--246 TJm
-(to) 7.75121 Tj
--247 TJm
-(compress.) 40.121 Tj
--617 TJm
-(An) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--247 TJm
-(calls) 18.2622 Tj
--246 TJm
-(for) 11.6169 Tj
--246 TJm
-(which) 24.3496 Tj
--247 TJm
-(this) 14.3965 Tj
--246 TJm
-(is) 6.64532 Tj
-72 409.166 Td
-(detected) 33.1967 Tj
--250 TJm
-(will) 15.5024 Tj
--250 TJm
-(return) 23.7916 Tj
-[1 0 0 1 151.959 409.166] cm
-0 g
-0 G
-[1 0 0 1 -151.959 -409.166] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-151.959 409.166 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-[1 0 0 1 253.578 409.166] cm
-0 g
-0 G
-[1 0 0 1 -253.578 -409.166] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.578 409.166 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--500 TJm
-(This) 17.7142 Tj
--250 TJm
-(indicates) 35.4185 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(programm) 41.5059 Tj
-1 TJm
-(ing) 12.7327 Tj
--250 TJm
-(mistak) 26.5713 Tj
-10 TJm
-(e) 4.42357 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(corrected.) 39.5531 Tj
-[1 0 0 1 72 407.009] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -397.046] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 387.248 Td
-/F128_0 9.963 Tf
-(Instead) 28.7731 Tj
--223 TJm
-(of) 8.29918 Tj
--224 TJm
-(asking) 26.0134 Tj
--224 TJm
-(to) 7.75121 Tj
--223 TJm
-(\002nish,) 24.6385 Tj
--229 TJm
-(the) 12.1748 Tj
--223 TJm
-(calling) 27.1193 Tj
--224 TJm
-(program) 33.7546 Tj
--223 TJm
-(may) 17.1563 Tj
--224 TJm
-(ask) 13.2807 Tj
-[1 0 0 1 293.282 387.248] cm
-0 g
-0 G
-[1 0 0 1 -293.282 -387.248] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.282 387.248 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 376.968 387.248] cm
-0 g
-0 G
-[1 0 0 1 -376.968 -387.248] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-379.196 387.248 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--224 TJm
-(ta) 7.19329 Tj
-1 TJm
-(k) 4.9815 Tj
-10 TJm
-(e) 4.42357 Tj
--224 TJm
-(all) 9.963 Tj
--224 TJm
-(the) 12.1748 Tj
--223 TJm
-(remaining) 40.4 Tj
--224 TJm
-(inp) 12.7327 Tj
-1 TJm
-(ut,) 10.242 Tj
--229 TJm
-(compress) 37.6303 Tj
-72 375.293 Td
-(it) 5.53943 Tj
--278 TJm
-(and) 14.3866 Tj
--278 TJm
-(terminate) 37.6303 Tj
--277 TJm
-(the) 12.1748 Tj
--278 TJm
-(current) 28.2152 Tj
--278 TJm
-(\(Burro) 26.5614 Tj
-25 TJm
-(ws-Wheeler\)) 51.4489 Tj
--278 TJm
-(co) 9.40507 Tj
-1 TJm
-(mpression) 40.9579 Tj
--278 TJm
-(block.) 24.6285 Tj
--787 TJm
-(This) 17.7142 Tj
--278 TJm
-(could) 22.1378 Tj
--278 TJm
-(be) 9.40507 Tj
--278 TJm
-(useful) 24.3496 Tj
--278 TJm
-(for) 11.6169 Tj
--278 TJm
-(e) 4.42357 Tj
-1 TJm
-(rror) 14.9345 Tj
--278 TJm
-(control) 28.2252 Tj
--278 TJm
-(purposes.) 37.9092 Tj
-72 363.337 Td
-(The) 15.4925 Tj
--328 TJm
-(mechanism) 45.3815 Tj
--328 TJm
-(is) 6.64532 Tj
--328 TJm
-(analogous) 40.4 Tj
--328 TJm
-(to) 7.75121 Tj
--328 TJm
-(that) 14.9445 Tj
--328 TJm
-(for) 11.6169 Tj
--328 TJm
-(\002nishing) 34.8805 Tj
-1 TJm
-(:) 2.76971 Tj
--467 TJm
-(cal) 11.6169 Tj
-1 TJm
-(l) 2.76971 Tj
-[1 0 0 1 297.049 363.337] cm
-0 g
-0 G
-[1 0 0 1 -297.049 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.049 363.337 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 380.735 363.337] cm
-0 g
-0 G
-[1 0 0 1 -380.735 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.003 363.337 Td
-/F128_0 9.963 Tf
-(with) 17.7142 Tj
--328 TJm
-(an) 9.40507 Tj
--328 TJm
-(action) 24.3496 Tj
--328 TJm
-(of) 8.29918 Tj
-[1 0 0 1 456.841 363.337] cm
-0 g
-0 G
-[1 0 0 1 -456.841 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-456.841 363.337 Td
-/F130_0 9.963 Tf
-(BZ_FLUSH) 47.8224 Tj
-[1 0 0 1 504.662 363.337] cm
-0 g
-0 G
-[1 0 0 1 -504.662 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-504.662 363.337 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--328 TJm
-(remo) 20.474 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-72 351.382 Td
-(output) 25.4654 Tj
--445 TJm
-(data,) 19.0891 Tj
--494 TJm
-(and) 14.3866 Tj
--445 TJm
-(persist) 26.0134 Tj
--445 TJm
-(with) 17.7142 Tj
--446 TJm
-(the) 12.1748 Tj
-[1 0 0 1 213.94 351.382] cm
-0 g
-0 G
-[1 0 0 1 -213.94 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.94 351.382 Td
-/F130_0 9.963 Tf
-(BZ_FLUSH) 47.8224 Tj
-[1 0 0 1 261.761 351.382] cm
-0 g
-0 G
-[1 0 0 1 -261.761 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.195 351.382 Td
-/F128_0 9.963 Tf
-(action) 24.3496 Tj
--445 TJm
-(until) 18.2721 Tj
--445 TJm
-(the) 12.1748 Tj
--445 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
-[1 0 0 1 360.062 351.382] cm
-0 g
-0 G
-[1 0 0 1 -360.062 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.062 351.382 Td
-/F130_0 9.963 Tf
-(BZ_RUN) 35.8668 Tj
-[1 0 0 1 395.928 351.382] cm
-0 g
-0 G
-[1 0 0 1 -395.928 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-400.362 351.382 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--445 TJm
-(returned.) 35.6875 Tj
--1792 TJm
-(A) 7.19329 Tj
-1 TJm
-(s) 3.87561 Tj
--446 TJm
-(with) 17.7142 Tj
--445 TJm
-(\002nishing,) 37.3712 Tj
-[1 0 0 1 72 339.427] cm
-0 g
-0 G
-[1 0 0 1 -72 -339.427] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 339.427 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 155.686 339.427] cm
-0 g
-0 G
-[1 0 0 1 -155.686 -339.427] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.177 339.427 Td
-/F128_0 9.963 Tf
-(detects) 27.6673 Tj
--250 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--250 TJm
-(attempt) 29.889 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vi) 7.75121 Tj
-1 TJm
-(de) 9.40507 Tj
--250 TJm
-(more) 20.474 Tj
--250 TJm
-(input) 20.4839 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(once) 18.8101 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\003ush) 19.378 Tj
--250 TJm
-(has) 13.2807 Tj
--250 TJm
-(be) 9.40507 Tj
-15 TJm
-(gun.) 17.4353 Tj
-[1 0 0 1 72 337.27] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -327.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 317.509 Td
-/F128_0 9.963 Tf
-(Once) 21.0219 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\003ush) 19.378 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(complete,) 39.0151 Tj
--250 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--250 TJm
-(stream) 26.5614 Tj
--250 TJm
-(returns) 27.6673 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(normal) 28.2252 Tj
--250 TJm
-(R) 6.64532 Tj
-40 TJm
-(UNNING) 39.2841 Tj
--250 TJm
-(state.) 20.7529 Tj
-[1 0 0 1 72 315.353] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -305.39] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 295.592 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--344 TJm
-(all) 9.963 Tj
--343 TJm
-(sounds) 27.6772 Tj
--344 TJm
-(pretty) 23.2437 Tj
--344 TJm
-(comple) 29.3311 Tj
-15 TJm
-(x) 4.9815 Tj
-1 TJm
-(,) 2.49075 Tj
--368 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--343 TJm
-(isn') 14.9445 Tj
-18 TJm
-(t) 2.76971 Tj
--344 TJm
-(really) 22.6858 Tj
-65 TJm
-(.) 2.49075 Tj
--1182 TJm
-(Here') 22.6758 Tj
-55 TJm
-(s) 3.87561 Tj
--344 TJm
-(a) 4.42357 Tj
--344 TJm
-(table) 19.3681 Tj
--343 TJm
-(which) 24.3496 Tj
--344 TJm
-(sho) 13.8386 Tj
-25 TJm
-(ws) 11.0689 Tj
--344 TJm
-(which) 24.3496 Tj
--343 TJm
-(actions) 28.2252 Tj
--344 TJm
-(are) 12.1648 Tj
--344 TJm
-(allo) 14.9445 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--343 TJm
-(in) 7.75121 Tj
--344 TJm
-(each) 18.2522 Tj
-72 283.636 Td
-(state,) 20.7529 Tj
--281 TJm
-(wh) 12.1748 Tj
-1 TJm
-(at) 7.19329 Tj
--275 TJm
-(action) 24.3496 Tj
--274 TJm
-(will) 15.5024 Tj
--275 TJm
-(be) 9.40507 Tj
--274 TJm
-(tak) 12.1748 Tj
-10 TJm
-(en,) 11.8958 Tj
--281 TJm
-(what) 19.3681 Tj
--274 TJm
-(the) 12.1748 Tj
--275 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--274 TJm
-(state) 18.2622 Tj
--275 TJm
-(is) 6.64532 Tj
-1 TJm
-(,) 2.49075 Tj
--281 TJm
-(and) 14.3866 Tj
--275 TJm
-(what) 19.3681 Tj
--274 TJm
-(the) 12.1748 Tj
--274 TJm
-(non-error) 37.6203 Tj
--275 TJm
-(return) 23.7916 Tj
--274 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues) 20.474 Tj
--275 TJm
-(are.) 14.6556 Tj
--767 TJm
-(Note) 19.3681 Tj
--274 TJm
-(that) 14.9445 Tj
--275 TJm
-(you) 14.9445 Tj
--274 TJm
-(can') 17.1463 Tj
-18 TJm
-(t) 2.76971 Tj
-72 271.681 Td
-(e) 4.42357 Tj
-15 TJm
-(xplicitly) 33.2166 Tj
--347 TJm
-(ask) 13.2807 Tj
--348 TJm
-(what) 19.3681 Tj
--347 TJm
-(state) 18.2622 Tj
--347 TJm
-(the) 12.1748 Tj
--348 TJm
-(stream) 26.5614 Tj
--347 TJm
-(is) 6.64532 Tj
--347 TJm
-(in,) 10.242 Tj
--372 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--348 TJm
-(nor) 13.2807 Tj
--347 TJm
-(do) 9.963 Tj
--347 TJm
-(you) 14.9445 Tj
--348 TJm
-(need) 18.8101 Tj
--347 TJm
-(to) 7.75121 Tj
--348 TJm
-(--) 6.63536 Tj
--347 TJm
-(it) 5.53943 Tj
--347 TJm
-(can) 13.8286 Tj
--348 TJm
-(be) 9.40507 Tj
--347 TJm
-(inferred) 31.5329 Tj
--348 TJm
-(from) 19.3681 Tj
--347 TJm
-(the) 12.1748 Tj
--347 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues) 20.474 Tj
--348 TJm
-(returned) 33.1967 Tj
--347 TJm
-(by) 9.963 Tj
-[1 0 0 1 72 259.726] cm
-0 g
-0 G
-[1 0 0 1 -72 -259.726] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 259.726 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 155.686 259.726] cm
-0 g
-0 G
-[1 0 0 1 -155.686 -259.726] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.686 259.726 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 258.162] cm
-0 g
-0 G
-[1 0 0 1 0 -207.31] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.852 Td
-/F128_0 9.963 Tf
-(14) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 18 18
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -595.402] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 573.848 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 570.261] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(IDLE/any) 47.8224 Tj
-98.488 699.676 Td
-(Illegal.) 47.8224 Tj
--852 TJm
-(IDLE) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(onl) 17.9334 Tj
-1 TJm
-(y) 5.9778 Tj
--426 TJm
-(exists) 35.8668 Tj
--426 TJm
-(after) 29.889 Tj
--426 TJm
-(BZ2_bzCompressEnd) 101.623 Tj
--426 TJm
-(or) 11.9556 Tj
-98.488 687.721 Td
-(before) 35.8668 Tj
--426 TJm
-(BZ2_bzCompressInit) 107.6 Tj
-1 TJm
-(.) 5.9778 Tj
-98.488 675.766 Td
-(Return) 35.8668 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_SEQUENC) 59.778 Tj
-1 TJm
-(E_ERROR) 41.8446 Tj
-90 651.856 Td
-(RUNNING/BZ_RUN) 83.6892 Tj
-98.488 639.9 Td
-(Compress) 47.8224 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(next_in) 41.8446 Tj
--426 TJm
-(to) 11.9556 Tj
--425 TJm
-(next_out) 47.8224 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(much) 23.9112 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(possible.) 53.8002 Tj
-98.488 627.945 Td
-(Next) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(RUNNING) 41.8446 Tj
-98.488 615.99 Td
-(Return) 35.8668 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_RUN_OK) 53.8002 Tj
-90 592.08 Td
-(RUNNING/BZ_FLUSH) 95.6448 Tj
-98.488 580.124 Td
-(Remember) 47.8224 Tj
--426 TJm
-(current) 41.8446 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(of) 11.9556 Tj
--425 TJm
-(next_in.) 47.8224 Tj
--426 TJm
-(Compress) 47.8224 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(next_in) 41.8446 Tj
-98.488 568.169 Td
-(to) 11.9556 Tj
--426 TJm
-(next_out) 47.8224 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(much) 23.9112 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(p) 5.9778 Tj
-1 TJm
-(ossible,) 47.8224 Tj
--426 TJm
-(but) 17.9334 Tj
--426 TJm
-(do) 11.9556 Tj
--426 TJm
-(not) 17.9334 Tj
--426 TJm
-(accept) 35.8668 Tj
--426 TJm
-(any) 17.9334 Tj
--426 TJm
-(more) 23.9112 Tj
--426 TJm
-(input.) 35.8668 Tj
-98.488 556.214 Td
-(Next) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(FLUSHING) 47.8224 Tj
-98.488 544.259 Td
-(Return) 35.8668 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_FLUSH_O) 59.778 Tj
-1 TJm
-(K) 5.9778 Tj
-90 520.349 Td
-(RUNNING/BZ_FINISH) 101.623 Tj
-98.488 508.393 Td
-(Remember) 47.8224 Tj
--426 TJm
-(current) 41.8446 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(of) 11.9556 Tj
--425 TJm
-(next_in.) 47.8224 Tj
--426 TJm
-(Compress) 47.8224 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(next_in) 41.8446 Tj
-98.488 496.438 Td
-(to) 11.9556 Tj
--426 TJm
-(next_out) 47.8224 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(much) 23.9112 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(p) 5.9778 Tj
-1 TJm
-(ossible,) 47.8224 Tj
--426 TJm
-(but) 17.9334 Tj
--426 TJm
-(do) 11.9556 Tj
--426 TJm
-(not) 17.9334 Tj
--426 TJm
-(accept) 35.8668 Tj
--426 TJm
-(any) 17.9334 Tj
--426 TJm
-(more) 23.9112 Tj
--426 TJm
-(input.) 35.8668 Tj
-98.488 484.483 Td
-(Next) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(FINISHING) 53.8002 Tj
-98.488 472.528 Td
-(Return) 35.8668 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_FINISH_) 59.778 Tj
-1 TJm
-(OK) 11.9556 Tj
-90 448.618 Td
-(FLUSHING/BZ_FLUSH) 101.623 Tj
-98.488 436.662 Td
-(Compress) 47.8224 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(next_in) 41.8446 Tj
--426 TJm
-(to) 11.9556 Tj
--425 TJm
-(next_out) 47.8224 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(much) 23.9112 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(possible,) 53.8002 Tj
-98.488 424.707 Td
-(but) 17.9334 Tj
--426 TJm
-(do) 11.9556 Tj
--426 TJm
-(not) 17.9334 Tj
--426 TJm
-(accept) 35.8668 Tj
--426 TJm
-(any) 17.9334 Tj
--426 TJm
-(mo) 11.9556 Tj
-1 TJm
-(re) 11.9556 Tj
--426 TJm
-(input.) 35.8668 Tj
-98.488 412.752 Td
-(If) 11.9556 Tj
--426 TJm
-(all) 17.9334 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(existing) 47.8224 Tj
--426 TJm
-(inpu) 23.9112 Tj
-1 TJm
-(t) 5.9778 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--426 TJm
-(used) 23.9112 Tj
--426 TJm
-(up) 11.9556 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(all) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
-98.488 400.797 Td
-(output) 35.8668 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--426 TJm
-(removed) 41.8446 Tj
-106.976 388.842 Td
-(Next) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(RUNNING;) 47.8224 Tj
--426 TJm
-(Re) 11.9556 Tj
-1 TJm
-(turn) 23.9112 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_RUN_OK) 53.8002 Tj
-98.488 376.887 Td
-(else) 23.9112 Tj
-106.976 364.931 Td
-(Next) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(FLUSHING;) 53.8002 Tj
--426 TJm
-(R) 5.9778 Tj
-1 TJm
-(eturn) 29.889 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_FLUSH_OK) 65.7558 Tj
-90 341.021 Td
-(FLUSHING/other) 83.6892 Tj
-98.488 329.066 Td
-(Illegal.) 47.8224 Tj
-98.488 317.111 Td
-(Return) 35.8668 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_SEQUENC) 59.778 Tj
-1 TJm
-(E_ERROR) 41.8446 Tj
-90 293.2 Td
-(FINISHING/BZ_FINISH) 113.578 Tj
-98.488 281.245 Td
-(Compress) 47.8224 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(next_in) 41.8446 Tj
--426 TJm
-(to) 11.9556 Tj
--425 TJm
-(next_out) 47.8224 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(much) 23.9112 Tj
--426 TJm
-(as) 11.9556 Tj
--426 TJm
-(possible,) 53.8002 Tj
-98.488 269.29 Td
-(but) 17.9334 Tj
--426 TJm
-(to) 11.9556 Tj
--426 TJm
-(not) 17.9334 Tj
--426 TJm
-(accept) 35.8668 Tj
--426 TJm
-(any) 17.9334 Tj
--426 TJm
-(mo) 11.9556 Tj
-1 TJm
-(re) 11.9556 Tj
--426 TJm
-(input.) 35.8668 Tj
-98.488 257.335 Td
-(If) 11.9556 Tj
--426 TJm
-(all) 17.9334 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(existing) 47.8224 Tj
--426 TJm
-(inpu) 23.9112 Tj
-1 TJm
-(t) 5.9778 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--426 TJm
-(used) 23.9112 Tj
--426 TJm
-(up) 11.9556 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(all) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
-98.488 245.38 Td
-(output) 35.8668 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--426 TJm
-(removed) 41.8446 Tj
-106.976 233.424 Td
-(Next) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(IDLE;) 29.889 Tj
--426 TJm
-(Retur) 29.889 Tj
-1 TJm
-(n) 5.9778 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_STREAM_END) 77.7114 Tj
-98.488 221.469 Td
-(else) 23.9112 Tj
-106.976 209.514 Td
-(Next) 23.9112 Tj
--426 TJm
-(state) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(FINISHING;) 59.778 Tj
--425 TJm
-(Return) 35.8668 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_FINISHING) 71.7336 Tj
-90 185.604 Td
-(FINISHING/other) 89.667 Tj
-98.488 173.649 Td
-(Illegal.) 47.8224 Tj
-98.488 161.693 Td
-(Return) 35.8668 Tj
--426 TJm
-(value) 29.889 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_SEQUENC) 59.778 Tj
-1 TJm
-(E_ERROR) 41.8446 Tj
-[1 0 0 1 72 146.152] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -136.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 124.234 Td
-/F128_0 9.963 Tf
-(That) 18.2622 Tj
--250 TJm
-(still) 14.9545 Tj
--250 TJm
-(looks) 21.5898 Tj
--250 TJm
-(complicate) 43.7176 Tj
-1 TJm
-(d?) 9.40507 Tj
--620 TJm
-(W) 9.40507 Tj
-80 TJm
-(ell,) 12.4538 Tj
--250 TJm
-(f) 3.31768 Tj
-10 TJm
-(air) 10.511 Tj
--250 TJm
-(enough.) 31.8218 Tj
--620 TJm
-(The) 15.4925 Tj
--250 TJm
-(usual) 21.0319 Tj
--250 TJm
-(sequence) 36.5144 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(calls) 18.2622 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(com) 17.1563 Tj
-1 TJm
-(pressing) 33.2067 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(load) 17.1563 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(is:) 9.41504 Tj
-[1 0 0 1 72 122.077] cm
-0 g
-0 G
-[1 0 0 1 0 -29.723] cm
-0 g
-0 G
-[1 0 0 1 7.372 0] cm
-0 g
-0 G
-[1 0 0 1 -79.372 -92.354] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.372 92.354 Td
-/F128_0 9.963 Tf
-(1.) 7.47225 Tj
-[1 0 0 1 86.844 92.354] cm
-0 g
-0 G
-[1 0 0 1 3.089 0] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 -91.925 -92.354] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.925 92.354 Td
-/F128_0 9.963 Tf
-(Get) 14.3866 Tj
--250 TJm
-(started) 26.5614 Tj
--250 TJm
-(with) 17.7142 Tj
-[1 0 0 1 158.056 92.354] cm
-0 g
-0 G
-[1 0 0 1 -158.056 -92.354] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.056 92.354 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 265.653 92.354] cm
-0 g
-0 G
-[1 0 0 1 -265.653 -92.354] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-265.653 92.354 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 268.144 92.354] cm
-0 g
-0 G
-[1 0 0 1 -196.144 -41.502] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(15) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 19 19
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -31.517] cm
-0 g
-0 G
-[1 0 0 1 7.372 0] cm
-0 g
-0 G
-[1 0 0 1 -79.372 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.372 710.037 Td
-/F128_0 9.963 Tf
-(2.) 7.47225 Tj
-[1 0 0 1 86.844 710.037] cm
-0 g
-0 G
-[1 0 0 1 3.089 0] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 -91.925 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.925 710.037 Td
-/F128_0 9.963 Tf
-(Sho) 15.5024 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--240 TJm
-(data) 16.5984 Tj
--240 TJm
-(in) 7.75121 Tj
--240 TJm
-(and) 14.3866 Tj
--241 TJm
-(shlur) 19.926 Tj
-1 TJm
-(p) 4.9815 Tj
--241 TJm
-(out) 12.7327 Tj
--240 TJm
-(its) 9.41504 Tj
--240 TJm
-(compressed) 47.0353 Tj
--240 TJm
-(form) 19.3681 Tj
--240 TJm
-(using) 21.5898 Tj
--240 TJm
-(zero) 17.1463 Tj
--240 TJm
-(or) 8.29918 Tj
--241 TJm
-(m) 7.75121 Tj
-1 TJm
-(ore) 12.7228 Tj
--241 TJm
-(calls) 18.2622 Tj
--240 TJm
-(of) 8.29918 Tj
-[1 0 0 1 401.454 710.037] cm
-0 g
-0 G
-[1 0 0 1 -401.454 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-401.454 710.037 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 485.14 710.037] cm
-0 g
-0 G
-[1 0 0 1 -485.14 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-487.533 710.037 Td
-/F128_0 9.963 Tf
-(with) 17.7142 Tj
--240 TJm
-(action) 24.3496 Tj
--240 TJm
-(=) 5.61913 Tj
-[1 0 0 1 91.925 698.082] cm
-0 g
-0 G
-[1 0 0 1 -91.925 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.925 698.082 Td
-/F130_0 9.963 Tf
-(BZ_RUN) 35.8668 Tj
-[1 0 0 1 127.791 698.082] cm
-0 g
-0 G
-[1 0 0 1 -127.791 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-127.791 698.082 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 130.281 698.082] cm
-0 g
-0 G
-[1 0 0 1 -58.281 -21.918] cm
-0 g
-0 G
-[1 0 0 1 7.372 0] cm
-0 g
-0 G
-[1 0 0 1 -79.372 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.372 676.164 Td
-/F128_0 9.963 Tf
-(3.) 7.47225 Tj
-[1 0 0 1 86.844 676.164] cm
-0 g
-0 G
-[1 0 0 1 3.089 0] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 -91.925 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.925 676.164 Td
-/F128_0 9.963 Tf
-(Finish) 24.9175 Tj
--242 TJm
-(up) 9.963 Tj
-1 TJm
-(.) 2.49075 Tj
--308 TJm
-(Repeatedl) 39.842 Tj
-1 TJm
-(y) 4.9815 Tj
--242 TJm
-(call) 14.3866 Tj
-[1 0 0 1 198.784 676.164] cm
-0 g
-0 G
-[1 0 0 1 -198.784 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.784 676.164 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 282.471 676.164] cm
-0 g
-0 G
-[1 0 0 1 -282.471 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.878 676.164 Td
-/F128_0 9.963 Tf
-(with) 17.7142 Tj
--242 TJm
-(ac) 8.84714 Tj
-1 TJm
-(tion) 15.5024 Tj
--242 TJm
-(=) 5.61913 Tj
-[1 0 0 1 339.78 676.164] cm
-0 g
-0 G
-[1 0 0 1 -339.78 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.78 676.164 Td
-/F130_0 9.963 Tf
-(BZ_FINISH) 53.8002 Tj
-[1 0 0 1 393.579 676.164] cm
-0 g
-0 G
-[1 0 0 1 -393.579 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-393.579 676.164 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--242 TJm
-(cop) 14.3866 Tj
-10 TJm
-(yi) 7.75121 Tj
-1 TJm
-(ng) 9.963 Tj
--242 TJm
-(out) 12.7327 Tj
--242 TJm
-(the) 12.1748 Tj
--241 TJm
-(compressed) 47.0353 Tj
--242 TJm
-(output,) 27.9562 Tj
-91.925 664.209 Td
-(until) 18.2721 Tj
-[1 0 0 1 112.687 664.209] cm
-0 g
-0 G
-[1 0 0 1 -112.687 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-112.687 664.209 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 190.396 664.209] cm
-0 g
-0 G
-[1 0 0 1 -190.396 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.886 664.209 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(returned.) 35.6875 Tj
-[1 0 0 1 237.708 664.209] cm
-0 g
-0 G
-[1 0 0 1 -165.708 -21.918] cm
-0 g
-0 G
-[1 0 0 1 7.372 0] cm
-0 g
-0 G
-[1 0 0 1 -79.372 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.372 642.291 Td
-/F128_0 9.963 Tf
-(4.) 7.47225 Tj
-[1 0 0 1 86.844 642.291] cm
-0 g
-0 G
-[1 0 0 1 3.089 0] cm
-0 g
-0 G
-[1 0 0 1 1.992 0] cm
-0 g
-0 G
-[1 0 0 1 -91.925 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.925 642.291 Td
-/F128_0 9.963 Tf
-(Close) 22.6957 Tj
--250 TJm
-(up) 9.963 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(go) 9.963 Tj
--250 TJm
-(home.) 24.6285 Tj
--620 TJm
-(Call) 16.6083 Tj
-[1 0 0 1 208.796 642.291] cm
-0 g
-0 G
-[1 0 0 1 -208.796 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.796 642.291 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressEnd) 101.623 Tj
-[1 0 0 1 310.415 642.291] cm
-0 g
-0 G
-[1 0 0 1 -310.415 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.415 642.291 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 312.906 642.291] cm
-0 g
-0 G
-[1 0 0 1 -240.906 -12.119] cm
-0 g
-0 G
-[1 0 0 1 -72 -630.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 620.374 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--269 TJm
-(the) 12.1748 Tj
--270 TJm
-(data) 16.5984 Tj
--269 TJm
-(you) 14.9445 Tj
--270 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--269 TJm
-(to) 7.75121 Tj
--269 TJm
-(compress) 37.6303 Tj
--270 TJm
-(\002ts) 12.1847 Tj
--269 TJm
-(into) 15.5024 Tj
--270 TJm
-(you) 14.9445 Tj
-1 TJm
-(r) 3.31768 Tj
--270 TJm
-(input) 20.4839 Tj
--269 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--270 TJm
-(all) 9.963 Tj
--269 TJm
-(at) 7.19329 Tj
--270 TJm
-(on) 9.963 Tj
-1 TJm
-(ce,) 11.3379 Tj
--275 TJm
-(you) 14.9445 Tj
--269 TJm
-(can) 13.8286 Tj
--270 TJm
-(skip) 16.6083 Tj
--269 TJm
-(the) 12.1748 Tj
--269 TJm
-(calls) 18.2622 Tj
--270 TJm
-(of) 8.29918 Tj
-[1 0 0 1 456.314 620.374] cm
-0 g
-0 G
-[1 0 0 1 -456.314 -620.374] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-456.314 620.374 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-72 608.418 Td
-(\() 5.9778 Tj
--600 TJm
-(...,) 23.9112 Tj
--600 TJm
-(BZ_RUN) 35.8668 Tj
--600 TJm
-(\)) 5.9778 Tj
-[1 0 0 1 161.664 608.418] cm
-0 g
-0 G
-[1 0 0 1 -161.664 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.154 608.418 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
--250 TJm
-(just) 14.3965 Tj
--250 TJm
-(do) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
-[1 0 0 1 225.036 608.418] cm
-0 g
-0 G
-[1 0 0 1 -225.036 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-225.036 608.418 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
--600 TJm
-(\() 5.9778 Tj
--600 TJm
-(...,) 23.9112 Tj
--600 TJm
-(B) 5.9778 Tj
-1 TJm
-(Z_FINISH) 47.8224 Tj
--600 TJm
-(\)) 5.9778 Tj
-[1 0 0 1 422.296 608.418] cm
-0 g
-0 G
-[1 0 0 1 -422.296 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-424.786 608.418 Td
-/F128_0 9.963 Tf
-(calls.) 20.7529 Tj
-[1 0 0 1 72 606.262] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -596.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 586.501 Td
-/F128_0 9.963 Tf
-(All) 12.7327 Tj
--277 TJm
-(required) 33.1967 Tj
--278 TJm
-(memory) 33.2067 Tj
--277 TJm
-(is) 6.64532 Tj
--278 TJm
-(allocated) 35.9664 Tj
--277 TJm
-(by) 9.963 Tj
-[1 0 0 1 220.295 586.501] cm
-0 g
-0 G
-[1 0 0 1 -220.295 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.295 586.501 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 327.891 586.501] cm
-0 g
-0 G
-[1 0 0 1 -327.891 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-327.891 586.501 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--785 TJm
-(The) 15.4925 Tj
--278 TJm
-(compression) 50.363 Tj
--277 TJm
-(library) 26.5614 Tj
--277 TJm
-(can) 13.8286 Tj
--278 TJm
-(accept) 25.4455 Tj
--277 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--278 TJm
-(data) 16.5984 Tj
--277 TJm
-(at) 7.19329 Tj
--278 TJm
-(all) 9.963 Tj
-72 574.545 Td
-(\(ob) 13.2807 Tj
-15 TJm
-(viously\).) 35.1495 Tj
--612 TJm
-(So) 10.5209 Tj
--237 TJm
-(you) 14.9445 Tj
--238 TJm
-(shouldn') 34.8705 Tj
-18 TJm
-(t) 2.76971 Tj
--238 TJm
-(ge) 9.40507 Tj
-1 TJm
-(t) 2.76971 Tj
--238 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--238 TJm
-(error) 19.3581 Tj
--238 TJm
-(r) 3.31768 Tj
-1 TJm
-(eturn) 20.474 Tj
--238 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues) 20.474 Tj
--238 TJm
-(from) 19.3681 Tj
--237 TJm
-(the) 12.1748 Tj
-[1 0 0 1 339.287 574.545] cm
-0 g
-0 G
-[1 0 0 1 -339.287 -574.545] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.287 574.545 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 422.973 574.545] cm
-0 g
-0 G
-[1 0 0 1 -422.973 -574.545] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.342 574.545 Td
-/F128_0 9.963 Tf
-(calls.) 20.7529 Tj
--612 TJm
-(If) 6.63536 Tj
--237 TJm
-(you) 14.9445 Tj
--238 TJm
-(do,) 12.4538 Tj
--240 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--238 TJm
-(will) 15.5024 Tj
--237 TJm
-(be) 9.40507 Tj
-[1 0 0 1 72 562.59] cm
-0 g
-0 G
-[1 0 0 1 -72 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 562.59 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-[1 0 0 1 173.619 562.59] cm
-0 g
-0 G
-[1 0 0 1 -173.619 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.619 562.59 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(indicate) 31.5429 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(your) 18.2622 Tj
--250 TJm
-(prog) 18.2622 Tj
-1 TJm
-(ramming.) 38.4671 Tj
-[1 0 0 1 72 560.433] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -550.471] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 540.672 Td
-/F128_0 9.963 Tf
-(T) 6.08739 Tj
-35 TJm
-(ri) 6.08739 Tj
-25 TJm
-(vial) 14.9445 Tj
--250 TJm
-(other) 20.474 Tj
--250 TJm
-(possible) 32.6587 Tj
--250 TJm
-(return) 23.7916 Tj
--249 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 538.516] cm
-0 g
-0 G
-[1 0 0 1 0 -36.862] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -529.151] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 529.151 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 517.196 Td
-(if) 11.9556 Tj
--426 TJm
-(strm) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL,) 29.889 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(strm) 23.9112 Tj
-1 TJm
-(->s) 17.9334 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-[1 0 0 1 72 501.654] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -491.691] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 471.033 Td
-/F121_0 17.215 Tf
-(3.3.3.) 43.0719 Tj
-[1 0 0 1 119.858 471.033] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -471.033] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 471.033 Td
-/F387_0 17.215 Tf
-(BZ2_bzCompressEnd) 175.593 Tj
-[1 0 0 1 295.455 471.033] cm
-0 g
-0 G
-[1 0 0 1 -223.455 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -459.335] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 459.335 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzCompressEnd) 101.623 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(b) 5.9778 Tj
-1 TJm
-(z_stream) 47.8224 Tj
--426 TJm
-(*strm) 29.889 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 443.793] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -433.831] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 421.876 Td
-/F128_0 9.963 Tf
-(Releases) 34.8605 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(memory) 33.2067 Tj
--250 TJm
-(assoc) 21.5799 Tj
-1 TJm
-(iated) 19.3681 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(compression) 50.363 Tj
--250 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 72 419.719] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -409.756] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 399.958 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 399.858] cm
-0 g
-0 G
-[1 0 0 1 0 -36.861] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -390.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 390.493 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
--852 TJm
-(if) 11.9556 Tj
--426 TJm
-(strm) 23.9112 Tj
--425 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(strm->s) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-90 378.538 Td
-(BZ_OK) 29.889 Tj
--4686 TJm
-(otherw) 35.8668 Tj
-1 TJm
-(ise) 17.9334 Tj
-[1 0 0 1 72 362.997] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -353.034] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 332.375 Td
-/F121_0 17.215 Tf
-(3.3.4.) 43.0719 Tj
-[1 0 0 1 119.858 332.375] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -332.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 332.375 Td
-/F387_0 17.215 Tf
-(BZ2_bzDecompressInit) 206.58 Tj
-[1 0 0 1 326.443 332.375] cm
-0 g
-0 G
-[1 0 0 1 -254.443 -2.332] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.323] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -320.678] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 320.678 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzDecompressInit) 119.556 Tj
--425 TJm
-(\() 5.9778 Tj
--426 TJm
-(bz_stream) 53.8002 Tj
--426 TJm
-(*strm,) 35.8668 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(verbosity,) 59.778 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(small) 29.889 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 305.136] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -295.173] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 283.218 Td
-/F128_0 9.963 Tf
-(Prepares) 34.3026 Tj
--351 TJm
-(for) 11.6169 Tj
--351 TJm
-(decompression.) 62.2588 Tj
--1227 TJm
-(As) 11.0689 Tj
--351 TJm
-(with) 17.7142 Tj
-[1 0 0 1 235.177 283.218] cm
-0 g
-0 G
-[1 0 0 1 -235.177 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.177 283.218 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 342.773 283.218] cm
-0 g
-0 G
-[1 0 0 1 -342.773 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-342.773 283.218 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--377 TJm
-(a) 4.42357 Tj
-[1 0 0 1 356.937 283.218] cm
-0 g
-0 G
-[1 0 0 1 -356.937 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-356.937 283.218 Td
-/F130_0 9.963 Tf
-(bz_stream) 53.8002 Tj
-[1 0 0 1 410.736 283.218] cm
-0 g
-0 G
-[1 0 0 1 -410.736 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.234 283.218 Td
-/F128_0 9.963 Tf
-(record) 25.4455 Tj
--351 TJm
-(should) 26.5713 Tj
--351 TJm
-(be) 9.40507 Tj
--351 TJm
-(allocated) 35.9664 Tj
--351 TJm
-(and) 14.3866 Tj
-72 271.263 Td
-(initialised) 39.304 Tj
--305 TJm
-(before) 25.4455 Tj
--306 TJm
-(the) 12.1748 Tj
--305 TJm
-(call.) 16.8773 Tj
--954 TJm
-(Fields) 24.3595 Tj
-[1 0 0 1 211.833 271.263] cm
-0 g
-0 G
-[1 0 0 1 -211.833 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.833 271.263 Td
-/F130_0 9.963 Tf
-(bzalloc) 41.8446 Tj
-[1 0 0 1 253.676 271.263] cm
-0 g
-0 G
-[1 0 0 1 -253.676 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.676 271.263 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 259.35 271.263] cm
-0 g
-0 G
-[1 0 0 1 -259.35 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.35 271.263 Td
-/F130_0 9.963 Tf
-(bzfree) 35.8668 Tj
-[1 0 0 1 295.215 271.263] cm
-0 g
-0 G
-[1 0 0 1 -295.215 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-298.26 271.263 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 315.69 271.263] cm
-0 g
-0 G
-[1 0 0 1 -315.69 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.69 271.263 Td
-/F130_0 9.963 Tf
-(opaque) 35.8668 Tj
-[1 0 0 1 351.556 271.263] cm
-0 g
-0 G
-[1 0 0 1 -351.556 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-354.6 271.263 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--305 TJm
-(be) 9.40507 Tj
--306 TJm
-(set) 11.0689 Tj
--306 TJm
-(if) 6.08739 Tj
--305 TJm
-(a) 4.42357 Tj
--306 TJm
-(custom) 28.7831 Tj
--305 TJm
-(memory) 33.2067 Tj
--306 TJm
-(al) 7.19329 Tj
-1 TJm
-(locator) 27.6673 Tj
--306 TJm
-(is) 6.64532 Tj
-72 259.308 Td
-(required,) 35.6875 Tj
--350 TJm
-(or) 8.29918 Tj
--330 TJm
-(made) 21.5799 Tj
-[1 0 0 1 147.635 259.308] cm
-0 g
-0 G
-[1 0 0 1 -147.635 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.635 259.308 Td
-/F130_0 9.963 Tf
-(NULL) 23.9112 Tj
-[1 0 0 1 171.546 259.308] cm
-0 g
-0 G
-[1 0 0 1 -171.546 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-174.836 259.308 Td
-/F128_0 9.963 Tf
-(for) 11.6169 Tj
--330 TJm
-(the) 12.1748 Tj
--330 TJm
-(normal) 28.2252 Tj
-[1 0 0 1 236.722 259.308] cm
-0 g
-0 G
-[1 0 0 1 -236.722 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.722 259.308 Td
-/F130_0 9.963 Tf
-(malloc) 35.8668 Tj
-[1 0 0 1 272.587 259.308] cm
-0 g
-0 G
-[1 0 0 1 -272.587 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.878 259.308 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 281.938 259.308] cm
-0 g
-0 G
-[1 0 0 1 -281.938 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-281.938 259.308 Td
-/F130_0 9.963 Tf
-(free) 23.9112 Tj
-[1 0 0 1 305.848 259.308] cm
-0 g
-0 G
-[1 0 0 1 -305.848 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.139 259.308 Td
-/F128_0 9.963 Tf
-(routines.) 34.5915 Tj
--1102 TJm
-(Upo) 17.1563 Tj
-1 TJm
-(n) 4.9815 Tj
--331 TJm
-(return,) 26.2824 Tj
--350 TJm
-(the) 12.1748 Tj
--330 TJm
-(internal) 30.437 Tj
--330 TJm
-(state) 18.2622 Tj
--331 TJm
-(wi) 9.963 Tj
-1 TJm
-(ll) 5.53943 Tj
--331 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--330 TJm
-(been) 18.8101 Tj
-72 247.353 Td
-(initialised,) 41.7948 Tj
--250 TJm
-(and) 14.3866 Tj
-[1 0 0 1 133.16 247.353] cm
-0 g
-0 G
-[1 0 0 1 -133.16 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-133.16 247.353 Td
-/F130_0 9.963 Tf
-(total_in) 47.8224 Tj
-[1 0 0 1 180.98 247.353] cm
-0 g
-0 G
-[1 0 0 1 -180.98 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.471 247.353 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 200.348 247.353] cm
-0 g
-0 G
-[1 0 0 1 -200.348 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.348 247.353 Td
-/F130_0 9.963 Tf
-(total_out) 53.8002 Tj
-[1 0 0 1 254.146 247.353] cm
-0 g
-0 G
-[1 0 0 1 -254.146 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.637 247.353 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(zero.) 19.6371 Tj
-[1 0 0 1 72 245.913] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -235.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 225.435 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(meaning) 34.3126 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(parameter) 39.8321 Tj
-[1 0 0 1 192.756 225.435] cm
-0 g
-0 G
-[1 0 0 1 -192.756 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.756 225.435 Td
-/F130_0 9.963 Tf
-(verbosity) 53.8002 Tj
-[1 0 0 1 246.554 225.435] cm
-0 g
-0 G
-[1 0 0 1 -246.554 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.554 225.435 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(see) 12.7228 Tj
-[1 0 0 1 266.748 225.435] cm
-0 g
-0 G
-[1 0 0 1 -266.748 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.748 225.435 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 374.345 225.435] cm
-0 g
-0 G
-[1 0 0 1 -374.345 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.345 225.435 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 223.278] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -213.316] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 203.517 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
-[1 0 0 1 81.497 203.517] cm
-0 g
-0 G
-[1 0 0 1 -81.497 -203.517] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-81.497 203.517 Td
-/F130_0 9.963 Tf
-(small) 29.889 Tj
-[1 0 0 1 111.385 203.517] cm
-0 g
-0 G
-[1 0 0 1 -111.385 -203.517] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-114.248 203.517 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--287 TJm
-(nonzero,) 34.5816 Tj
--297 TJm
-(the) 12.1748 Tj
--287 TJm
-(library) 26.5614 Tj
--287 TJm
-(will) 15.5024 Tj
--287 TJm
-(use) 13.2807 Tj
--288 TJm
-(an) 9.40507 Tj
--287 TJm
-(alternati) 32.6488 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--287 TJm
-(decompression) 59.768 Tj
--287 TJm
-(algorithm) 38.7461 Tj
--287 TJm
-(which) 24.3496 Tj
--287 TJm
-(uses) 17.1563 Tj
--288 TJm
-(less) 14.9445 Tj
--287 TJm
-(memory) 33.2067 Tj
--287 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--287 TJm
-(at) 7.19329 Tj
--287 TJm
-(the) 12.1748 Tj
-72 191.562 Td
-(cost) 16.0504 Tj
--289 TJm
-(of) 8.29918 Tj
--290 TJm
-(deco) 18.8101 Tj
-1 TJm
-(mpressing) 40.9579 Tj
--290 TJm
-(more) 20.474 Tj
--289 TJm
-(slo) 11.6268 Tj
-25 TJm
-(wly) 14.9445 Tj
--289 TJm
-(\(roughly) 34.3126 Tj
--289 TJm
-(speaking,) 37.9092 Tj
--299 TJm
-(half) 15.4925 Tj
--290 TJm
-(the) 12.1748 Tj
--289 TJm
-(speed,) 25.1765 Tj
--299 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--289 TJm
-(the) 12.1748 Tj
--290 TJm
-(m) 7.75121 Tj
-1 TJm
-(aximum) 32.6587 Tj
--290 TJm
-(memory) 33.2067 Tj
--289 TJm
-(requirement) 48.1412 Tj
--289 TJm
-(drops) 22.1378 Tj
-72 179.607 Td
-(to) 7.75121 Tj
--250 TJm
-(around) 27.6673 Tj
--250 TJm
-(2300k\).) 30.7159 Tj
--620 TJm
-(See) 14.3866 Tj
-[1 0 0 1 166.166 179.607] cm
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -166.166 -179.607] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.166 179.607 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(bzip2) 22.1378 Tj
-[1 0 0 1 235.924 179.607] cm
-0 g
-0 G
-0 0 1 rg
-0 0 1 RG
-0 0 1 rg
-0 0 1 RG
-[1 0 0 1 -235.924 -179.607] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.415 179.607 Td
-/F128_0 9.963 Tf
-([2]) 11.6169 Tj
-[1 0 0 1 250.031 179.607] cm
-0 0 1 rg
-0 0 1 RG
-0 g
-0 G
-[1 0 0 1 -250.031 -179.607] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-252.522 179.607 Td
-/F128_0 9.963 Tf
-(for) 11.6169 Tj
--250 TJm
-(more) 20.474 Tj
--250 TJm
-(information) 47.0453 Tj
--250 TJm
-(on) 9.963 Tj
--250 TJm
-(mem) 19.926 Tj
-1 TJm
-(ory) 13.2807 Tj
--250 TJm
-(management.) 53.4017 Tj
-[1 0 0 1 72 177.45] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -167.487] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 157.689 Td
-/F128_0 9.963 Tf
-(Note) 19.3681 Tj
--289 TJm
-(that) 14.9445 Tj
--289 TJm
-(the) 12.1748 Tj
--290 TJm
-(amou) 22.1378 Tj
-1 TJm
-(nt) 7.75121 Tj
--290 TJm
-(of) 8.29918 Tj
--289 TJm
-(memory) 33.2067 Tj
--289 TJm
-(needed) 28.2152 Tj
--289 TJm
-(to) 7.75121 Tj
--289 TJm
-(decompress) 47.0353 Tj
--290 TJm
-(a) 4.42357 Tj
--289 TJm
-(stream) 26.5614 Tj
--289 TJm
-(cannot) 26.5614 Tj
--289 TJm
-(be) 9.40507 Tj
--289 TJm
-(determined) 44.8235 Tj
--289 TJm
-(until) 18.2721 Tj
--290 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--290 TJm
-(stream') 29.879 Tj
-55 TJm
-(s) 3.87561 Tj
--289 TJm
-(header) 26.5514 Tj
--289 TJm
-(has) 13.2807 Tj
-72 145.734 Td
-(been) 18.8101 Tj
--342 TJm
-(read,) 19.6371 Tj
--365 TJm
-(so) 8.85711 Tj
--343 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--342 TJm
-(if) 6.08739 Tj
-[1 0 0 1 161.081 145.734] cm
-0 g
-0 G
-[1 0 0 1 -161.081 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.081 145.734 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressInit) 119.556 Tj
-[1 0 0 1 280.633 145.734] cm
-0 g
-0 G
-[1 0 0 1 -280.633 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.043 145.734 Td
-/F128_0 9.963 Tf
-(succeeds,) 37.8993 Tj
--365 TJm
-(a) 4.42357 Tj
--342 TJm
-(subsequent) 44.2756 Tj
-[1 0 0 1 381.098 145.734] cm
-0 g
-0 G
-[1 0 0 1 -381.098 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-381.098 145.734 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 476.739 145.734] cm
-0 g
-0 G
-[1 0 0 1 -476.739 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-480.149 145.734 Td
-/F128_0 9.963 Tf
-(could) 22.1378 Tj
--342 TJm
-(f) 3.31768 Tj
-10 TJm
-(ail) 9.963 Tj
--342 TJm
-(with) 17.7142 Tj
-[1 0 0 1 72 133.779] cm
-0 g
-0 G
-[1 0 0 1 -72 -133.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 133.779 Td
-/F130_0 9.963 Tf
-(BZ_MEM_ERROR) 71.7336 Tj
-[1 0 0 1 143.731 133.779] cm
-0 g
-0 G
-[1 0 0 1 -143.731 -133.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.731 133.779 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 132.613] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -122.651] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 111.861 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 111.761] cm
-0 g
-0 G
-[1 0 0 1 0 -60.909] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(16) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 20 20
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -117.195] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 95.641 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 92.055] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(BZ_CONFIG_ERROR) 89.667 Tj
-98.488 699.676 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(library) 41.8446 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--425 TJm
-(mis-compiled) 71.7336 Tj
-90 687.721 Td
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 675.766 Td
-(if) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(small) 29.889 Tj
--426 TJm
-(!=) 11.9556 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(&&) 11.9556 Tj
--426 TJm
-(small) 29.889 Tj
--425 TJm
-(!=) 11.9556 Tj
--426 TJm
-(1) 5.9778 Tj
--426 TJm
-(\)) 5.9778 Tj
-98.488 663.811 Td
-(or) 11.9556 Tj
--426 TJm
-(\(verbosity) 59.778 Tj
--426 TJm
-(<;) 11.9556 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(||) 11.9556 Tj
--426 TJm
-(ve) 11.9556 Tj
-1 TJm
-(rbosity) 41.8446 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(4\)) 11.9556 Tj
-90 651.856 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 639.9 Td
-(if) 11.9556 Tj
--426 TJm
-(insufficient) 71.7336 Tj
--426 TJm
-(memory) 35.8668 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(available) 53.8002 Tj
-[1 0 0 1 72 624.359] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -614.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 602.441 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 602.341] cm
-0 g
-0 G
-[1 0 0 1 0 -48.817] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 47.821 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 44.234] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -592.976] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 592.976 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-98.488 581.021 Td
-(if) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(returned) 47.8224 Tj
-98.488 569.066 Td
-(no) 11.9556 Tj
--426 TJm
-(specific) 47.8224 Tj
--426 TJm
-(action) 35.8668 Tj
--426 TJm
-(requir) 35.8668 Tj
-1 TJm
-(ed) 11.9556 Tj
--426 TJm
-(in) 11.9556 Tj
--426 TJm
-(case) 23.9112 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(error) 29.889 Tj
-[1 0 0 1 72 553.524] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -543.562] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 522.903 Td
-/F121_0 17.215 Tf
-(3.3.5.) 43.0719 Tj
-[1 0 0 1 119.858 522.903] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -522.903] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 522.903 Td
-/F387_0 17.215 Tf
-(BZ2_bzDecompress) 165.264 Tj
-[1 0 0 1 285.126 522.903] cm
-0 g
-0 G
-[1 0 0 1 -213.126 -2.332] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.323] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -511.206] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 511.206 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzDecompress) 95.6448 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(bz) 11.9556 Tj
-1 TJm
-(_stream) 41.8446 Tj
--426 TJm
-(*strm) 29.889 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 495.664] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 473.746 Td
-/F128_0 9.963 Tf
-(Pro) 13.8386 Tj
-15 TJm
-(vides) 21.0319 Tj
--301 TJm
-(more) 20.474 Tj
--302 TJm
-(inpu) 17.7142 Tj
-1 TJm
-(t) 2.76971 Tj
--302 TJm
-(and/out) 29.889 Tj
--301 TJm
-(output) 25.4654 Tj
--301 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--302 TJm
-(space) 22.1278 Tj
--301 TJm
-(for) 11.6169 Tj
--301 TJm
-(the) 12.1748 Tj
--302 TJm
-(library) 26.5614 Tj
-65 TJm
-(.) 2.49075 Tj
--928 TJm
-(The) 15.4925 Tj
--301 TJm
-(caller) 22.1278 Tj
--302 TJm
-(maintains) 38.7461 Tj
--301 TJm
-(input) 20.4839 Tj
--301 TJm
-(and) 14.3866 Tj
--302 TJm
-(out) 12.7327 Tj
-1 TJm
-(put) 12.7327 Tj
--302 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fers,) 17.4253 Tj
--314 TJm
-(and) 14.3866 Tj
-72 461.791 Td
-(uses) 17.1563 Tj
-[1 0 0 1 91.646 461.791] cm
-0 g
-0 G
-[1 0 0 1 -91.646 -461.791] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.646 461.791 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 187.287 461.791] cm
-0 g
-0 G
-[1 0 0 1 -187.287 -461.791] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.778 461.791 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(transfer) 30.427 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(between) 33.1967 Tj
--250 TJm
-(them) 19.926 Tj
-1 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 460.227] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -450.264] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.873 Td
-/F128_0 9.963 Tf
-(Before) 27.1093 Tj
--498 TJm
-(each) 18.2522 Tj
--498 TJm
-(call) 14.3866 Tj
--499 TJm
-(to) 7.75121 Tj
-[1 0 0 1 159.356 439.873] cm
-0 g
-0 G
-[1 0 0 1 -159.356 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.356 439.873 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 254.997 439.873] cm
-0 g
-0 G
-[1 0 0 1 -254.997 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-254.997 439.873 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 263.071 439.873] cm
-0 g
-0 G
-[1 0 0 1 -263.071 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.071 439.873 Td
-/F130_0 9.963 Tf
-(next_in) 41.8446 Tj
-[1 0 0 1 304.914 439.873] cm
-0 g
-0 G
-[1 0 0 1 -304.914 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.879 439.873 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--498 TJm
-(point) 20.4839 Tj
--498 TJm
-(at) 7.19329 Tj
--499 TJm
-(the) 12.1748 Tj
--498 TJm
-(compressed) 47.0353 Tj
--498 TJm
-(data,) 19.0891 Tj
--560 TJm
-(and) 14.3866 Tj
-[1 0 0 1 492.179 439.873] cm
-0 g
-0 G
-[1 0 0 1 -492.179 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-492.179 439.873 Td
-/F130_0 9.963 Tf
-(avail_in) 47.8224 Tj
-[1 0 0 1 540 439.873] cm
-0 g
-0 G
-[1 0 0 1 -540 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 427.918 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--308 TJm
-(indicate) 31.5429 Tj
--308 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--308 TJm
-(man) 17.1563 Tj
-15 TJm
-(y) 4.9815 Tj
--308 TJm
-(bytes) 21.0319 Tj
--308 TJm
-(the) 12.1748 Tj
--309 TJm
-(library) 26.5614 Tj
--308 TJm
-(may) 17.1563 Tj
--308 TJm
-(read.) 19.6371 Tj
-[1 0 0 1 294.955 427.918] cm
-0 g
-0 G
-[1 0 0 1 -294.955 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.955 427.918 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 390.597 427.918] cm
-0 g
-0 G
-[1 0 0 1 -390.597 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-393.667 427.918 Td
-/F128_0 9.963 Tf
-(updates) 30.437 Tj
-[1 0 0 1 427.173 427.918] cm
-0 g
-0 G
-[1 0 0 1 -427.173 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.173 427.918 Td
-/F130_0 9.963 Tf
-(next_in) 41.8446 Tj
-[1 0 0 1 469.016 427.918] cm
-0 g
-0 G
-[1 0 0 1 -469.016 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-469.016 427.918 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 474.723 427.918] cm
-0 g
-0 G
-[1 0 0 1 -474.723 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-474.723 427.918 Td
-/F130_0 9.963 Tf
-(avail_in) 47.8224 Tj
-[1 0 0 1 522.543 427.918] cm
-0 g
-0 G
-[1 0 0 1 -522.543 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 427.918 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 72 415.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 415.963 Td
-/F130_0 9.963 Tf
-(total_in) 47.8224 Tj
-[1 0 0 1 119.821 415.963] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.311 415.963 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(re\003ect) 24.8975 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(number) 30.437 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(bytes) 21.0319 Tj
--250 TJm
-(i) 2.76971 Tj
-1 TJm
-(t) 2.76971 Tj
--250 TJm
-(has) 13.2807 Tj
--250 TJm
-(read.) 19.6371 Tj
-[1 0 0 1 72 413.806] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -403.843] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 394.045 Td
-/F128_0 9.963 Tf
-(Similarly) 37.0922 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 113.799 394.045] cm
-0 g
-0 G
-[1 0 0 1 -113.799 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.799 394.045 Td
-/F130_0 9.963 Tf
-(next_out) 47.8224 Tj
-[1 0 0 1 161.62 394.045] cm
-0 g
-0 G
-[1 0 0 1 -161.62 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.41 394.045 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--280 TJm
-(point) 20.4839 Tj
--280 TJm
-(to) 7.75121 Tj
--280 TJm
-(a) 4.42357 Tj
--280 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--280 TJm
-(in) 7.75121 Tj
--280 TJm
-(which) 24.3496 Tj
--280 TJm
-(the) 12.1748 Tj
--280 TJm
-(uncompressed) 56.9983 Tj
--280 TJm
-(output) 25.4654 Tj
--280 TJm
-(is) 6.64532 Tj
--280 TJm
-(to) 7.75121 Tj
--280 TJm
-(be) 9.40507 Tj
--280 TJm
-(placed,) 28.4942 Tj
--288 TJm
-(with) 17.7142 Tj
-[1 0 0 1 486.202 394.045] cm
-0 g
-0 G
-[1 0 0 1 -486.202 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 394.045 Td
-/F130_0 9.963 Tf
-(avail_out) 53.8002 Tj
-[1 0 0 1 540 394.045] cm
-0 g
-0 G
-[1 0 0 1 -540 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 382.09 Td
-/F128_0 9.963 Tf
-(indicating) 39.852 Tj
--524 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--525 TJm
-(much) 22.1378 Tj
--524 TJm
-(output) 25.4654 Tj
--525 TJm
-(space) 22.1278 Tj
--524 TJm
-(is) 6.64532 Tj
--525 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailable.) 29.0521 Tj
-[1 0 0 1 285.792 382.09] cm
-0 g
-0 G
-[1 0 0 1 -285.792 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-285.792 382.09 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 369.478 382.09] cm
-0 g
-0 G
-[1 0 0 1 -369.478 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.705 382.09 Td
-/F128_0 9.963 Tf
-(updates) 30.437 Tj
-[1 0 0 1 410.367 382.09] cm
-0 g
-0 G
-[1 0 0 1 -410.367 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.367 382.09 Td
-/F130_0 9.963 Tf
-(next_out) 47.8224 Tj
-[1 0 0 1 458.188 382.09] cm
-0 g
-0 G
-[1 0 0 1 -458.188 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-458.188 382.09 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 466.589 382.09] cm
-0 g
-0 G
-[1 0 0 1 -466.589 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-466.589 382.09 Td
-/F130_0 9.963 Tf
-(avail_out) 53.8002 Tj
-[1 0 0 1 520.387 382.09] cm
-0 g
-0 G
-[1 0 0 1 -520.387 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 382.09 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 72 370.135] cm
-0 g
-0 G
-[1 0 0 1 -72 -370.135] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 370.135 Td
-/F130_0 9.963 Tf
-(total_out) 53.8002 Tj
-[1 0 0 1 125.798 370.135] cm
-0 g
-0 G
-[1 0 0 1 -125.798 -370.135] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.289 370.135 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(re\003ect) 24.8975 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(number) 30.437 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(bytes) 21.0319 Tj
--249 TJm
-(output.) 27.9562 Tj
-[1 0 0 1 72 367.978] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -358.015] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 348.217 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--320 TJm
-(may) 17.1563 Tj
--321 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vide) 17.1563 Tj
--320 TJm
-(and) 14.3866 Tj
--320 TJm
-(remo) 20.474 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--321 TJm
-(as) 8.29918 Tj
--320 TJm
-(little) 18.2721 Tj
--320 TJm
-(or) 8.29918 Tj
--321 TJm
-(as) 8.29918 Tj
--320 TJm
-(much) 22.1378 Tj
--320 TJm
-(data) 16.5984 Tj
--321 TJm
-(as) 8.29918 Tj
--320 TJm
-(you) 14.9445 Tj
--321 TJm
-(lik) 10.5209 Tj
-11 TJm
-(e) 4.42357 Tj
--321 TJm
-(on) 9.963 Tj
--320 TJm
-(each) 18.2522 Tj
--321 TJm
-(call) 14.3866 Tj
--320 TJm
-(of) 8.29918 Tj
-[1 0 0 1 407.816 348.217] cm
-0 g
-0 G
-[1 0 0 1 -407.816 -348.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-407.816 348.217 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 503.457 348.217] cm
-0 g
-0 G
-[1 0 0 1 -503.457 -348.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-503.457 348.217 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1043 TJm
-(In) 8.29918 Tj
--320 TJm
-(the) 12.1748 Tj
-72 336.262 Td
-(limit,) 21.3208 Tj
--295 TJm
-(it) 5.53943 Tj
--286 TJm
-(is) 6.64532 Tj
--287 TJm
-(ac) 8.84714 Tj
-1 TJm
-(ceptable) 33.1967 Tj
--287 TJm
-(to) 7.75121 Tj
--286 TJm
-(supply) 26.5713 Tj
--286 TJm
-(and) 14.3866 Tj
--286 TJm
-(remo) 20.474 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--286 TJm
-(data) 16.5984 Tj
--286 TJm
-(one) 14.3866 Tj
--286 TJm
-(byte) 17.1563 Tj
--287 TJm
-(at) 7.19329 Tj
--286 TJm
-(a) 4.42357 Tj
--286 TJm
-(time,) 20.205 Tj
--295 TJm
-(although) 34.8705 Tj
--286 TJm
-(this) 14.3965 Tj
--286 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--287 TJm
-(be) 9.40507 Tj
--286 TJm
-(terribly) 29.3311 Tj
--286 TJm
-(inef) 15.4925 Tj
-25 TJm
-(\002cient.) 27.3983 Tj
--837 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
-72 324.307 Td
-(should) 26.5713 Tj
--250 TJm
-(al) 7.19329 Tj
-10 TJm
-(w) 7.19329 Tj
-10 TJm
-(ays) 13.2807 Tj
--250 TJm
-(ensure) 26.0034 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(at) 7.19329 Tj
--249 TJm
-(least) 18.2622 Tj
--250 TJm
-(one) 14.3866 Tj
--250 TJm
-(byte) 17.1563 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(output) 25.4654 Tj
--250 TJm
-(space) 22.1278 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailable) 26.5614 Tj
--250 TJm
-(at) 7.19329 Tj
--250 TJm
-(each) 18.2522 Tj
--250 TJm
-(call.) 16.8773 Tj
-[1 0 0 1 72 322.15] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -312.187] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 302.389 Td
-/F128_0 9.963 Tf
-(Use) 15.4925 Tj
--250 TJm
-(of) 8.29918 Tj
-[1 0 0 1 100.772 302.389] cm
-0 g
-0 G
-[1 0 0 1 -100.772 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-100.772 302.389 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 196.413 302.389] cm
-0 g
-0 G
-[1 0 0 1 -196.413 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.904 302.389 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(simpler) 29.889 Tj
--250 TJm
-(than) 17.1563 Tj
-[1 0 0 1 260.064 302.389] cm
-0 g
-0 G
-[1 0 0 1 -260.064 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-260.064 302.389 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 343.75 302.389] cm
-0 g
-0 G
-[1 0 0 1 -343.75 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-343.75 302.389 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 300.232] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -290.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 280.471 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--346 TJm
-(should) 26.5713 Tj
--346 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vide) 17.1563 Tj
--346 TJm
-(input) 20.4839 Tj
--347 TJm
-(and) 14.3866 Tj
--346 TJm
-(remo) 20.474 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--346 TJm
-(output) 25.4654 Tj
--346 TJm
-(as) 8.29918 Tj
--346 TJm
-(described) 38.1782 Tj
--346 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e,) 6.91432 Tj
--371 TJm
-(and) 14.3866 Tj
--346 TJm
-(repeatedly) 41.4959 Tj
--346 TJm
-(call) 14.3866 Tj
-[1 0 0 1 422.638 280.471] cm
-0 g
-0 G
-[1 0 0 1 -422.638 -280.471] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.638 280.471 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 518.279 280.471] cm
-0 g
-0 G
-[1 0 0 1 -518.279 -280.471] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-521.729 280.471 Td
-/F128_0 9.963 Tf
-(until) 18.2721 Tj
-[1 0 0 1 72 268.516] cm
-0 g
-0 G
-[1 0 0 1 -72 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 268.516 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 149.709 268.516] cm
-0 g
-0 G
-[1 0 0 1 -149.709 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.314 268.516 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--262 TJm
-(ret) 10.511 Tj
-1 TJm
-(urned.) 25.1765 Tj
--345 TJm
-(Appearance) 47.5733 Tj
--261 TJm
-(of) 8.29918 Tj
-[1 0 0 1 261.767 268.516] cm
-0 g
-0 G
-[1 0 0 1 -261.767 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.767 268.516 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 339.475 268.516] cm
-0 g
-0 G
-[1 0 0 1 -339.475 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-342.081 268.516 Td
-/F128_0 9.963 Tf
-(denotes) 30.437 Tj
--261 TJm
-(that) 14.9445 Tj
-[1 0 0 1 392.672 268.516] cm
-0 g
-0 G
-[1 0 0 1 -392.672 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.672 268.516 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 488.313 268.516] cm
-0 g
-0 G
-[1 0 0 1 -488.313 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-490.919 268.516 Td
-/F128_0 9.963 Tf
-(has) 13.2807 Tj
--261 TJm
-(detected) 33.1967 Tj
-72 256.561 Td
-(the) 12.1748 Tj
--212 TJm
-(logical) 27.1193 Tj
--211 TJm
-(end) 14.3866 Tj
--212 TJm
-(of) 8.29918 Tj
--212 TJm
-(the) 12.1748 Tj
--212 TJm
-(compressed) 47.0353 Tj
--211 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 237.858 256.561] cm
-0 g
-0 G
-[1 0 0 1 -237.858 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.858 256.561 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 333.499 256.561] cm
-0 g
-0 G
-[1 0 0 1 -333.499 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.609 256.561 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--212 TJm
-(not) 12.7327 Tj
--212 TJm
-(pr) 8.29918 Tj
-1 TJm
-(oduce) 23.7916 Tj
-[1 0 0 1 402.263 256.561] cm
-0 g
-0 G
-[1 0 0 1 -402.263 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-402.263 256.561 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 479.972 256.561] cm
-0 g
-0 G
-[1 0 0 1 -479.972 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.082 256.561 Td
-/F128_0 9.963 Tf
-(until) 18.2721 Tj
--212 TJm
-(all) 9.963 Tj
--211 TJm
-(output) 25.4654 Tj
-72 244.605 Td
-(data) 16.5984 Tj
--256 TJm
-(has) 13.2807 Tj
--255 TJm
-(been) 18.8101 Tj
--256 TJm
-(placed) 26.0034 Tj
--256 TJm
-(into) 15.5024 Tj
--256 TJm
-(the) 12.1748 Tj
--255 TJm
-(output) 25.4654 Tj
--256 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-40 TJm
-(,) 2.49075 Tj
--257 TJm
-(so) 8.85711 Tj
--256 TJm
-(once) 18.8101 Tj
-[1 0 0 1 278.979 244.605] cm
-0 g
-0 G
-[1 0 0 1 -278.979 -244.605] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.979 244.605 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 356.687 244.605] cm
-0 g
-0 G
-[1 0 0 1 -356.687 -244.605] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-359.236 244.605 Td
-/F128_0 9.963 Tf
-(appears,) 32.9178 Tj
--257 TJm
-(you) 14.9445 Tj
--256 TJm
-(are) 12.1648 Tj
--256 TJm
-(guaran) 27.1093 Tj
-1 TJm
-(teed) 16.5984 Tj
--256 TJm
-(to) 7.75121 Tj
--256 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--256 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailable) 26.5614 Tj
-72 232.65 Td
-(all) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(decompressed) 56.4404 Tj
--250 TJm
-(output,) 27.9562 Tj
--249 TJm
-(and) 14.3866 Tj
-[1 0 0 1 205.369 232.65] cm
-0 g
-0 G
-[1 0 0 1 -205.369 -232.65] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-205.369 232.65 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressEnd) 113.578 Tj
-[1 0 0 1 318.943 232.65] cm
-0 g
-0 G
-[1 0 0 1 -318.943 -232.65] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-321.433 232.65 Td
-/F128_0 9.963 Tf
-(can) 13.8286 Tj
--250 TJm
-(safely) 23.7916 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(called.) 26.2824 Tj
-[1 0 0 1 72 230.493] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -220.531] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 210.732 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--250 TJm
-(case) 17.1463 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(an) 9.40507 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
-1 TJm
-(,) 2.49075 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(call) 14.3866 Tj
-[1 0 0 1 261.259 210.732] cm
-0 g
-0 G
-[1 0 0 1 -261.259 -210.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.259 210.732 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressEnd) 113.578 Tj
-[1 0 0 1 374.833 210.732] cm
-0 g
-0 G
-[1 0 0 1 -374.833 -210.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-377.323 210.732 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(clean) 21.0219 Tj
--250 TJm
-(up) 9.963 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(release) 27.6573 Tj
--250 TJm
-(memor) 28.2252 Tj
-1 TJm
-(y) 4.9815 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 208.576] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -198.613] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 188.815 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 188.715] cm
-0 g
-0 G
-[1 0 0 1 0 -137.863] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(17) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 21 21
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -200.882] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 179.328 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 175.741] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 699.676 Td
-(if) 11.9556 Tj
--426 TJm
-(strm) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(strm-) 29.889 Tj
-1 TJm
-(>s) 11.9556 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-98.488 687.721 Td
-(or) 11.9556 Tj
--426 TJm
-(strm->avail_out) 89.667 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(1) 5.9778 Tj
-90 675.766 Td
-(BZ_DATA_ERROR) 77.7114 Tj
-98.488 663.811 Td
-(if) 11.9556 Tj
--426 TJm
-(a) 5.9778 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(integrity) 53.8002 Tj
--426 TJm
-(erro) 23.9112 Tj
-1 TJm
-(r) 5.9778 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(detected) 47.8224 Tj
--426 TJm
-(in) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(stream) 35.8668 Tj
-90 651.856 Td
-(BZ_DATA_ERROR_MAGIC) 113.578 Tj
-98.488 639.9 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(stream) 35.8668 Tj
--425 TJm
-(doesn't) 41.8446 Tj
--426 TJm
-(begin) 29.889 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(right) 29.889 Tj
--426 TJm
-(magic) 29.889 Tj
--426 TJm
-(bytes) 29.889 Tj
-90 627.945 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 615.99 Td
-(if) 11.9556 Tj
--426 TJm
-(there) 29.889 Tj
--426 TJm
-(wasn't) 35.8668 Tj
--426 TJm
-(enough) 35.8668 Tj
--426 TJm
-(m) 5.9778 Tj
-1 TJm
-(emory) 29.889 Tj
--426 TJm
-(available) 53.8002 Tj
-90 604.035 Td
-(BZ_STREAM_END) 77.7114 Tj
-98.488 592.08 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(logical) 41.8446 Tj
--426 TJm
-(end) 17.9334 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(th) 11.9556 Tj
-1 TJm
-(e) 5.9778 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(stream) 35.8668 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(detected) 47.8224 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(all) 17.9334 Tj
-98.488 580.124 Td
-(output) 35.8668 Tj
--426 TJm
-(in) 11.9556 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--426 TJm
-(consu) 29.889 Tj
-1 TJm
-(med,) 23.9112 Tj
--426 TJm
-(eg) 11.9556 Tj
--426 TJm
-(s-->avail_out) 77.7114 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
-90 568.169 Td
-(BZ_OK) 29.889 Tj
-98.488 556.214 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 540.672] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 518.755 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 518.655] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 56.189] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -509.29] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 509.29 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-98.488 497.335 Td
-(if) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(returned) 47.8224 Tj
-90 485.38 Td
-(BZ2_bzDecompressEnd) 113.578 Tj
-98.488 473.425 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 457.883] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -447.92] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 427.262 Td
-/F121_0 17.215 Tf
-(3.3.6.) 43.0719 Tj
-[1 0 0 1 119.858 427.262] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -427.262] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 427.262 Td
-/F387_0 17.215 Tf
-(BZ2_bzDecompressEnd) 196.251 Tj
-[1 0 0 1 316.114 427.262] cm
-0 g
-0 G
-[1 0 0 1 -244.114 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.906] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -415.564] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 415.564 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzDecompressEnd) 113.578 Tj
--426 TJm
-(\() 5.9778 Tj
--425 TJm
-(bz_stream) 53.8002 Tj
--426 TJm
-(*strm) 29.889 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 400.023] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -390.06] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 378.105 Td
-/F128_0 9.963 Tf
-(Releases) 34.8605 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(memory) 33.2067 Tj
--250 TJm
-(assoc) 21.5799 Tj
-1 TJm
-(iated) 19.3681 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(decompression) 59.768 Tj
--250 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 72 375.948] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -365.985] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 356.187 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 356.087] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 56.189] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -346.723] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 346.723 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 334.767 Td
-(if) 11.9556 Tj
--426 TJm
-(strm) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(strm-) 29.889 Tj
-1 TJm
-(>s) 11.9556 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-90 322.812 Td
-(BZ_OK) 29.889 Tj
-98.488 310.857 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 295.315] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -285.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 273.398 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 273.298] cm
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -263.933] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-98.488 263.933 Td
-/F130_0 9.963 Tf
-(None.) 29.889 Tj
-[1 0 0 1 72 248.391] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -238.429] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 213.639 Td
-/F121_0 20.659 Tf
-(3.4.) 34.4592 Tj
--278 TJm
-(High-le) 70.0134 Tj
-15 TJm
-(vel) 28.716 Tj
--278 TJm
-(interface) 86.1067 Tj
-[1 0 0 1 72 209.042] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -199.08] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 191.721 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
--250 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vides) 21.0319 Tj
--250 TJm
-(funct) 20.474 Tj
-1 TJm
-(ions) 16.6083 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(reading) 29.879 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(writing) 28.7831 Tj
-[1 0 0 1 300.292 191.721] cm
-0 g
-0 G
-[1 0 0 1 -300.292 -191.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.292 191.721 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 330.18 191.721] cm
-0 g
-0 G
-[1 0 0 1 -330.18 -191.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.67 191.721 Td
-/F128_0 9.963 Tf
-(format) 26.5614 Tj
--250 TJm
-(\002les.) 19.0991 Tj
--620 TJm
-(First,) 20.7629 Tj
--250 TJm
-(some) 21.0319 Tj
--250 TJm
-(gen) 14.3866 Tj
-1 TJm
-(eral) 14.9345 Tj
--250 TJm
-(points.) 26.8503 Tj
-[1 0 0 1 72 189.564] cm
-0 g
-0 G
-[1 0 0 1 0 -29.724] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 159.84 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 159.84] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 159.84 Td
-/F128_0 9.963 Tf
-(All) 12.7327 Tj
--332 TJm
-(of) 8.29918 Tj
--331 TJm
-(the) 12.1748 Tj
--332 TJm
-(functions) 37.0823 Tj
--331 TJm
-(tak) 12.1748 Tj
-10 TJm
-(e) 4.42357 Tj
--332 TJm
-(an) 9.40507 Tj
-[1 0 0 1 202.958 159.84] cm
-0 g
-0 G
-[1 0 0 1 -202.958 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-202.958 159.84 Td
-/F130_0 9.963 Tf
-(int*) 23.9112 Tj
-[1 0 0 1 226.868 159.84] cm
-0 g
-0 G
-[1 0 0 1 -226.868 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.172 159.84 Td
-/F128_0 9.963 Tf
-(\002rst) 15.5024 Tj
--332 TJm
-(ar) 7.74125 Tj
-18 TJm
-(gume) 22.1378 Tj
-1 TJm
-(nt,) 10.242 Tj
-[1 0 0 1 292.426 159.84] cm
-0 g
-0 G
-[1 0 0 1 -292.426 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.426 159.84 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 334.269 159.84] cm
-0 g
-0 G
-[1 0 0 1 -334.269 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-334.269 159.84 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1110 TJm
-(After) 21.0219 Tj
--331 TJm
-(each) 18.2522 Tj
--332 TJm
-(call,) 16.8773 Tj
-[1 0 0 1 414.083 159.84] cm
-0 g
-0 G
-[1 0 0 1 -414.083 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.083 159.84 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 455.926 159.84] cm
-0 g
-0 G
-[1 0 0 1 -455.926 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-459.23 159.84 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--332 TJm
-(be) 9.40507 Tj
--331 TJm
-(consulted) 38.1882 Tj
-86.944 147.885 Td
-(\002rst) 15.5024 Tj
--349 TJm
-(to) 7.75121 Tj
--348 TJm
-(determine) 39.842 Tj
--349 TJm
-(the) 12.1748 Tj
--349 TJm
-(outcome) 34.3126 Tj
--348 TJm
-(of) 8.29918 Tj
--349 TJm
-(the) 12.1748 Tj
--349 TJm
-(call.) 16.8773 Tj
--1212 TJm
-(If) 6.63536 Tj
-[1 0 0 1 280.386 147.885] cm
-0 g
-0 G
-[1 0 0 1 -280.386 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-280.386 147.885 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 322.229 147.885] cm
-0 g
-0 G
-[1 0 0 1 -322.229 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-325.704 147.885 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
-[1 0 0 1 335.823 147.885] cm
-0 g
-0 G
-[1 0 0 1 -335.823 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.823 147.885 Td
-/F130_0 9.963 Tf
-(BZ_OK) 29.889 Tj
-[1 0 0 1 365.711 147.885] cm
-0 g
-0 G
-[1 0 0 1 -365.711 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-365.711 147.885 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--349 TJm
-(the) 12.1748 Tj
--349 TJm
-(c) 4.42357 Tj
-1 TJm
-(all) 9.963 Tj
--349 TJm
-(completed) 41.5059 Tj
--349 TJm
-(successfully) 48.6991 Tj
-65 TJm
-(,) 2.49075 Tj
--373 TJm
-(and) 14.3866 Tj
--349 TJm
-(only) 17.7142 Tj
-86.944 135.93 Td
-(then) 17.1563 Tj
--271 TJm
-(s) 3.87561 Tj
-1 TJm
-(hould) 22.6957 Tj
--271 TJm
-(the) 12.1748 Tj
--271 TJm
-(re) 7.74125 Tj
-1 TJm
-(turn) 16.0504 Tj
--271 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--271 TJm
-(o) 4.9815 Tj
-1 TJm
-(f) 3.31768 Tj
--271 TJm
-(the) 12.1748 Tj
--271 TJm
-(functi) 23.2437 Tj
-1 TJm
-(on) 9.963 Tj
--271 TJm
-(\(if) 9.40507 Tj
--271 TJm
-(an) 9.40507 Tj
-15 TJm
-(y\)) 8.29918 Tj
--270 TJm
-(be) 9.40507 Tj
--271 TJm
-(consulted.) 40.6789 Tj
--743 TJm
-(If) 6.63536 Tj
-[1 0 0 1 365.077 135.93] cm
-0 g
-0 G
-[1 0 0 1 -365.077 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-365.077 135.93 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 406.92 135.93] cm
-0 g
-0 G
-[1 0 0 1 -406.92 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-409.616 135.93 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
-[1 0 0 1 418.956 135.93] cm
-0 g
-0 G
-[1 0 0 1 -418.956 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-418.956 135.93 Td
-/F130_0 9.963 Tf
-(BZ_IO_ERROR) 65.7558 Tj
-[1 0 0 1 484.71 135.93] cm
-0 g
-0 G
-[1 0 0 1 -484.71 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-484.71 135.93 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--271 TJm
-(ther) 15.4925 Tj
-1 TJm
-(e) 4.42357 Tj
--271 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--271 TJm
-(an) 9.40507 Tj
-86.944 123.975 Td
-(error) 19.3581 Tj
--246 TJm
-(read) 17.1463 Tj
-1 TJm
-(ing/writing) 44.2855 Tj
--246 TJm
-(the) 12.1748 Tj
--246 TJm
-(und) 14.9445 Tj
-1 TJm
-(erlying) 28.2252 Tj
--246 TJm
-(compressed) 47.0353 Tj
--245 TJm
-(\002le,) 15.2235 Tj
--247 TJm
-(and) 14.3866 Tj
--246 TJm
-(you) 14.9445 Tj
--245 TJm
-(should) 26.5713 Tj
--246 TJm
-(then) 17.1563 Tj
--245 TJm
-(consult) 28.7831 Tj
-[1 0 0 1 414.096 123.975] cm
-0 g
-0 G
-[1 0 0 1 -414.096 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.096 123.975 Td
-/F130_0 9.963 Tf
-(errno) 29.889 Tj
-[1 0 0 1 443.984 123.975] cm
-0 g
-0 G
-[1 0 0 1 -443.984 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.432 123.975 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 451.649 123.975] cm
-0 g
-0 G
-[1 0 0 1 -451.649 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-451.649 123.975 Td
-/F130_0 9.963 Tf
-(perror) 35.8668 Tj
-[1 0 0 1 487.514 123.975] cm
-0 g
-0 G
-[1 0 0 1 -487.514 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-489.962 123.975 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--246 TJm
-(deter) 19.916 Tj
-1 TJm
-(mine) 19.926 Tj
-86.944 112.02 Td
-(the) 12.1748 Tj
--356 TJm
-(cause) 22.1278 Tj
--355 TJm
-(of) 8.29918 Tj
--356 TJm
-(the) 12.1748 Tj
--356 TJm
-(dif) 11.0689 Tj
-25 TJm
-(\002culty) 25.4654 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 206.528 112.02] cm
-0 g
-0 G
-[1 0 0 1 -206.528 -112.02] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-206.528 112.02 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 248.371 112.02] cm
-0 g
-0 G
-[1 0 0 1 -248.371 -112.02] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-251.916 112.02 Td
-/F128_0 9.963 Tf
-(may) 17.1563 Tj
--356 TJm
-(also) 16.0504 Tj
--355 TJm
-(be) 9.40507 Tj
--356 TJm
-(set) 11.0689 Tj
--356 TJm
-(to) 7.75121 Tj
--356 TJm
-(v) 4.9815 Tj
-25 TJm
-(arious) 24.3496 Tj
--355 TJm
-(other) 20.474 Tj
--356 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues;) 23.2437 Tj
--409 TJm
-(precise) 28.2152 Tj
--356 TJm
-(d) 4.9815 Tj
-1 TJm
-(etails) 21.0319 Tj
--356 TJm
-(are) 12.1648 Tj
--356 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--356 TJm
-(on) 9.963 Tj
--355 TJm
-(a) 4.42357 Tj
-86.944 100.064 Td
-(per) 12.7228 Tj
-20 TJm
-(-function) 36.5244 Tj
--250 TJm
-(basis) 19.926 Tj
--250 TJm
-(belo) 17.1563 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 186.838 100.064] cm
-0 g
-0 G
-[1 0 0 1 -114.838 -49.212] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(18) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 22 22
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -31.517] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 710.037 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 710.037] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 710.037 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
-[1 0 0 1 95.958 710.037] cm
-0 g
-0 G
-[1 0 0 1 -95.958 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.958 710.037 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 137.801 710.037] cm
-0 g
-0 G
-[1 0 0 1 -137.801 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.179 710.037 Td
-/F128_0 9.963 Tf
-(indicates) 35.4185 Tj
--239 TJm
-(an) 9.40507 Tj
--238 TJm
-(error) 19.3581 Tj
--239 TJm
-(\(ie,) 13.0017 Tj
--241 TJm
-(an) 9.40507 Tj
-15 TJm
-(ything) 25.4654 Tj
--239 TJm
-(e) 4.42357 Tj
-15 TJm
-(x) 4.9815 Tj
-1 TJm
-(cept) 16.5984 Tj
-[1 0 0 1 292.225 710.037] cm
-0 g
-0 G
-[1 0 0 1 -292.225 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.225 710.037 Td
-/F130_0 9.963 Tf
-(BZ_OK) 29.889 Tj
-[1 0 0 1 322.113 710.037] cm
-0 g
-0 G
-[1 0 0 1 -322.113 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-324.492 710.037 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 341.257 710.037] cm
-0 g
-0 G
-[1 0 0 1 -341.257 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.257 710.037 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 418.965 710.037] cm
-0 g
-0 G
-[1 0 0 1 -418.965 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-418.965 710.037 Td
-/F128_0 9.963 Tf
-(\),) 5.80843 Tj
--239 TJm
-(you) 14.9445 Tj
--238 TJm
-(should) 26.5713 Tj
--239 TJm
-(immediately) 49.815 Tj
--239 TJm
-(cal) 11.6169 Tj
-1 TJm
-(l) 2.76971 Tj
-[1 0 0 1 86.944 698.082] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 698.082 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 176.608 698.082] cm
-0 g
-0 G
-[1 0 0 1 -176.608 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.343 698.082 Td
-/F128_0 9.963 Tf
-(\(or) 11.6169 Tj
-[1 0 0 1 193.695 698.082] cm
-0 g
-0 G
-[1 0 0 1 -193.695 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.695 698.082 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteClose) 95.6448 Tj
-[1 0 0 1 289.337 698.082] cm
-0 g
-0 G
-[1 0 0 1 -289.337 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.337 698.082 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--281 TJm
-(depending) 41.5059 Tj
--274 TJm
-(on) 9.963 Tj
--275 TJm
-(whethe) 28.7731 Tj
-1 TJm
-(r) 3.31768 Tj
--275 TJm
-(you) 14.9445 Tj
--275 TJm
-(are) 12.1648 Tj
--274 TJm
-(attempting) 42.6217 Tj
--274 TJm
-(to) 7.75121 Tj
--275 TJm
-(read) 17.1463 Tj
--274 TJm
-(or) 8.29918 Tj
--275 TJm
-(to) 7.75121 Tj
--275 TJm
-(writ) 16.0504 Tj
-1 TJm
-(e\)) 7.74125 Tj
-86.944 686.127 Td
-(to) 7.75121 Tj
--242 TJm
-(free) 15.4825 Tj
--241 TJm
-(up) 9.963 Tj
--242 TJm
-(all) 9.963 Tj
--242 TJm
-(resources) 37.6203 Tj
--241 TJm
-(associated) 40.9479 Tj
--242 TJm
-(with) 17.7142 Tj
--242 TJm
-(the) 12.1748 Tj
--241 TJm
-(stream.) 29.0521 Tj
--615 TJm
-(Once) 21.0219 Tj
--241 TJm
-(an) 9.40507 Tj
--242 TJm
-(error) 19.3581 Tj
--242 TJm
-(has) 13.2807 Tj
--241 TJm
-(been) 18.8101 Tj
--242 TJm
-(indicated,) 39.0151 Tj
--243 TJm
-(beha) 18.8101 Tj
-20 TJm
-(viour) 21.0319 Tj
--242 TJm
-(of) 8.29918 Tj
--242 TJm
-(all) 9.963 Tj
--241 TJm
-(calls) 18.2622 Tj
--242 TJm
-(e) 4.42357 Tj
-15 TJm
-(xcept) 21.5799 Tj
-[1 0 0 1 86.944 674.172] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 674.172 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 176.608 674.172] cm
-0 g
-0 G
-[1 0 0 1 -176.608 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.705 674.172 Td
-/F128_0 9.963 Tf
-(\() 3.31768 Tj
-[1 0 0 1 183.022 674.172] cm
-0 g
-0 G
-[1 0 0 1 -183.022 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.022 674.172 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteClose) 95.6448 Tj
-[1 0 0 1 278.664 674.172] cm
-0 g
-0 G
-[1 0 0 1 -278.664 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.664 674.172 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--311 TJm
-(is) 6.64532 Tj
--311 TJm
-(unde\002) 24.9075 Tj
-1 TJm
-(ned.) 16.8773 Tj
--986 TJm
-(Th) 11.0689 Tj
-1 TJm
-(e) 4.42357 Tj
--311 TJm
-(implication) 45.3914 Tj
--311 TJm
-(is) 6.64532 Tj
--311 TJm
-(that) 14.9445 Tj
--311 TJm
-(\(1) 8.29918 Tj
-1 TJm
-(\)) 3.31768 Tj
-[1 0 0 1 455.988 674.172] cm
-0 g
-0 G
-[1 0 0 1 -455.988 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-455.988 674.172 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 497.831 674.172] cm
-0 g
-0 G
-[1 0 0 1 -497.831 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-500.928 674.172 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--311 TJm
-(be) 9.40507 Tj
-86.944 662.217 Td
-(check) 23.2337 Tj
-10 TJm
-(ed) 9.40507 Tj
--291 TJm
-(after) 18.2522 Tj
--291 TJm
-(each) 18.2522 Tj
--291 TJm
-(call,) 16.8773 Tj
--301 TJm
-(and) 14.3866 Tj
--291 TJm
-(\(2\)) 11.6169 Tj
--291 TJm
-(if) 6.08739 Tj
-[1 0 0 1 225.347 662.217] cm
-0 g
-0 G
-[1 0 0 1 -225.347 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-225.347 662.217 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 267.19 662.217] cm
-0 g
-0 G
-[1 0 0 1 -267.19 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-270.09 662.217 Td
-/F128_0 9.963 Tf
-(indicates) 35.4185 Tj
--291 TJm
-(an) 9.40507 Tj
--291 TJm
-(error) 19.3581 Tj
-40 TJm
-(,) 2.49075 Tj
-[1 0 0 1 345.161 662.217] cm
-0 g
-0 G
-[1 0 0 1 -345.161 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-345.161 662.217 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 434.824 662.217] cm
-0 g
-0 G
-[1 0 0 1 -434.824 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-437.724 662.217 Td
-/F128_0 9.963 Tf
-(\() 3.31768 Tj
-[1 0 0 1 441.041 662.217] cm
-0 g
-0 G
-[1 0 0 1 -441.041 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.041 662.217 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteClose) 95.6448 Tj
-[1 0 0 1 536.682 662.217] cm
-0 g
-0 G
-[1 0 0 1 -536.682 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-536.682 662.217 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
-86.944 650.262 Td
-(should) 26.5713 Tj
--250 TJm
-(then) 17.1563 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(called) 23.7916 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(clea) 16.0404 Tj
-1 TJm
-(n) 4.9815 Tj
--250 TJm
-(up.) 12.4538 Tj
-[1 0 0 1 220.034 650.262] cm
-0 g
-0 G
-[1 0 0 1 -148.034 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 628.344 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 628.344] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 628.344 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
-[1 0 0 1 106.362 628.344] cm
-0 g
-0 G
-[1 0 0 1 -106.362 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-106.362 628.344 Td
-/F130_0 9.963 Tf
-(FILE*) 29.889 Tj
-[1 0 0 1 136.25 628.344] cm
-0 g
-0 G
-[1 0 0 1 -136.25 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.177 628.344 Td
-/F128_0 9.963 Tf
-(ar) 7.74125 Tj
-18 TJm
-(guments) 33.7646 Tj
--394 TJm
-(passed) 26.5614 Tj
--394 TJm
-(to) 7.75121 Tj
-[1 0 0 1 227.592 628.344] cm
-0 g
-0 G
-[1 0 0 1 -227.592 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-227.592 628.344 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadOpen) 83.6892 Tj
-[1 0 0 1 311.278 628.344] cm
-0 g
-0 G
-[1 0 0 1 -311.278 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.205 628.344 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 321.901 628.344] cm
-0 g
-0 G
-[1 0 0 1 -321.901 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-321.901 628.344 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteOpen) 89.667 Tj
-[1 0 0 1 411.565 628.344] cm
-0 g
-0 G
-[1 0 0 1 -411.565 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-415.491 628.344 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--394 TJm
-(be) 9.40507 Tj
--394 TJm
-(set) 11.0689 Tj
--394 TJm
-(to) 7.75121 Tj
--394 TJm
-(binary) 25.4555 Tj
--394 TJm
-(mode.) 24.6285 Tj
-86.944 616.389 Td
-(Most) 20.4839 Tj
--229 TJm
-(Unix) 19.926 Tj
--229 TJm
-(s) 3.87561 Tj
-1 TJm
-(ystems) 27.6772 Tj
--229 TJm
-(will) 15.5024 Tj
--229 TJm
-(do) 9.963 Tj
--229 TJm
-(this) 14.3965 Tj
--229 TJm
-(by) 9.963 Tj
--228 TJm
-(def) 12.7228 Tj
-10 TJm
-(ault,) 17.4353 Tj
--233 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--229 TJm
-(other) 20.474 Tj
--229 TJm
-(platforms,) 40.6789 Tj
--233 TJm
-(including) 37.6402 Tj
--228 TJm
-(W) 9.40507 Tj
-40 TJm
-(indo) 17.7142 Tj
-25 TJm
-(ws) 11.0689 Tj
--229 TJm
-(and) 14.3866 Tj
--229 TJm
-(Mac,) 20.195 Tj
--233 TJm
-(will) 15.5024 Tj
--229 TJm
-(not.) 15.2235 Tj
--605 TJm
-(If) 6.63536 Tj
--229 TJm
-(you) 14.9445 Tj
--229 TJm
-(omit) 18.2721 Tj
-86.944 604.433 Td
-(this,) 16.8873 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(may) 17.1563 Tj
--250 TJm
-(encounter) 39.2841 Tj
--250 TJm
-(probl) 21.0319 Tj
-1 TJm
-(ems) 16.0504 Tj
--250 TJm
-(when) 21.5799 Tj
--250 TJm
-(mo) 12.7327 Tj
-15 TJm
-(ving) 17.7142 Tj
--250 TJm
-(code) 18.8101 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(ne) 9.40507 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(platforms.) 40.6789 Tj
-[1 0 0 1 372.66 604.433] cm
-0 g
-0 G
-[1 0 0 1 -300.66 -21.917] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 582.516 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 582.516] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 582.516 Td
-/F128_0 9.963 Tf
-(Memory) 34.3126 Tj
--348 TJm
-(allocation) 39.2941 Tj
--348 TJm
-(requests) 32.6488 Tj
--348 TJm
-(are) 12.1648 Tj
--348 TJm
-(handled) 31.5429 Tj
--348 TJm
-(by) 9.963 Tj
-[1 0 0 1 267.67 582.516] cm
-0 g
-0 G
-[1 0 0 1 -267.67 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-267.67 582.516 Td
-/F130_0 9.963 Tf
-(malloc) 35.8668 Tj
-[1 0 0 1 303.535 582.516] cm
-0 g
-0 G
-[1 0 0 1 -303.535 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-307.003 582.516 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 313.241 582.516] cm
-0 g
-0 G
-[1 0 0 1 -313.241 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-313.241 582.516 Td
-/F130_0 9.963 Tf
-(free) 23.9112 Tj
-[1 0 0 1 337.151 582.516] cm
-0 g
-0 G
-[1 0 0 1 -337.151 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-337.151 582.516 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1208 TJm
-(At) 9.963 Tj
--349 TJm
-(pr) 8.29918 Tj
-1 TJm
-(esent) 20.474 Tj
--348 TJm
-(there) 19.916 Tj
--348 TJm
-(is) 6.64532 Tj
--348 TJm
-(no) 9.963 Tj
--349 TJm
-(f) 3.31768 Tj
-10 TJm
-(a) 4.42357 Tj
-1 TJm
-(cility) 20.4839 Tj
--348 TJm
-(for) 11.6169 Tj
--348 TJm
-(user) 16.5984 Tj
-20 TJm
-(-de\002ned) 32.6488 Tj
-86.944 570.56 Td
-(memory) 33.2067 Tj
--250 TJm
-(allocators) 38.7361 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\002l) 8.30914 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(I/O) 13.2807 Tj
--250 TJm
-(functions) 37.0823 Tj
--250 TJm
-(\(could) 25.4555 Tj
--250 TJm
-(easily) 23.2437 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(added,) 26.2824 Tj
--250 TJm
-(though\).) 33.4856 Tj
-[1 0 0 1 387.165 570.56] cm
-0 g
-0 G
-[1 0 0 1 -315.165 -12.119] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -548.478] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 529.977 Td
-/F121_0 17.215 Tf
-(3.4.1.) 43.0719 Tj
-[1 0 0 1 119.858 529.977] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -529.977] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 529.977 Td
-/F387_0 17.215 Tf
-(BZ2_bzReadOpen) 144.606 Tj
-[1 0 0 1 264.468 529.977] cm
-0 g
-0 G
-[1 0 0 1 -192.468 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -72.727] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 71.731 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 68.145] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -518.279] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 518.279 Td
-/F130_0 9.963 Tf
-(typedef) 41.8446 Tj
--426 TJm
-(void) 23.9112 Tj
--426 TJm
-(BZFILE;) 41.8446 Tj
-90 494.369 Td
-(BZFILE) 35.8668 Tj
--426 TJm
-(*BZ2_bzReadOpen\() 95.6448 Tj
--426 TJm
-(i) 5.9778 Tj
-1 TJm
-(nt) 11.9556 Tj
--426 TJm
-(*bzerror,) 53.8002 Tj
--426 TJm
-(FILE) 23.9112 Tj
--426 TJm
-(*f,) 17.9334 Tj
-191.855 482.414 Td
-(int) 17.9334 Tj
--426 TJm
-(verbosity,) 59.778 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(small,) 35.8668 Tj
-191.855 470.458 Td
-(void) 23.9112 Tj
--426 TJm
-(*unused,) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(nUnused) 41.8446 Tj
--425 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 454.917] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -444.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 432.999 Td
-/F128_0 9.963 Tf
-(Prepare) 30.427 Tj
--290 TJm
-(t) 2.76971 Tj
-1 TJm
-(o) 4.9815 Tj
--290 TJm
-(read) 17.1463 Tj
--290 TJm
-(compresse) 42.0538 Tj
-1 TJm
-(d) 4.9815 Tj
--290 TJm
-(data) 16.5984 Tj
--290 TJm
-(from) 19.3681 Tj
--289 TJm
-(\002le) 12.7327 Tj
--290 TJm
-(handle) 26.5614 Tj
-[1 0 0 1 272.697 432.999] cm
-0 g
-0 G
-[1 0 0 1 -272.697 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.697 432.999 Td
-/F130_0 9.963 Tf
-(f) 5.9778 Tj
-[1 0 0 1 278.675 432.999] cm
-0 g
-0 G
-[1 0 0 1 -278.675 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.675 432.999 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 285.439 432.999] cm
-0 g
-0 G
-[1 0 0 1 -285.439 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-285.439 432.999 Td
-/F130_0 9.963 Tf
-(f) 5.9778 Tj
-[1 0 0 1 291.417 432.999] cm
-0 g
-0 G
-[1 0 0 1 -291.417 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.302 432.999 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--290 TJm
-(refer) 18.8002 Tj
--289 TJm
-(to) 7.75121 Tj
--290 TJm
-(a) 4.42357 Tj
--289 TJm
-(\002le) 12.7327 Tj
--290 TJm
-(which) 24.3496 Tj
--289 TJm
-(has) 13.2807 Tj
--290 TJm
-(been) 18.8101 Tj
--290 TJm
-(opened) 28.7731 Tj
--289 TJm
-(for) 11.6169 Tj
--290 TJm
-(reading,) 32.3698 Tj
--299 TJm
-(and) 14.3866 Tj
-72 421.044 Td
-(for) 11.6169 Tj
--306 TJm
-(which) 24.3496 Tj
--305 TJm
-(the) 12.1748 Tj
--306 TJm
-(error) 19.3581 Tj
--305 TJm
-(indicator) 35.4185 Tj
--306 TJm
-(\() 3.31768 Tj
-[1 0 0 1 193.457 421.044] cm
-0 g
-0 G
-[1 0 0 1 -193.457 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.457 421.044 Td
-/F130_0 9.963 Tf
-(ferror\(f\)) 53.8002 Tj
-[1 0 0 1 247.255 421.044] cm
-0 g
-0 G
-[1 0 0 1 -247.255 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-247.255 421.044 Td
-/F128_0 9.963 Tf
-(\)is) 9.963 Tj
--306 TJm
-(not) 12.7327 Tj
--305 TJm
-(set.) 13.5596 Tj
--954 TJm
-(If) 6.63536 Tj
-[1 0 0 1 308.784 421.044] cm
-0 g
-0 G
-[1 0 0 1 -308.784 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.784 421.044 Td
-/F130_0 9.963 Tf
-(small) 29.889 Tj
-[1 0 0 1 338.672 421.044] cm
-0 g
-0 G
-[1 0 0 1 -338.672 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.717 421.044 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--306 TJm
-(1,) 7.47225 Tj
--319 TJm
-(the) 12.1748 Tj
--306 TJm
-(library) 26.5614 Tj
--305 TJm
-(will) 15.5024 Tj
--306 TJm
-(try) 11.0689 Tj
--305 TJm
-(to) 7.75121 Tj
--306 TJm
-(decompress) 47.0353 Tj
--306 TJm
-(us) 8.85711 Tj
-1 TJm
-(ing) 12.7327 Tj
--306 TJm
-(less) 14.9445 Tj
-72 409.089 Td
-(memory) 33.2067 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(at) 7.19329 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(e) 4.42357 Tj
-15 TJm
-(xpense) 27.6673 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(spee) 17.7043 Tj
-1 TJm
-(d.) 7.47225 Tj
-[1 0 0 1 72 406.932] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -396.969] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 387.171 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--227 TJm
-(reasons) 29.879 Tj
--227 TJm
-(e) 4.42357 Tj
-15 TJm
-(xplained) 34.3126 Tj
--227 TJm
-(belo) 17.1563 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 189.193 387.171] cm
-0 g
-0 G
-[1 0 0 1 -189.193 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.193 387.171 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 248.969 387.171] cm
-0 g
-0 G
-[1 0 0 1 -248.969 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-251.232 387.171 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--227 TJm
-(decompress) 47.0353 Tj
--227 TJm
-(the) 12.1748 Tj
-[1 0 0 1 332.732 387.171] cm
-0 g
-0 G
-[1 0 0 1 -332.732 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.732 387.171 Td
-/F130_0 9.963 Tf
-(nUnused) 41.8446 Tj
-[1 0 0 1 374.575 387.171] cm
-0 g
-0 G
-[1 0 0 1 -374.575 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-376.838 387.171 Td
-/F128_0 9.963 Tf
-(bytes) 21.0319 Tj
--227 TJm
-(starting) 29.889 Tj
--227 TJm
-(at) 7.19329 Tj
-[1 0 0 1 441.74 387.171] cm
-0 g
-0 G
-[1 0 0 1 -441.74 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.74 387.171 Td
-/F130_0 9.963 Tf
-(unused) 35.8668 Tj
-[1 0 0 1 477.605 387.171] cm
-0 g
-0 G
-[1 0 0 1 -477.605 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.605 387.171 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--232 TJm
-(before) 25.4455 Tj
--227 TJm
-(starting) 29.889 Tj
-72 375.216 Td
-(to) 7.75121 Tj
--279 TJm
-(read) 17.1463 Tj
--280 TJm
-(from) 19.3681 Tj
--279 TJm
-(the) 12.1748 Tj
--280 TJm
-(\002le) 12.7327 Tj
-[1 0 0 1 155.094 375.216] cm
-0 g
-0 G
-[1 0 0 1 -155.094 -375.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.094 375.216 Td
-/F130_0 9.963 Tf
-(f) 5.9778 Tj
-[1 0 0 1 161.072 375.216] cm
-0 g
-0 G
-[1 0 0 1 -161.072 -375.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.072 375.216 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--797 TJm
-(At) 9.963 Tj
--280 TJm
-(most) 19.378 Tj
-[1 0 0 1 206.414 375.216] cm
-0 g
-0 G
-[1 0 0 1 -206.414 -375.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-206.414 375.216 Td
-/F130_0 9.963 Tf
-(BZ_MAX_UNUSED) 77.7114 Tj
-[1 0 0 1 284.122 375.216] cm
-0 g
-0 G
-[1 0 0 1 -284.122 -375.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-286.907 375.216 Td
-/F128_0 9.963 Tf
-(bytes) 21.0319 Tj
--279 TJm
-(may) 17.1563 Tj
--280 TJm
-(be) 9.40507 Tj
--279 TJm
-(supplied) 33.7646 Tj
--280 TJm
-(lik) 10.5209 Tj
-10 TJm
-(e) 4.42357 Tj
--279 TJm
-(this.) 16.8873 Tj
--797 TJm
-(If) 6.63536 Tj
--280 TJm
-(this) 14.3965 Tj
--279 TJm
-(f) 3.31768 Tj
-10 TJm
-(acility) 24.9075 Tj
--280 TJm
-(is) 6.64532 Tj
--279 TJm
-(not) 12.7327 Tj
--280 TJm
-(re) 7.74125 Tj
-1 TJm
-(quired,) 27.9462 Tj
-72 363.26 Td
-(you) 14.9445 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(pass) 17.1563 Tj
-[1 0 0 1 138.141 363.26] cm
-0 g
-0 G
-[1 0 0 1 -138.141 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.141 363.26 Td
-/F130_0 9.963 Tf
-(NULL) 23.9112 Tj
-[1 0 0 1 162.052 363.26] cm
-0 g
-0 G
-[1 0 0 1 -162.052 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.542 363.26 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 181.419 363.26] cm
-0 g
-0 G
-[1 0 0 1 -181.419 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.419 363.26 Td
-/F130_0 9.963 Tf
-(0) 5.9778 Tj
-[1 0 0 1 187.397 363.26] cm
-0 g
-0 G
-[1 0 0 1 -187.397 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.887 363.26 Td
-/F128_0 9.963 Tf
-(for) 11.6169 Tj
-[1 0 0 1 203.994 363.26] cm
-0 g
-0 G
-[1 0 0 1 -203.994 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.994 363.26 Td
-/F130_0 9.963 Tf
-(unused) 35.8668 Tj
-[1 0 0 1 239.86 363.26] cm
-0 g
-0 G
-[1 0 0 1 -239.86 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-242.351 363.26 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
--250 TJm
-(n) 4.9815 Tj
-[1 0 0 1 264.209 363.26] cm
-0 g
-0 G
-[1 0 0 1 -264.209 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.209 363.26 Td
-/F130_0 9.963 Tf
-(Unused) 35.8668 Tj
-[1 0 0 1 300.074 363.26] cm
-0 g
-0 G
-[1 0 0 1 -300.074 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.565 363.26 Td
-/F128_0 9.963 Tf
-(respecti) 30.9849 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ely) 12.1748 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 361.104] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -351.141] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 341.343 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(meaning) 34.3126 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(parameter) 39.8321 Tj
-1 TJm
-(s) 3.87561 Tj
-[1 0 0 1 196.631 341.343] cm
-0 g
-0 G
-[1 0 0 1 -196.631 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.631 341.343 Td
-/F130_0 9.963 Tf
-(small) 29.889 Tj
-[1 0 0 1 226.519 341.343] cm
-0 g
-0 G
-[1 0 0 1 -226.519 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.01 341.343 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 245.887 341.343] cm
-0 g
-0 G
-[1 0 0 1 -245.887 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.887 341.343 Td
-/F130_0 9.963 Tf
-(verbosity) 53.8002 Tj
-[1 0 0 1 299.685 341.343] cm
-0 g
-0 G
-[1 0 0 1 -299.685 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.685 341.343 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(see) 12.7228 Tj
-[1 0 0 1 319.879 341.343] cm
-0 g
-0 G
-[1 0 0 1 -319.879 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-319.879 341.343 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressInit) 119.556 Tj
-[1 0 0 1 439.431 341.343] cm
-0 g
-0 G
-[1 0 0 1 -439.431 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-439.431 341.343 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 339.186] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -329.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 319.425 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--402 TJm
-(amount) 29.889 Tj
--402 TJm
-(of) 8.29918 Tj
--402 TJm
-(mem) 19.926 Tj
-1 TJm
-(ory) 13.2807 Tj
--402 TJm
-(needed) 28.2152 Tj
--402 TJm
-(to) 7.75121 Tj
--402 TJm
-(decompress) 47.0353 Tj
--402 TJm
-(a) 4.42357 Tj
--402 TJm
-(\002le) 12.7327 Tj
--402 TJm
-(c) 4.42357 Tj
-1 TJm
-(annot) 22.1378 Tj
--402 TJm
-(be) 9.40507 Tj
--402 TJm
-(determined) 44.8235 Tj
--402 TJm
-(until) 18.2721 Tj
--402 TJm
-(the) 12.1748 Tj
--402 TJm
-(\002le') 16.0504 Tj
-55 TJm
-(s) 3.87561 Tj
--401 TJm
-(header) 26.5514 Tj
--402 TJm
-(has) 13.2807 Tj
--402 TJm
-(been) 18.8101 Tj
--402 TJm
-(read.) 19.6371 Tj
-72 307.47 Td
-(So) 10.5209 Tj
--492 TJm
-(it) 5.53943 Tj
--491 TJm
-(is) 6.64532 Tj
--492 TJm
-(possible) 32.6587 Tj
--491 TJm
-(that) 14.9445 Tj
-[1 0 0 1 166.797 307.47] cm
-0 g
-0 G
-[1 0 0 1 -166.797 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.797 307.47 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadOpen) 83.6892 Tj
-[1 0 0 1 250.483 307.47] cm
-0 g
-0 G
-[1 0 0 1 -250.483 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.381 307.47 Td
-/F128_0 9.963 Tf
-(returns) 27.6673 Tj
-[1 0 0 1 287.945 307.47] cm
-0 g
-0 G
-[1 0 0 1 -287.945 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-287.945 307.47 Td
-/F130_0 9.963 Tf
-(BZ_OK) 29.889 Tj
-[1 0 0 1 317.833 307.47] cm
-0 g
-0 G
-[1 0 0 1 -317.833 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-322.729 307.47 Td
-/F128_0 9.963 Tf
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--492 TJm
-(a) 4.42357 Tj
--491 TJm
-(subsequent) 44.2756 Tj
--492 TJm
-(call) 14.3866 Tj
--491 TJm
-(of) 8.29918 Tj
-[1 0 0 1 431.135 307.47] cm
-0 g
-0 G
-[1 0 0 1 -431.135 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.135 307.47 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 490.911 307.47] cm
-0 g
-0 G
-[1 0 0 1 -490.911 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-495.81 307.47 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--492 TJm
-(re) 7.74125 Tj
-1 TJm
-(turn) 16.0504 Tj
-[1 0 0 1 72 295.514] cm
-0 g
-0 G
-[1 0 0 1 -72 -295.514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 295.514 Td
-/F130_0 9.963 Tf
-(BZ_MEM_ERROR) 71.7336 Tj
-[1 0 0 1 143.731 295.514] cm
-0 g
-0 G
-[1 0 0 1 -143.731 -295.514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.731 295.514 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 294.349] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -284.386] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 273.597 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(assignments) 48.7091 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 169.144 273.597] cm
-0 g
-0 G
-[1 0 0 1 -169.144 -273.597] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 273.597 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 210.987 273.597] cm
-0 g
-0 G
-[1 0 0 1 -210.987 -273.597] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 273.597 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 271.44] cm
-0 g
-0 G
-[1 0 0 1 0 -168.369] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 167.372 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 163.786] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -262.075] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 262.075 Td
-/F130_0 9.963 Tf
-(BZ_CONFIG_ERROR) 89.667 Tj
-98.488 250.12 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(library) 41.8446 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--425 TJm
-(mis-compiled) 71.7336 Tj
-90 238.165 Td
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 226.209 Td
-(if) 11.9556 Tj
--426 TJm
-(f) 5.9778 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-98.488 214.254 Td
-(or) 11.9556 Tj
--426 TJm
-(small) 29.889 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(neither) 41.8446 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(no) 11.9556 Tj
-1 TJm
-(r) 5.9778 Tj
--426 TJm
-(1) 5.9778 Tj
-98.488 202.299 Td
-(or) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(unused) 35.8668 Tj
--426 TJm
-(==) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(&&) 11.9556 Tj
--426 TJm
-(n) 5.9778 Tj
-1 TJm
-(Unused) 35.8668 Tj
--426 TJm
-(!=) 11.9556 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(\)) 5.9778 Tj
-98.488 190.344 Td
-(or) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(unused) 35.8668 Tj
--426 TJm
-(!=) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(&&) 11.9556 Tj
--426 TJm
-(!) 5.9778 Tj
-1 TJm
-(\(0) 11.9556 Tj
--426 TJm
-(<=) 11.9556 Tj
--426 TJm
-(nUnused) 41.8446 Tj
--426 TJm
-(<=) 11.9556 Tj
--426 TJm
-(BZ_MAX_UNUSED\)) 83.6892 Tj
--426 TJm
-(\)) 5.9778 Tj
-90 178.389 Td
-(BZ_IO_ERROR) 65.7558 Tj
-98.488 166.434 Td
-(if) 11.9556 Tj
--426 TJm
-(ferror\(f\)) 53.8002 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(nonzero) 41.8446 Tj
-90 154.478 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 142.523 Td
-(if) 11.9556 Tj
--426 TJm
-(insufficient) 71.7336 Tj
--426 TJm
-(memory) 35.8668 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(available) 53.8002 Tj
-90 130.568 Td
-(BZ_OK) 29.889 Tj
-98.488 118.613 Td
-(otherwise.) 59.778 Tj
-[1 0 0 1 72 103.071] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -93.109] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 81.153 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 81.054] cm
-0 g
-0 G
-[1 0 0 1 0 -30.202] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.974] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -51.071] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 51.071 Td
-/F128_0 9.963 Tf
-(19) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 23 23
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -81.33] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 56.189] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(Pointer) 41.8446 Tj
--426 TJm
-(to) 11.9556 Tj
--426 TJm
-(an) 11.9556 Tj
--426 TJm
-(abstract) 47.8224 Tj
--426 TJm
-(B) 5.9778 Tj
-1 TJm
-(ZFILE) 29.889 Tj
-98.488 699.676 Td
-(if) 11.9556 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
-90 687.721 Td
-(NULL) 23.9112 Tj
-98.488 675.766 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 660.224] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -650.261] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 638.306 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 638.207] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 56.19] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -628.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 628.842 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-98.488 616.887 Td
-(if) 11.9556 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
-90 604.932 Td
-(BZ2_bzClose) 65.7558 Tj
-98.488 592.976 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 577.435] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -567.472] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 546.814 Td
-/F121_0 17.215 Tf
-(3.4.2.) 43.0719 Tj
-[1 0 0 1 119.858 546.814] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -546.814] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 546.814 Td
-/F387_0 17.215 Tf
-(BZ2_bzRead) 103.29 Tj
-[1 0 0 1 223.151 546.814] cm
-0 g
-0 G
-[1 0 0 1 -151.151 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -535.116] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 535.116 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzRead) 59.778 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(*bz) 17.9334 Tj
-1 TJm
-(error,) 35.8668 Tj
--426 TJm
-(BZFILE) 35.8668 Tj
--426 TJm
-(*b,) 17.9334 Tj
--426 TJm
-(void) 23.9112 Tj
--426 TJm
-(*buf,) 29.889 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(len) 17.9334 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 519.574] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -509.612] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 497.656 Td
-/F128_0 9.963 Tf
-(Reads) 24.3496 Tj
--284 TJm
-(up) 9.963 Tj
--285 TJm
-(to) 7.75121 Tj
-[1 0 0 1 122.569 497.656] cm
-0 g
-0 G
-[1 0 0 1 -122.569 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.569 497.656 Td
-/F130_0 9.963 Tf
-(len) 17.9334 Tj
-[1 0 0 1 140.501 497.656] cm
-0 g
-0 G
-[1 0 0 1 -140.501 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.337 497.656 Td
-/F128_0 9.963 Tf
-(\(uncompressed\)) 63.6337 Tj
--284 TJm
-(bytes) 21.0319 Tj
--285 TJm
-(from) 19.3681 Tj
--284 TJm
-(the) 12.1748 Tj
--285 TJm
-(compressed) 47.0353 Tj
--284 TJm
-(\002le) 12.7327 Tj
-[1 0 0 1 336.319 497.656] cm
-0 g
-0 G
-[1 0 0 1 -336.319 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-336.319 497.656 Td
-/F130_0 9.963 Tf
-(b) 5.9778 Tj
-[1 0 0 1 342.296 497.656] cm
-0 g
-0 G
-[1 0 0 1 -342.296 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-345.132 497.656 Td
-/F128_0 9.963 Tf
-(into) 15.5024 Tj
--285 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--285 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-[1 0 0 1 405.205 497.656] cm
-0 g
-0 G
-[1 0 0 1 -405.205 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.205 497.656 Td
-/F130_0 9.963 Tf
-(buf) 17.9334 Tj
-[1 0 0 1 423.137 497.656] cm
-0 g
-0 G
-[1 0 0 1 -423.137 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-423.137 497.656 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--828 TJm
-(If) 6.63536 Tj
--284 TJm
-(the) 12.1748 Tj
--285 TJm
-(read) 17.1463 Tj
--284 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--285 TJm
-(successful,) 43.4387 Tj
-[1 0 0 1 72 485.701] cm
-0 g
-0 G
-[1 0 0 1 -72 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 485.701 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 113.843 485.701] cm
-0 g
-0 G
-[1 0 0 1 -113.843 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.36 485.701 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--353 TJm
-(set) 11.0689 Tj
--353 TJm
-(to) 7.75121 Tj
-[1 0 0 1 153.374 485.701] cm
-0 g
-0 G
-[1 0 0 1 -153.374 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-153.374 485.701 Td
-/F130_0 9.963 Tf
-(BZ_OK) 29.889 Tj
-[1 0 0 1 183.262 485.701] cm
-0 g
-0 G
-[1 0 0 1 -183.262 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-186.778 485.701 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
--353 TJm
-(the) 12.1748 Tj
--353 TJm
-(number) 30.437 Tj
--353 TJm
-(of) 8.29918 Tj
--353 TJm
-(bytes) 21.0319 Tj
--353 TJm
-(read) 17.1463 Tj
--352 TJm
-(is) 6.64532 Tj
--353 TJm
-(returned.) 35.6875 Tj
--1238 TJm
-(If) 6.63536 Tj
--353 TJm
-(the) 12.1748 Tj
--353 TJm
-(logical) 27.1193 Tj
--353 TJm
-(end-of-stream) 55.8825 Tj
--353 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--353 TJm
-(detecte) 28.2152 Tj
-1 TJm
-(d,) 7.47225 Tj
-[1 0 0 1 72 473.746] cm
-0 g
-0 G
-[1 0 0 1 -72 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 473.746 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 113.843 473.746] cm
-0 g
-0 G
-[1 0 0 1 -113.843 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.795 473.746 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--296 TJm
-(be) 9.40507 Tj
--296 TJm
-(set) 11.0689 Tj
--297 TJm
-(to) 7.75121 Tj
-[1 0 0 1 172.328 473.746] cm
-0 g
-0 G
-[1 0 0 1 -172.328 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.328 473.746 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 250.037 473.746] cm
-0 g
-0 G
-[1 0 0 1 -250.037 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-250.037 473.746 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--296 TJm
-(and) 14.3866 Tj
--297 TJm
-(th) 7.75121 Tj
-1 TJm
-(e) 4.42357 Tj
--297 TJm
-(number) 30.437 Tj
--296 TJm
-(of) 8.29918 Tj
--296 TJm
-(bytes) 21.0319 Tj
--296 TJm
-(read) 17.1463 Tj
--297 TJm
-(is) 6.64532 Tj
--296 TJm
-(returned.) 35.6875 Tj
--898 TJm
-(All) 12.7327 Tj
--296 TJm
-(other) 20.474 Tj
-[1 0 0 1 470 473.746] cm
-0 g
-0 G
-[1 0 0 1 -470 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-470 473.746 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 511.843 473.746] cm
-0 g
-0 G
-[1 0 0 1 -511.843 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-514.795 473.746 Td
-/F128_0 9.963 Tf
-(v) 4.9815 Tj
-25 TJm
-(alues) 20.474 Tj
-72 461.791 Td
-(denote) 26.5614 Tj
--250 TJm
-(an) 9.40507 Tj
--250 TJm
-(error) 19.3581 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 461.691] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -451.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.873 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 131.776 439.873] cm
-0 g
-0 G
-[1 0 0 1 -131.776 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.224 439.873 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--246 TJm
-(supply) 26.5713 Tj
-[1 0 0 1 181.193 439.873] cm
-0 g
-0 G
-[1 0 0 1 -181.193 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.193 439.873 Td
-/F130_0 9.963 Tf
-(len) 17.9334 Tj
-[1 0 0 1 199.126 439.873] cm
-0 g
-0 G
-[1 0 0 1 -199.126 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.575 439.873 Td
-/F128_0 9.963 Tf
-(bytes,) 23.5226 Tj
--246 TJm
-(unless) 24.9075 Tj
--246 TJm
-(the) 12.1748 Tj
--246 TJm
-(logical) 27.1193 Tj
--245 TJm
-(stream) 26.5614 Tj
--246 TJm
-(end) 14.3866 Tj
--246 TJm
-(is) 6.64532 Tj
--246 TJm
-(detec) 21.0219 Tj
-1 TJm
-(ted) 12.1748 Tj
--246 TJm
-(or) 8.29918 Tj
--246 TJm
-(an) 9.40507 Tj
--246 TJm
-(error) 19.3581 Tj
--245 TJm
-(occurs.) 28.4942 Tj
--617 TJm
-(Because) 33.1967 Tj
--246 TJm
-(of) 8.29918 Tj
--246 TJm
-(this,) 16.8873 Tj
--246 TJm
-(it) 5.53943 Tj
-72 427.918 Td
-(is) 6.64532 Tj
--231 TJm
-(possible) 32.6587 Tj
--231 TJm
-(to) 7.75121 Tj
--231 TJm
-(detect) 23.7916 Tj
--231 TJm
-(the) 12.1748 Tj
--231 TJm
-(stream) 26.5614 Tj
--231 TJm
-(end) 14.3866 Tj
--231 TJm
-(by) 9.963 Tj
--231 TJm
-(observing) 39.2941 Tj
--231 TJm
-(when) 21.5799 Tj
--231 TJm
-(the) 12.1748 Tj
--231 TJm
-(number) 30.437 Tj
--231 TJm
-(of) 8.29918 Tj
--231 TJm
-(bytes) 21.0319 Tj
--231 TJm
-(returned) 33.1967 Tj
--231 TJm
-(is) 6.64532 Tj
--231 TJm
-(less) 14.9445 Tj
--231 TJm
-(than) 17.1563 Tj
--231 TJm
-(the) 12.1748 Tj
--231 TJm
-(number) 30.437 Tj
--231 TJm
-(requested.) 40.669 Tj
-72 415.963 Td
-(Ne) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ertheless,) 37.3513 Tj
--309 TJm
-(this) 14.3965 Tj
--297 TJm
-(is) 6.64532 Tj
--297 TJm
-(re) 7.74125 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(arded) 22.1278 Tj
--298 TJm
-(as) 8.29918 Tj
--297 TJm
-(inadvisable;) 48.1512 Tj
--321 TJm
-(you) 14.9445 Tj
--297 TJm
-(should) 26.5713 Tj
--297 TJm
-(instead) 28.2252 Tj
--297 TJm
-(check) 23.2337 Tj
-[1 0 0 1 360.631 415.963] cm
-0 g
-0 G
-[1 0 0 1 -360.631 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.631 415.963 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 402.475 415.963] cm
-0 g
-0 G
-[1 0 0 1 -402.475 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.437 415.963 Td
-/F128_0 9.963 Tf
-(after) 18.2522 Tj
--297 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
--297 TJm
-(call) 14.3866 Tj
--298 TJm
-(and) 14.3866 Tj
--297 TJm
-(w) 7.19329 Tj
-10 TJm
-(atch) 16.5984 Tj
--297 TJm
-(out) 12.7327 Tj
--297 TJm
-(for) 11.6169 Tj
-[1 0 0 1 72 404.008] cm
-0 g
-0 G
-[1 0 0 1 -72 -404.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 404.008 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 149.709 404.008] cm
-0 g
-0 G
-[1 0 0 1 -149.709 -404.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-149.709 404.008 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 402.842] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -392.879] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 382.09 Td
-/F128_0 9.963 Tf
-(Internally) 38.7361 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 117.541 382.09] cm
-0 g
-0 G
-[1 0 0 1 -117.541 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.541 382.09 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 177.317 382.09] cm
-0 g
-0 G
-[1 0 0 1 -177.317 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.786 382.09 Td
-/F128_0 9.963 Tf
-(copies) 25.4555 Tj
--448 TJm
-(data) 16.5984 Tj
--449 TJm
-(from) 19.3681 Tj
--448 TJm
-(the) 12.1748 Tj
--449 TJm
-(compressed) 47.0353 Tj
--448 TJm
-(\002le) 12.7327 Tj
--449 TJm
-(in) 7.75121 Tj
--448 TJm
-(chunks) 28.2252 Tj
--449 TJm
-(of) 8.29918 Tj
--448 TJm
-(size) 15.4925 Tj
-[1 0 0 1 419.602 382.09] cm
-0 g
-0 G
-[1 0 0 1 -419.602 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.602 382.09 Td
-/F130_0 9.963 Tf
-(BZ_MAX_UNUSED) 77.7114 Tj
-[1 0 0 1 497.311 382.09] cm
-0 g
-0 G
-[1 0 0 1 -497.311 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-501.778 382.09 Td
-/F128_0 9.963 Tf
-(bytes) 21.0319 Tj
--448 TJm
-(be-) 12.7228 Tj
-72 370.135 Td
-(fore) 16.0404 Tj
--414 TJm
-(decompressing) 59.768 Tj
--414 TJm
-(it.) 8.03018 Tj
--1605 TJm
-(If) 6.63536 Tj
--414 TJm
-(the) 12.1748 Tj
--414 TJm
-(\002le) 12.7327 Tj
--414 TJm
-(contains) 33.2067 Tj
--414 TJm
-(more) 20.474 Tj
--415 TJm
-(by) 9.963 Tj
-1 TJm
-(tes) 11.0689 Tj
--415 TJm
-(than) 17.1563 Tj
--414 TJm
-(strictly) 27.6772 Tj
--414 TJm
-(needed) 28.2152 Tj
--414 TJm
-(to) 7.75121 Tj
--414 TJm
-(reach) 21.5699 Tj
--414 TJm
-(the) 12.1748 Tj
--414 TJm
-(logical) 27.1193 Tj
--414 TJm
-(end-of-stream,) 58.3732 Tj
-[1 0 0 1 72 358.18] cm
-0 g
-0 G
-[1 0 0 1 -72 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 358.18 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 131.776 358.18] cm
-0 g
-0 G
-[1 0 0 1 -131.776 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.749 358.18 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--298 TJm
-(almost) 26.5713 Tj
--299 TJm
-(certainly) 34.8605 Tj
--298 TJm
-(read) 17.1463 Tj
--298 TJm
-(some) 21.0319 Tj
--299 TJm
-(of) 8.29918 Tj
--298 TJm
-(the) 12.1748 Tj
--299 TJm
-(t) 2.76971 Tj
-1 TJm
-(railing) 26.0134 Tj
--299 TJm
-(data) 16.5984 Tj
--298 TJm
-(before) 25.4455 Tj
--299 TJm
-(s) 3.87561 Tj
-1 TJm
-(ignalling) 35.4284 Tj
-[1 0 0 1 413.162 358.18] cm
-0 g
-0 G
-[1 0 0 1 -413.162 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-413.162 358.18 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_END) 89.667 Tj
-[1 0 0 1 502.826 358.18] cm
-0 g
-0 G
-[1 0 0 1 -502.826 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-502.826 358.18 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--597 TJm
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--298 TJm
-(col-) 15.4925 Tj
-72 346.224 Td
-(lect) 14.3866 Tj
--242 TJm
-(the) 12.1748 Tj
--242 TJm
-(read) 17.1463 Tj
--242 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--242 TJm
-(unused) 28.2252 Tj
--243 TJm
-(d) 4.9815 Tj
-1 TJm
-(ata) 11.6169 Tj
--243 TJm
-(once) 18.8101 Tj
-[1 0 0 1 208.759 346.224] cm
-0 g
-0 G
-[1 0 0 1 -208.759 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.759 346.224 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_END) 89.667 Tj
-[1 0 0 1 298.423 346.224] cm
-0 g
-0 G
-[1 0 0 1 -298.423 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.835 346.224 Td
-/F128_0 9.963 Tf
-(has) 13.2807 Tj
--242 TJm
-(appeared,) 38.4472 Tj
--244 TJm
-(call) 14.3866 Tj
-[1 0 0 1 374.201 346.224] cm
-0 g
-0 G
-[1 0 0 1 -374.201 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.201 346.224 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadGetUnused) 113.578 Tj
-[1 0 0 1 487.775 346.224] cm
-0 g
-0 G
-[1 0 0 1 -487.775 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-490.188 346.224 Td
-/F128_0 9.963 Tf
-(immediately) 49.815 Tj
-72 334.269 Td
-(before) 25.4455 Tj
-[1 0 0 1 99.935 334.269] cm
-0 g
-0 G
-[1 0 0 1 -99.935 -334.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-99.935 334.269 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 189.599 334.269] cm
-0 g
-0 G
-[1 0 0 1 -189.599 -334.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.599 334.269 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 333.104] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -323.141] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 312.351 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(assignments) 48.7091 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 169.144 312.351] cm
-0 g
-0 G
-[1 0 0 1 -169.144 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 312.351 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 210.987 312.351] cm
-0 g
-0 G
-[1 0 0 1 -210.987 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 312.351 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 310.195] cm
-0 g
-0 G
-[1 0 0 1 0 -259.343] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(20) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 24 24
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -284.568] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 263.014 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 259.427] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 699.676 Td
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(buf) 17.9334 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(len) 17.9334 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
-90 687.721 Td
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-98.488 675.766 Td
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(opened) 35.8668 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(BZ2) 17.9334 Tj
-1 TJm
-(_bzWriteOpen) 71.7336 Tj
-90 663.811 Td
-(BZ_IO_ERROR) 65.7558 Tj
-98.488 651.856 Td
-(if) 11.9556 Tj
--426 TJm
-(there) 29.889 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(an) 11.9556 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(rea) 17.9334 Tj
-1 TJm
-(ding) 23.9112 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(file) 23.9112 Tj
-90 639.9 Td
-(BZ_UNEXPECTED_EOF) 101.623 Tj
-98.488 627.945 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(file) 23.9112 Tj
--426 TJm
-(e) 5.9778 Tj
-1 TJm
-(nded) 23.9112 Tj
--426 TJm
-(before) 35.8668 Tj
-98.488 615.99 Td
-(the) 17.9334 Tj
--426 TJm
-(logical) 41.8446 Tj
--426 TJm
-(end-of-stream) 77.7114 Tj
--425 TJm
-(was) 17.9334 Tj
--426 TJm
-(detected) 47.8224 Tj
-90 604.035 Td
-(BZ_DATA_ERROR) 77.7114 Tj
-98.488 592.08 Td
-(if) 11.9556 Tj
--426 TJm
-(a) 5.9778 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(integrity) 53.8002 Tj
--426 TJm
-(erro) 23.9112 Tj
-1 TJm
-(r) 5.9778 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(detected) 47.8224 Tj
--426 TJm
-(in) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(stream) 35.8668 Tj
-90 580.124 Td
-(BZ_DATA_ERROR_MAGIC) 113.578 Tj
-98.488 568.169 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(stream) 35.8668 Tj
--426 TJm
-(does) 23.9112 Tj
--426 TJm
-(not) 17.9334 Tj
--426 TJm
-(b) 5.9778 Tj
-1 TJm
-(egin) 23.9112 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(requisite) 53.8002 Tj
--426 TJm
-(header) 35.8668 Tj
--426 TJm
-(bytes) 29.889 Tj
-98.488 556.214 Td
-(\(ie,) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(not) 17.9334 Tj
--426 TJm
-(a) 5.9778 Tj
--426 TJm
-(bzip2) 29.889 Tj
--426 TJm
-(data) 23.9112 Tj
--425 TJm
-(file\).) 35.8668 Tj
--852 TJm
-(This) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(really) 35.8668 Tj
-98.488 544.259 Td
-(a) 5.9778 Tj
--426 TJm
-(special) 41.8446 Tj
--426 TJm
-(case) 23.9112 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(BZ_DAT) 35.8668 Tj
-1 TJm
-(A_ERROR.) 47.8224 Tj
-90 532.304 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 520.349 Td
-(if) 11.9556 Tj
--426 TJm
-(insufficient) 71.7336 Tj
--426 TJm
-(memory) 35.8668 Tj
--426 TJm
-(wa) 11.9556 Tj
-1 TJm
-(s) 5.9778 Tj
--426 TJm
-(available) 53.8002 Tj
-90 508.393 Td
-(BZ_STREAM_END) 77.7114 Tj
-98.488 496.438 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(logical) 41.8446 Tj
--426 TJm
-(end) 17.9334 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(st) 11.9556 Tj
-1 TJm
-(ream) 23.9112 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(detected.) 53.8002 Tj
-90 484.483 Td
-(BZ_OK) 29.889 Tj
-98.488 472.528 Td
-(otherwise.) 59.778 Tj
-[1 0 0 1 72 456.986] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -447.024] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 435.068 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 434.969] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 56.19] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -425.604] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 425.604 Td
-/F130_0 9.963 Tf
-(number) 35.8668 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(bytes) 29.889 Tj
--426 TJm
-(read) 23.9112 Tj
-98.488 413.649 Td
-(if) 11.9556 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(B) 5.9778 Tj
-1 TJm
-(Z_STREAM_END) 71.7336 Tj
-90 401.694 Td
-(undefined) 53.8002 Tj
-98.488 389.739 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 374.197] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -364.234] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 352.279 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 352.179] cm
-0 g
-0 G
-[1 0 0 1 0 -84.682] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 83.686 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 80.099] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -342.815] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 342.815 Td
-/F130_0 9.963 Tf
-(collect) 41.8446 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(buf,) 23.9112 Tj
--426 TJm
-(t) 5.9778 Tj
-1 TJm
-(hen) 17.9334 Tj
--426 TJm
-(BZ2_bzRead) 59.778 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(BZ2_bzReadClose) 89.667 Tj
-98.488 330.859 Td
-(if) 11.9556 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
-90 318.904 Td
-(collect) 41.8446 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(buf,) 23.9112 Tj
--426 TJm
-(t) 5.9778 Tj
-1 TJm
-(hen) 17.9334 Tj
--426 TJm
-(BZ2_bzReadClose) 89.667 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(BZ2_bzReadGetUnused) 113.578 Tj
-98.488 306.949 Td
-(if) 11.9556 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(BZ_SEQUENCE) 65.7558 Tj
-1 TJm
-(_END) 23.9112 Tj
-90 294.994 Td
-(BZ2_bzReadClose) 89.667 Tj
-98.488 283.039 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 267.497] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -257.534] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 236.876 Td
-/F121_0 17.215 Tf
-(3.4.3.) 43.0719 Tj
-[1 0 0 1 119.858 236.876] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -236.876] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 236.876 Td
-/F387_0 17.215 Tf
-(BZ2_bzReadGetUnused) 196.251 Tj
-[1 0 0 1 316.114 236.876] cm
-0 g
-0 G
-[1 0 0 1 -244.114 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -36.862] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -225.178] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 225.178 Td
-/F130_0 9.963 Tf
-(void) 23.9112 Tj
--426 TJm
-(BZ2_bzReadGetUnused\() 119.556 Tj
--425 TJm
-(int*) 23.9112 Tj
--426 TJm
-(bzerror,) 47.8224 Tj
--426 TJm
-(BZFILE) 35.8668 Tj
--426 TJm
-(*b,) 17.9334 Tj
-200.343 213.223 Td
-(void**) 35.8668 Tj
--426 TJm
-(unused,) 41.8446 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(nUnuse) 35.8668 Tj
-1 TJm
-(d) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 197.681] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -187.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 175.764 Td
-/F128_0 9.963 Tf
-(Returns) 30.9949 Tj
--435 TJm
-(data) 16.5984 Tj
--435 TJm
-(which) 24.3496 Tj
--435 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--435 TJm
-(rea) 12.1648 Tj
-1 TJm
-(d) 4.9815 Tj
--435 TJm
-(from) 19.3681 Tj
--435 TJm
-(the) 12.1748 Tj
--435 TJm
-(compressed) 47.0353 Tj
--435 TJm
-(\002le) 12.7327 Tj
--435 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--435 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--435 TJm
-(not) 12.7327 Tj
--435 TJm
-(needed) 28.2152 Tj
--435 TJm
-(to) 7.75121 Tj
--435 TJm
-(get) 12.1748 Tj
--434 TJm
-(to) 7.75121 Tj
--435 TJm
-(the) 12.1748 Tj
--435 TJm
-(logical) 27.1193 Tj
--435 TJm
-(end-of-stream.) 58.3732 Tj
-[1 0 0 1 72 163.808] cm
-0 g
-0 G
-[1 0 0 1 -72 -163.808] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 163.808 Td
-/F130_0 9.963 Tf
-(*unused) 41.8446 Tj
-[1 0 0 1 113.843 163.808] cm
-0 g
-0 G
-[1 0 0 1 -113.843 -163.808] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.2 163.808 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--337 TJm
-(set) 11.0689 Tj
--337 TJm
-(to) 7.75121 Tj
--337 TJm
-(the) 12.1748 Tj
--336 TJm
-(address) 29.879 Tj
--337 TJm
-(of) 8.29918 Tj
--337 TJm
-(the) 12.1748 Tj
--337 TJm
-(data,) 19.0891 Tj
--359 TJm
-(a) 4.42357 Tj
-1 TJm
-(nd) 9.963 Tj
-[1 0 0 1 269.089 163.808] cm
-0 g
-0 G
-[1 0 0 1 -269.089 -163.808] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.089 163.808 Td
-/F130_0 9.963 Tf
-(*nUnused) 47.8224 Tj
-[1 0 0 1 316.91 163.808] cm
-0 g
-0 G
-[1 0 0 1 -316.91 -163.808] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-320.267 163.808 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--337 TJm
-(the) 12.1748 Tj
--337 TJm
-(number) 30.437 Tj
--337 TJm
-(o) 4.9815 Tj
-1 TJm
-(f) 3.31768 Tj
--337 TJm
-(bytes.) 23.5226 Tj
-[1 0 0 1 427.247 163.808] cm
-0 g
-0 G
-[1 0 0 1 -427.247 -163.808] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.247 163.808 Td
-/F130_0 9.963 Tf
-(*nUnused) 47.8224 Tj
-[1 0 0 1 475.068 163.808] cm
-0 g
-0 G
-[1 0 0 1 -475.068 -163.808] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-478.425 163.808 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--337 TJm
-(be) 9.40507 Tj
--337 TJm
-(set) 11.0689 Tj
--337 TJm
-(to) 7.75121 Tj
--336 TJm
-(a) 4.42357 Tj
-72 151.853 Td
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--250 TJm
-(between) 33.1967 Tj
-[1 0 0 1 131.506 151.853] cm
-0 g
-0 G
-[1 0 0 1 -131.506 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.506 151.853 Td
-/F130_0 9.963 Tf
-(0) 5.9778 Tj
-[1 0 0 1 137.484 151.853] cm
-0 g
-0 G
-[1 0 0 1 -137.484 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-139.975 151.853 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 156.851 151.853] cm
-0 g
-0 G
-[1 0 0 1 -156.851 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-156.851 151.853 Td
-/F130_0 9.963 Tf
-(BZ_MAX_UNUSED) 77.7114 Tj
-[1 0 0 1 234.56 151.853] cm
-0 g
-0 G
-[1 0 0 1 -234.56 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.05 151.853 Td
-/F128_0 9.963 Tf
-(inclusi) 26.5713 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e.) 6.91432 Tj
-[1 0 0 1 72 150.688] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -140.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 129.936 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--882 TJm
-(function) 33.2067 Tj
--883 TJm
-(may) 17.1563 Tj
--882 TJm
-(only) 17.7142 Tj
--882 TJm
-(be) 9.40507 Tj
--883 TJm
-(called) 23.7916 Tj
--882 TJm
-(once) 18.8101 Tj
-[1 0 0 1 271.332 129.936] cm
-0 g
-0 G
-[1 0 0 1 -271.332 -129.936] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-271.332 129.936 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 331.108 129.936] cm
-0 g
-0 G
-[1 0 0 1 -331.108 -129.936] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.9 129.936 Td
-/F128_0 9.963 Tf
-(has) 13.2807 Tj
--882 TJm
-(signalled) 35.9764 Tj
-[1 0 0 1 406.737 129.936] cm
-0 g
-0 G
-[1 0 0 1 -406.737 -129.936] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.737 129.936 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 484.446 129.936] cm
-0 g
-0 G
-[1 0 0 1 -484.446 -129.936] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.231 129.936 Td
-/F128_0 9.963 Tf
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--882 TJm
-(before) 25.4455 Tj
-[1 0 0 1 72 117.98] cm
-0 g
-0 G
-[1 0 0 1 -72 -117.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 117.98 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 161.664 117.98] cm
-0 g
-0 G
-[1 0 0 1 -161.664 -117.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.664 117.98 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 116.815] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -106.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 96.063 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(assignments) 48.7091 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 169.144 96.063] cm
-0 g
-0 G
-[1 0 0 1 -169.144 -96.063] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 96.063 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 210.987 96.063] cm
-0 g
-0 G
-[1 0 0 1 -210.987 -96.063] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 96.063 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 93.906] cm
-0 g
-0 G
-[1 0 0 1 0 -43.054] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.852 Td
-/F128_0 9.963 Tf
-(21) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 25 25
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -129.151] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 107.597 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 104.01] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 699.676 Td
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-98.488 687.721 Td
-(or) 11.9556 Tj
--426 TJm
-(unused) 35.8668 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(nUn) 17.9334 Tj
-1 TJm
-(used) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-90 675.766 Td
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-98.488 663.811 Td
-(if) 11.9556 Tj
--426 TJm
-(BZ_STREAM_END) 77.7114 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(not) 17.9334 Tj
--425 TJm
-(been) 23.9112 Tj
--426 TJm
-(signalled) 53.8002 Tj
-98.488 651.856 Td
-(or) 11.9556 Tj
--426 TJm
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(opened) 35.8668 Tj
--426 TJm
-(with) 23.9112 Tj
--425 TJm
-(BZ2_bzWriteOpen) 89.667 Tj
-90 639.9 Td
-(BZ_OK) 29.889 Tj
-98.488 627.945 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 612.403] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -602.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 590.486 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 590.386] cm
-0 g
-0 G
-[1 0 0 1 0 -24.906] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -581.021] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 581.021 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 72 565.48] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -555.517] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 534.858 Td
-/F121_0 17.215 Tf
-(3.4.4.) 43.0719 Tj
-[1 0 0 1 119.858 534.858] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -534.858] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 534.858 Td
-/F387_0 17.215 Tf
-(BZ2_bzReadClose) 154.935 Tj
-[1 0 0 1 274.797 534.858] cm
-0 g
-0 G
-[1 0 0 1 -202.797 -2.332] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.323] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -523.161] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 523.161 Td
-/F130_0 9.963 Tf
-(void) 23.9112 Tj
--426 TJm
-(BZ2_bzReadClose) 89.667 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(in) 11.9556 Tj
-1 TJm
-(t) 5.9778 Tj
--426 TJm
-(*bzerror,) 53.8002 Tj
--426 TJm
-(BZFILE) 35.8668 Tj
--426 TJm
-(*b) 11.9556 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 507.619] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 485.701 Td
-/F128_0 9.963 Tf
-(Releases) 34.8605 Tj
--429 TJm
-(all) 9.963 Tj
--430 TJm
-(memory) 33.2067 Tj
--429 TJm
-(pertaining) 40.4 Tj
--430 TJm
-(to) 7.75121 Tj
--429 TJm
-(the) 12.1748 Tj
--430 TJm
-(compressed) 47.0353 Tj
--429 TJm
-(\002le) 12.7327 Tj
-[1 0 0 1 304.352 485.701] cm
-0 g
-0 G
-[1 0 0 1 -304.352 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-304.352 485.701 Td
-/F130_0 9.963 Tf
-(b) 5.9778 Tj
-[1 0 0 1 310.33 485.701] cm
-0 g
-0 G
-[1 0 0 1 -310.33 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.33 485.701 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 321.276 485.701] cm
-0 g
-0 G
-[1 0 0 1 -321.276 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-321.276 485.701 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 410.94 485.701] cm
-0 g
-0 G
-[1 0 0 1 -410.94 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-415.22 485.701 Td
-/F128_0 9.963 Tf
-(does) 18.2622 Tj
--429 TJm
-(not) 12.7327 Tj
--430 TJm
-(call) 14.3866 Tj
-[1 0 0 1 473.438 485.701] cm
-0 g
-0 G
-[1 0 0 1 -473.438 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-473.438 485.701 Td
-/F130_0 9.963 Tf
-(fclose) 35.8668 Tj
-[1 0 0 1 509.304 485.701] cm
-0 g
-0 G
-[1 0 0 1 -509.304 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-513.583 485.701 Td
-/F128_0 9.963 Tf
-(on) 9.963 Tj
--430 TJm
-(the) 12.1748 Tj
-72 473.746 Td
-(underlying) 43.1697 Tj
--264 TJm
-(\002le) 12.7327 Tj
--264 TJm
-(hand) 19.3681 Tj
-1 TJm
-(le,) 9.68404 Tj
--268 TJm
-(so) 8.85711 Tj
--264 TJm
-(you) 14.9445 Tj
--264 TJm
-(sh) 8.85711 Tj
-1 TJm
-(ould) 17.7142 Tj
--264 TJm
-(do) 9.963 Tj
--264 TJm
-(that) 14.9445 Tj
--264 TJm
-(yourself) 32.6488 Tj
--264 TJm
-(if) 6.08739 Tj
--264 TJm
-(appropri) 33.7546 Tj
-1 TJm
-(ate.) 14.1076 Tj
-[1 0 0 1 348.653 473.746] cm
-0 g
-0 G
-[1 0 0 1 -348.653 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-348.653 473.746 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 438.317 473.746] cm
-0 g
-0 G
-[1 0 0 1 -438.317 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-440.946 473.746 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--264 TJm
-(be) 9.40507 Tj
--264 TJm
-(called) 23.7916 Tj
--263 TJm
-(to) 7.75121 Tj
--264 TJm
-(clean) 21.0219 Tj
-72 461.791 Td
-(up) 9.963 Tj
--250 TJm
-(after) 18.2522 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(situations.) 40.6889 Tj
-[1 0 0 1 72 459.634] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -449.671] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.873 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(assignments) 48.7091 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 169.144 439.873] cm
-0 g
-0 G
-[1 0 0 1 -169.144 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 439.873 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 210.987 439.873] cm
-0 g
-0 G
-[1 0 0 1 -210.987 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 439.873 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 437.716] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 56.189] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -428.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 428.351 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-98.488 416.396 Td
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(opened) 35.8668 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(BZ2) 17.9334 Tj
-1 TJm
-(_bzOpenWrite) 71.7336 Tj
-90 404.441 Td
-(BZ_OK) 29.889 Tj
-98.488 392.486 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 376.944] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -366.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 355.026 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 354.927] cm
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -345.562] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 345.562 Td
-/F130_0 9.963 Tf
-(none) 23.9112 Tj
-[1 0 0 1 72 330.02] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -320.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 299.399 Td
-/F121_0 17.215 Tf
-(3.4.5.) 43.0719 Tj
-[1 0 0 1 119.858 299.399] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -299.399] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 299.399 Td
-/F387_0 17.215 Tf
-(BZ2_bzWriteOpen) 154.935 Tj
-[1 0 0 1 274.797 299.399] cm
-0 g
-0 G
-[1 0 0 1 -202.797 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -48.817] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 47.821 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 44.234] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -287.702] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 287.702 Td
-/F130_0 9.963 Tf
-(BZFILE) 35.8668 Tj
--426 TJm
-(*BZ2_bzWriteOpen\() 101.623 Tj
--425 TJm
-(int) 17.9334 Tj
--426 TJm
-(*bzerror,) 53.8002 Tj
--426 TJm
-(FILE) 23.9112 Tj
--426 TJm
-(*f,) 17.9334 Tj
-196.099 275.746 Td
-(int) 17.9334 Tj
--426 TJm
-(blockSize100k,) 83.6892 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(ver) 17.9334 Tj
-1 TJm
-(bosity,) 41.8446 Tj
-196.099 263.791 Td
-(int) 17.9334 Tj
--426 TJm
-(workFactor) 59.778 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 248.249] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -238.287] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 226.332 Td
-/F128_0 9.963 Tf
-(Prepare) 30.427 Tj
--268 TJm
-(to) 7.75121 Tj
--269 TJm
-(write) 20.474 Tj
--268 TJm
-(compressed) 47.0353 Tj
--268 TJm
-(data) 16.5984 Tj
--269 TJm
-(to) 7.75121 Tj
--268 TJm
-(\002le) 12.7327 Tj
--269 TJm
-(hand) 19.3681 Tj
-1 TJm
-(le) 7.19329 Tj
-[1 0 0 1 262.72 226.332] cm
-0 g
-0 G
-[1 0 0 1 -262.72 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-262.72 226.332 Td
-/F130_0 9.963 Tf
-(f) 5.9778 Tj
-[1 0 0 1 268.698 226.332] cm
-0 g
-0 G
-[1 0 0 1 -268.698 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-268.698 226.332 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 274.829 226.332] cm
-0 g
-0 G
-[1 0 0 1 -274.829 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-274.829 226.332 Td
-/F130_0 9.963 Tf
-(f) 5.9778 Tj
-[1 0 0 1 280.807 226.332] cm
-0 g
-0 G
-[1 0 0 1 -280.807 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-283.481 226.332 Td
-/F128_0 9.963 Tf
-(should) 26.5713 Tj
--268 TJm
-(refer) 18.8002 Tj
--269 TJm
-(to) 7.75121 Tj
--268 TJm
-(a) 4.42357 Tj
--269 TJm
-(\002le) 12.7327 Tj
--268 TJm
-(which) 24.3496 Tj
--268 TJm
-(has) 13.2807 Tj
--269 TJm
-(been) 18.8101 Tj
--268 TJm
-(opened) 28.7731 Tj
--269 TJm
-(f) 3.31768 Tj
-1 TJm
-(or) 8.29918 Tj
--269 TJm
-(writing,) 31.2739 Tj
--273 TJm
-(and) 14.3866 Tj
--268 TJm
-(for) 11.6169 Tj
-72 214.377 Td
-(which) 24.3496 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(indicator) 35.4185 Tj
--250 TJm
-(\() 3.31768 Tj
-[1 0 0 1 176.577 214.377] cm
-0 g
-0 G
-[1 0 0 1 -176.577 -214.377] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.577 214.377 Td
-/F130_0 9.963 Tf
-(ferror\(f\)) 53.8002 Tj
-[1 0 0 1 230.375 214.377] cm
-0 g
-0 G
-[1 0 0 1 -230.375 -214.377] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.375 214.377 Td
-/F128_0 9.963 Tf
-(\)is) 9.963 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(set.) 13.5596 Tj
-[1 0 0 1 72 212.593] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -202.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 192.459 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--223 TJm
-(the) 12.1748 Tj
--224 TJm
-(meaning) 34.3126 Tj
--223 TJm
-(of) 8.29918 Tj
--223 TJm
-(parameters) 43.7077 Tj
-[1 0 0 1 195.306 192.459] cm
-0 g
-0 G
-[1 0 0 1 -195.306 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-195.306 192.459 Td
-/F130_0 9.963 Tf
-(blockSize100k) 77.7114 Tj
-[1 0 0 1 273.015 192.459] cm
-0 g
-0 G
-[1 0 0 1 -273.015 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-273.015 192.459 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 277.784 192.459] cm
-0 g
-0 G
-[1 0 0 1 -277.784 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.784 192.459 Td
-/F130_0 9.963 Tf
-(verbosity) 53.8002 Tj
-[1 0 0 1 331.583 192.459] cm
-0 g
-0 G
-[1 0 0 1 -331.583 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.808 192.459 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 350.42 192.459] cm
-0 g
-0 G
-[1 0 0 1 -350.42 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-350.42 192.459 Td
-/F130_0 9.963 Tf
-(workFactor) 59.778 Tj
-[1 0 0 1 410.196 192.459] cm
-0 g
-0 G
-[1 0 0 1 -410.196 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.196 192.459 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--229 TJm
-(see) 12.7228 Tj
-[1 0 0 1 429.913 192.459] cm
-0 g
-0 G
-[1 0 0 1 -429.913 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.913 192.459 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 537.509 192.459] cm
-0 g
-0 G
-[1 0 0 1 -537.509 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 192.459 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 190.302] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -180.339] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 170.541 Td
-/F128_0 9.963 Tf
-(All) 12.7327 Tj
--382 TJm
-(required) 33.1967 Tj
--382 TJm
-(memory) 33.2067 Tj
--382 TJm
-(is) 6.64532 Tj
--382 TJm
-(allocated) 35.9664 Tj
--382 TJm
-(at) 7.19329 Tj
--382 TJm
-(this) 14.3965 Tj
--382 TJm
-(stage,) 22.9647 Tj
--415 TJm
-(so) 8.85711 Tj
--382 TJm
-(if) 6.08739 Tj
--382 TJm
-(the) 12.1748 Tj
--382 TJm
-(call) 14.3866 Tj
--382 TJm
-(completes) 40.4 Tj
--382 TJm
-(successfully) 48.6991 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 424.692 170.541] cm
-0 g
-0 G
-[1 0 0 1 -424.692 -170.541] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-424.692 170.541 Td
-/F130_0 9.963 Tf
-(BZ_MEM_ERROR) 71.7336 Tj
-[1 0 0 1 496.423 170.541] cm
-0 g
-0 G
-[1 0 0 1 -496.423 -170.541] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-500.228 170.541 Td
-/F128_0 9.963 Tf
-(cannot) 26.5614 Tj
--382 TJm
-(be) 9.40507 Tj
-72 158.586 Td
-(signalled) 35.9764 Tj
--250 TJm
-(by) 9.963 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(subsequent) 44.2756 Tj
--250 TJm
-(cal) 11.6169 Tj
-1 TJm
-(l) 2.76971 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 203.715 158.586] cm
-0 g
-0 G
-[1 0 0 1 -203.715 -158.586] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.715 158.586 Td
-/F130_0 9.963 Tf
-(BZ2_bzWrite) 65.7558 Tj
-[1 0 0 1 269.468 158.586] cm
-0 g
-0 G
-[1 0 0 1 -269.468 -158.586] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.468 158.586 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 156.429] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -146.466] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 136.668 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(assignments) 48.7091 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 169.144 136.668] cm
-0 g
-0 G
-[1 0 0 1 -169.144 -136.668] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 136.668 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 210.987 136.668] cm
-0 g
-0 G
-[1 0 0 1 -210.987 -136.668] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 136.668 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 134.511] cm
-0 g
-0 G
-[1 0 0 1 0 -83.659] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.852 Td
-/F128_0 9.963 Tf
-(22) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 26 26
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -165.016] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 143.462 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 139.875] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(BZ_CONFIG_ERROR) 89.667 Tj
-98.488 699.676 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(library) 41.8446 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--425 TJm
-(mis-compiled) 71.7336 Tj
-90 687.721 Td
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 675.766 Td
-(if) 11.9556 Tj
--426 TJm
-(f) 5.9778 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-98.488 663.811 Td
-(or) 11.9556 Tj
--426 TJm
-(blockSize100k) 77.7114 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(1) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--425 TJm
-(blockSize100k) 77.7114 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(9) 5.9778 Tj
-90 651.856 Td
-(BZ_IO_ERROR) 65.7558 Tj
-98.488 639.9 Td
-(if) 11.9556 Tj
--426 TJm
-(ferror\(f\)) 53.8002 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(nonzero) 41.8446 Tj
-90 627.945 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 615.99 Td
-(if) 11.9556 Tj
--426 TJm
-(insufficient) 71.7336 Tj
--426 TJm
-(memory) 35.8668 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(available) 53.8002 Tj
-90 604.035 Td
-(BZ_OK) 29.889 Tj
-98.488 592.08 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 576.538] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -566.575] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 554.62 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 554.521] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 56.189] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -545.156] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 545.156 Td
-/F130_0 9.963 Tf
-(Pointer) 41.8446 Tj
--426 TJm
-(to) 11.9556 Tj
--426 TJm
-(an) 11.9556 Tj
--426 TJm
-(abstract) 47.8224 Tj
--426 TJm
-(B) 5.9778 Tj
-1 TJm
-(ZFILE) 29.889 Tj
-98.488 533.201 Td
-(if) 11.9556 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
-90 521.245 Td
-(NULL) 23.9112 Tj
-98.488 509.29 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 493.749] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -483.786] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 471.831 Td
-/F128_0 9.963 Tf
-(Allo) 17.7142 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able) 16.5984 Tj
--250 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(actions:) 30.9949 Tj
-[1 0 0 1 72 471.731] cm
-0 g
-0 G
-[1 0 0 1 0 -84.682] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 83.686 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 80.1] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -462.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 462.366 Td
-/F130_0 9.963 Tf
-(BZ2_bzWrite) 65.7558 Tj
-98.488 450.411 Td
-(if) 11.9556 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
-98.488 438.456 Td
-(\(you) 23.9112 Tj
--426 TJm
-(could) 29.889 Tj
--426 TJm
-(go) 11.9556 Tj
--426 TJm
-(directly) 47.8224 Tj
--426 TJm
-(t) 5.9778 Tj
-1 TJm
-(o) 5.9778 Tj
--426 TJm
-(BZ2_bzWriteClose,) 101.623 Tj
--426 TJm
-(but) 17.9334 Tj
--426 TJm
-(this) 23.9112 Tj
--426 TJm
-(would) 29.889 Tj
--426 TJm
-(be) 11.9556 Tj
--426 TJm
-(pretty) 35.8668 Tj
-485.506 434.212 Td
-/F559_0 9.963 Tf
-( ) 9.963 Tj
-493.808 434.212 Td
-/F143_0 9.963 Tf
-(-) 2.76971 Tj
-90 426.501 Td
-/F130_0 9.963 Tf
-(pointless\)) 59.778 Tj
-90 414.546 Td
-(BZ2_bzWriteClose) 95.6448 Tj
-98.488 402.59 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 387.049] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -377.086] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 356.428 Td
-/F121_0 17.215 Tf
-(3.4.6.) 43.0719 Tj
-[1 0 0 1 119.858 356.428] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -356.428] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 356.428 Td
-/F387_0 17.215 Tf
-(BZ2_bzWrite) 113.619 Tj
-[1 0 0 1 233.48 356.428] cm
-0 g
-0 G
-[1 0 0 1 -161.48 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -344.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 344.73 Td
-/F130_0 9.963 Tf
-(void) 23.9112 Tj
--426 TJm
-(BZ2_bzWrite) 65.7558 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(*) 5.9778 Tj
-1 TJm
-(bzerror,) 47.8224 Tj
--426 TJm
-(BZFILE) 35.8668 Tj
--426 TJm
-(*b,) 17.9334 Tj
--426 TJm
-(void) 23.9112 Tj
--426 TJm
-(*buf,) 29.889 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(len) 17.9334 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 329.188] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -319.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 307.271 Td
-/F128_0 9.963 Tf
-(Absorbs) 33.2067 Tj
-[1 0 0 1 107.696 307.271] cm
-0 g
-0 G
-[1 0 0 1 -107.696 -307.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-107.696 307.271 Td
-/F130_0 9.963 Tf
-(len) 17.9334 Tj
-[1 0 0 1 125.629 307.271] cm
-0 g
-0 G
-[1 0 0 1 -125.629 -307.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.119 307.271 Td
-/F128_0 9.963 Tf
-(bytes) 21.0319 Tj
--250 TJm
-(from) 19.3681 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-[1 0 0 1 214.544 307.271] cm
-0 g
-0 G
-[1 0 0 1 -214.544 -307.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.544 307.271 Td
-/F130_0 9.963 Tf
-(buf) 17.9334 Tj
-[1 0 0 1 232.477 307.271] cm
-0 g
-0 G
-[1 0 0 1 -232.477 -307.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.477 307.271 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(entually) 32.1008 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(compressed) 47.0353 Tj
--249 TJm
-(and) 14.3866 Tj
--250 TJm
-(written) 28.2252 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(\002le.) 15.2235 Tj
-[1 0 0 1 72 305.114] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -295.151] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 285.353 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(assignments) 48.7091 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 169.144 285.353] cm
-0 g
-0 G
-[1 0 0 1 -169.144 -285.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 285.353 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 210.987 285.353] cm
-0 g
-0 G
-[1 0 0 1 -210.987 -285.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 285.353 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 283.196] cm
-0 g
-0 G
-[1 0 0 1 0 -108.593] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 107.597 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 104.01] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -273.831] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 273.831 Td
-/F130_0 9.963 Tf
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 261.876 Td
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(buf) 17.9334 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(len) 17.9334 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
-90 249.921 Td
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-98.488 237.966 Td
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(opened) 35.8668 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(BZ2) 17.9334 Tj
-1 TJm
-(_bzReadOpen) 65.7558 Tj
-90 226.01 Td
-(BZ_IO_ERROR) 65.7558 Tj
-98.488 214.055 Td
-(if) 11.9556 Tj
--426 TJm
-(there) 29.889 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(an) 11.9556 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(wri) 17.9334 Tj
-1 TJm
-(ting) 23.9112 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(file.) 29.889 Tj
-90 202.1 Td
-(BZ_OK) 29.889 Tj
-98.488 190.145 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 174.603] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -164.64] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 143.982 Td
-/F121_0 17.215 Tf
-(3.4.7.) 43.0719 Tj
-[1 0 0 1 119.858 143.982] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -143.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 143.982 Td
-/F387_0 17.215 Tf
-(BZ2_bzWriteClose) 165.264 Tj
-[1 0 0 1 285.126 143.982] cm
-0 g
-0 G
-[1 0 0 1 -213.126 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -90.797] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(23) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 27 27
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -165.016] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 143.462 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 139.875] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(void) 23.9112 Tj
--426 TJm
-(BZ2_bzWriteClose\() 101.623 Tj
--426 TJm
-(in) 11.9556 Tj
-1 TJm
-(t) 5.9778 Tj
--426 TJm
-(*bzerror,) 53.8002 Tj
--426 TJm
-(BZFILE*) 41.8446 Tj
--426 TJm
-(f,) 11.9556 Tj
-187.611 699.676 Td
-(int) 17.9334 Tj
--426 TJm
-(abandon,) 47.8224 Tj
-187.611 687.721 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(nbytes_in,) 59.778 Tj
-187.611 675.766 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(nbytes_out) 59.778 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 651.856 Td
-(void) 23.9112 Tj
--426 TJm
-(BZ2_bzWriteClose64\() 113.578 Tj
--425 TJm
-(int) 17.9334 Tj
--426 TJm
-(*bzerror,) 53.8002 Tj
--426 TJm
-(BZFILE*) 41.8446 Tj
--426 TJm
-(f,) 11.9556 Tj
-196.099 639.9 Td
-(int) 17.9334 Tj
--426 TJm
-(abandon,) 47.8224 Tj
-196.099 627.945 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(nbytes_in_lo3) 77.7114 Tj
-1 TJm
-(2,) 11.9556 Tj
-196.099 615.99 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(nbytes_in_hi3) 77.7114 Tj
-1 TJm
-(2,) 11.9556 Tj
-196.099 604.035 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(nbytes_out_lo) 77.7114 Tj
-1 TJm
-(32,) 17.9334 Tj
-196.099 592.08 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(nbytes_out_hi) 77.7114 Tj
-1 TJm
-(32) 11.9556 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 576.538] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -566.575] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 554.62 Td
-/F128_0 9.963 Tf
-(Compresses) 48.1512 Tj
--402 TJm
-(and) 14.3866 Tj
--403 TJm
-(\003ushes) 27.6772 Tj
--403 TJm
-(to) 7.75121 Tj
--402 TJm
-(the) 12.1748 Tj
--403 TJm
-(compressed) 47.0353 Tj
--402 TJm
-(\002le) 12.7327 Tj
--403 TJm
-(all) 9.963 Tj
--402 TJm
-(data) 16.5984 Tj
--403 TJm
-(so) 8.85711 Tj
--403 TJm
-(f) 3.31768 Tj
-11 TJm
-(ar) 7.74125 Tj
--403 TJm
-(supplied) 33.7646 Tj
--403 TJm
-(by) 9.963 Tj
-[1 0 0 1 384.152 554.62] cm
-0 g
-0 G
-[1 0 0 1 -384.152 -554.62] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.152 554.62 Td
-/F130_0 9.963 Tf
-(BZ2_bzWrite) 65.7558 Tj
-[1 0 0 1 449.906 554.62] cm
-0 g
-0 G
-[1 0 0 1 -449.906 -554.62] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.906 554.62 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--768 TJm
-(The) 15.4925 Tj
--402 TJm
-(logical) 27.1193 Tj
--403 TJm
-(end-of-) 29.3211 Tj
-72 542.665 Td
-(stream) 26.5614 Tj
--352 TJm
-(mark) 20.474 Tj
-10 TJm
-(ers) 11.6169 Tj
--352 TJm
-(are) 12.1648 Tj
--352 TJm
-(also) 16.0504 Tj
--352 TJm
-(written,) 30.7159 Tj
--378 TJm
-(so) 8.85711 Tj
--352 TJm
-(subsequent) 44.2756 Tj
--352 TJm
-(calls) 18.2622 Tj
--352 TJm
-(to) 7.75121 Tj
-[1 0 0 1 300.456 542.665] cm
-0 g
-0 G
-[1 0 0 1 -300.456 -542.665] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.456 542.665 Td
-/F130_0 9.963 Tf
-(BZ2_bzWrite) 65.7558 Tj
-[1 0 0 1 366.209 542.665] cm
-0 g
-0 G
-[1 0 0 1 -366.209 -542.665] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-369.718 542.665 Td
-/F128_0 9.963 Tf
-(are) 12.1648 Tj
--352 TJm
-(ille) 12.7327 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(al.) 9.68404 Tj
--1233 TJm
-(All) 12.7327 Tj
--352 TJm
-(memory) 33.2067 Tj
--353 TJm
-(ass) 12.1748 Tj
-1 TJm
-(ociated) 28.7731 Tj
--353 TJm
-(wit) 12.7327 Tj
-1 TJm
-(h) 4.9815 Tj
-72 530.71 Td
-(the) 12.1748 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(\002le) 12.7327 Tj
-[1 0 0 1 151.411 530.71] cm
-0 g
-0 G
-[1 0 0 1 -151.411 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-151.411 530.71 Td
-/F130_0 9.963 Tf
-(b) 5.9778 Tj
-[1 0 0 1 157.389 530.71] cm
-0 g
-0 G
-[1 0 0 1 -157.389 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.88 530.71 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(released.) 35.1295 Tj
-[1 0 0 1 207.231 530.71] cm
-0 g
-0 G
-[1 0 0 1 -207.231 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.231 530.71 Td
-/F130_0 9.963 Tf
-(fflush) 35.8668 Tj
-[1 0 0 1 243.097 530.71] cm
-0 g
-0 G
-[1 0 0 1 -243.097 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.587 530.71 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(called) 23.7916 Tj
--250 TJm
-(on) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(\002l) 8.30914 Tj
-1 TJm
-(e,) 6.91432 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(not) 12.7327 Tj
-[1 0 0 1 422.771 530.71] cm
-0 g
-0 G
-[1 0 0 1 -422.771 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.771 530.71 Td
-/F130_0 9.963 Tf
-(fclose) 35.8668 Tj
-[1 0 0 1 458.636 530.71] cm
-0 g
-0 G
-[1 0 0 1 -458.636 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-458.636 530.71 Td
-/F128_0 9.963 Tf
-(') 3.31768 Tj
-50 TJm
-(d.) 7.47225 Tj
-[1 0 0 1 72 528.553] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -518.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 508.792 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
-[1 0 0 1 81.574 508.792] cm
-0 g
-0 G
-[1 0 0 1 -81.574 -508.792] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-81.574 508.792 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteClose) 95.6448 Tj
-[1 0 0 1 177.216 508.792] cm
-0 g
-0 G
-[1 0 0 1 -177.216 -508.792] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-180.155 508.792 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--295 TJm
-(called) 23.7916 Tj
--295 TJm
-(to) 7.75121 Tj
--295 TJm
-(clean) 21.0219 Tj
--295 TJm
-(up) 9.963 Tj
--295 TJm
-(after) 18.2522 Tj
--295 TJm
-(an) 9.40507 Tj
--295 TJm
-(error) 19.3581 Tj
-40 TJm
-(,) 2.49075 Tj
--306 TJm
-(the) 12.1748 Tj
--295 TJm
-(only) 17.7142 Tj
--295 TJm
-(action) 24.3496 Tj
--295 TJm
-(is) 6.64532 Tj
--295 TJm
-(to) 7.75121 Tj
--295 TJm
-(relea) 19.3581 Tj
-1 TJm
-(se) 8.29918 Tj
--295 TJm
-(the) 12.1748 Tj
--295 TJm
-(memory) 33.2067 Tj
-65 TJm
-(.) 2.49075 Tj
--890 TJm
-(The) 15.4925 Tj
--295 TJm
-(library) 26.5614 Tj
-72 496.837 Td
-(records) 29.3211 Tj
--289 TJm
-(the) 12.1748 Tj
--289 TJm
-(error) 19.3581 Tj
--289 TJm
-(codes) 22.6858 Tj
--289 TJm
-(issued) 24.9075 Tj
--289 TJm
-(by) 9.963 Tj
--289 TJm
-(p) 4.9815 Tj
-1 TJm
-(re) 7.74125 Tj
-25 TJm
-(vious) 21.5898 Tj
--289 TJm
-(calls,) 20.7529 Tj
--299 TJm
-(so) 8.85711 Tj
--289 TJm
-(this) 14.3965 Tj
--289 TJm
-(situation) 34.3225 Tj
--289 TJm
-(will) 15.5024 Tj
--289 TJm
-(be) 9.40507 Tj
--289 TJm
-(detecte) 28.2152 Tj
-1 TJm
-(d) 4.9815 Tj
--289 TJm
-(automatically) 54.2386 Tj
-65 TJm
-(.) 2.49075 Tj
--427 TJm
-(There) 23.2337 Tj
--289 TJm
-(is) 6.64532 Tj
--289 TJm
-(no) 9.963 Tj
--289 TJm
-(attempt) 29.889 Tj
-72 484.882 Td
-(to) 7.75121 Tj
--263 TJm
-(comple) 29.3311 Tj
-1 TJm
-(te) 7.19329 Tj
--263 TJm
-(the) 12.1748 Tj
--263 TJm
-(compression) 50.363 Tj
--262 TJm
-(operation,) 40.121 Tj
--266 TJm
-(nor) 13.2807 Tj
--262 TJm
-(to) 7.75121 Tj
-[1 0 0 1 258.308 484.882] cm
-0 g
-0 G
-[1 0 0 1 -258.308 -484.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.308 484.882 Td
-/F130_0 9.963 Tf
-(fflush) 35.8668 Tj
-[1 0 0 1 294.173 484.882] cm
-0 g
-0 G
-[1 0 0 1 -294.173 -484.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-296.79 484.882 Td
-/F128_0 9.963 Tf
-(the) 12.1748 Tj
--263 TJm
-(compres) 33.7546 Tj
-1 TJm
-(sed) 13.2807 Tj
--263 TJm
-(\002le.) 15.2235 Tj
--696 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--263 TJm
-(can) 13.8286 Tj
--262 TJm
-(force) 20.464 Tj
--263 TJm
-(this) 14.3965 Tj
--262 TJm
-(beha) 18.8101 Tj
-20 TJm
-(viour) 21.0319 Tj
--263 TJm
-(to) 7.75121 Tj
--262 TJm
-(happen) 28.7731 Tj
-72 472.927 Td
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(case) 17.1463 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(no) 9.963 Tj
--250 TJm
-(error) 19.3581 Tj
-40 TJm
-(,) 2.49075 Tj
--250 TJm
-(by) 9.963 Tj
--250 TJm
-(p) 4.9815 Tj
-1 TJm
-(assing) 24.9075 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(nonzero) 32.0908 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue) 16.5984 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 305.015 472.927] cm
-0 g
-0 G
-[1 0 0 1 -305.015 -472.927] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.015 472.927 Td
-/F130_0 9.963 Tf
-(abandon) 41.8446 Tj
-[1 0 0 1 346.858 472.927] cm
-0 g
-0 G
-[1 0 0 1 -346.858 -472.927] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-346.858 472.927 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 470.77] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -460.807] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 451.009 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
-[1 0 0 1 80.597 451.009] cm
-0 g
-0 G
-[1 0 0 1 -80.597 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-80.597 451.009 Td
-/F130_0 9.963 Tf
-(nbytes_in) 53.8002 Tj
-[1 0 0 1 134.396 451.009] cm
-0 g
-0 G
-[1 0 0 1 -134.396 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-136.358 451.009 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--197 TJm
-(non-null,) 36.2554 Tj
-[1 0 0 1 183.287 451.009] cm
-0 g
-0 G
-[1 0 0 1 -183.287 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.287 451.009 Td
-/F130_0 9.963 Tf
-(*nbytes_in) 59.778 Tj
-[1 0 0 1 243.063 451.009] cm
-0 g
-0 G
-[1 0 0 1 -243.063 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.025 451.009 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--197 TJm
-(be) 9.40507 Tj
--197 TJm
-(set) 11.0689 Tj
--197 TJm
-(to) 7.75121 Tj
--197 TJm
-(be) 9.40507 Tj
--197 TJm
-(the) 12.1748 Tj
--197 TJm
-(tot) 10.5209 Tj
-1 TJm
-(al) 7.19329 Tj
--197 TJm
-(v) 4.9815 Tj
-20 TJm
-(olume) 24.9075 Tj
--197 TJm
-(of) 8.29918 Tj
--197 TJm
-(uncompressed) 56.9983 Tj
--197 TJm
-(data) 16.5984 Tj
--197 TJm
-(handled.) 34.0336 Tj
--584 TJm
-(Similarly) 37.0922 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 72 439.054] cm
-0 g
-0 G
-[1 0 0 1 -72 -439.054] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.054 Td
-/F130_0 9.963 Tf
-(nbytes_out) 59.778 Tj
-[1 0 0 1 131.776 439.054] cm
-0 g
-0 G
-[1 0 0 1 -131.776 -439.054] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.716 439.054 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--295 TJm
-(be) 9.40507 Tj
--295 TJm
-(set) 11.0689 Tj
--295 TJm
-(to) 7.75121 Tj
--295 TJm
-(the) 12.1748 Tj
--295 TJm
-(total) 17.7142 Tj
--295 TJm
-(v) 4.9815 Tj
-20 TJm
-(olume) 24.9075 Tj
--295 TJm
-(of) 8.29918 Tj
--295 TJm
-(compressed) 47.0353 Tj
--295 TJm
-(data) 16.5984 Tj
--295 TJm
-(written.) 30.7159 Tj
--890 TJm
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--295 TJm
-(compatibility) 53.1426 Tj
--295 TJm
-(with) 17.7142 Tj
--295 TJm
-(older) 20.474 Tj
--295 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--295 TJm
-(of) 8.29918 Tj
-72 427.098 Td
-(the) 12.1748 Tj
--283 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 118.294 427.098] cm
-0 g
-0 G
-[1 0 0 1 -118.294 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.294 427.098 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteClose) 95.6448 Tj
-[1 0 0 1 213.936 427.098] cm
-0 g
-0 G
-[1 0 0 1 -213.936 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.753 427.098 Td
-/F128_0 9.963 Tf
-(only) 17.7142 Tj
--283 TJm
-(yields) 23.8016 Tj
--282 TJm
-(the) 12.1748 Tj
--283 TJm
-(lo) 7.75121 Tj
-25 TJm
-(wer) 14.9345 Tj
--283 TJm
-(32) 9.963 Tj
--283 TJm
-(bits) 14.3965 Tj
--282 TJm
-(of) 8.29918 Tj
--283 TJm
-(these) 20.474 Tj
--283 TJm
-(counts.) 28.5041 Tj
--817 TJm
-(Use) 15.4925 Tj
-[1 0 0 1 423.499 427.098] cm
-0 g
-0 G
-[1 0 0 1 -423.499 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-423.499 427.098 Td
-/F130_0 9.963 Tf
-(BZ2_bzWriteClose64) 107.6 Tj
-[1 0 0 1 531.095 427.098] cm
-0 g
-0 G
-[1 0 0 1 -531.095 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.913 427.098 Td
-/F128_0 9.963 Tf
-(if) 6.08739 Tj
-72 415.143 Td
-(you) 14.9445 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(full) 13.8386 Tj
--250 TJm
-(64) 9.963 Tj
--250 TJm
-(bit) 10.5209 Tj
--250 TJm
-(counts) 26.0134 Tj
-1 TJm
-(.) 2.49075 Tj
--620 TJm
-(These) 23.7916 Tj
--250 TJm
-(tw) 9.963 Tj
-10 TJm
-(o) 4.9815 Tj
--250 TJm
-(functions) 37.0823 Tj
--250 TJm
-(are) 12.1648 Tj
--250 TJm
-(otherwise) 38.7361 Tj
--250 TJm
-(absolutely) 40.9579 Tj
--250 TJm
-(identic) 27.1193 Tj
-1 TJm
-(al.) 9.68404 Tj
-[1 0 0 1 72 412.986] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -403.024] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 393.225 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(assignments) 48.7091 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 169.144 393.225] cm
-0 g
-0 G
-[1 0 0 1 -169.144 -393.225] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 393.225 Td
-/F130_0 9.963 Tf
-(bzerror) 41.8446 Tj
-[1 0 0 1 210.987 393.225] cm
-0 g
-0 G
-[1 0 0 1 -210.987 -393.225] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 393.225 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 391.069] cm
-0 g
-0 G
-[1 0 0 1 0 -84.683] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 83.686 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 80.099] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -381.704] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 381.704 Td
-/F130_0 9.963 Tf
-(BZ_SEQUENCE_ERROR) 101.623 Tj
-98.488 369.749 Td
-(if) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(opened) 35.8668 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(BZ2) 17.9334 Tj
-1 TJm
-(_bzReadOpen) 65.7558 Tj
-90 357.793 Td
-(BZ_IO_ERROR) 65.7558 Tj
-98.488 345.838 Td
-(if) 11.9556 Tj
--426 TJm
-(there) 29.889 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(an) 11.9556 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(wri) 17.9334 Tj
-1 TJm
-(ting) 23.9112 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(file) 23.9112 Tj
-90 333.883 Td
-(BZ_OK) 29.889 Tj
-98.488 321.928 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 306.386] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -296.423] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 275.765 Td
-/F121_0 17.215 Tf
-(3.4.8.) 43.0719 Tj
--278 TJm
-(Handling) 73.6458 Tj
--278 TJm
-(embed) 55.4839 Tj
-10 TJm
-(ded) 30.6083 Tj
--278 TJm
-(compressed) 101.414 Tj
--278 TJm
-(data) 35.394 Tj
--278 TJm
-(streams) 66.0195 Tj
-[1 0 0 1 72 271.935] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -261.972] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 253.847 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--203 TJm
-(high-le) 28.2252 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--203 TJm
-(library) 26.5614 Tj
--203 TJm
-(f) 3.31768 Tj
-10 TJm
-(acilitates) 35.4185 Tj
--203 TJm
-(use) 13.2807 Tj
--203 TJm
-(of) 8.29918 Tj
-[1 0 0 1 226.404 253.847] cm
-0 g
-0 G
-[1 0 0 1 -226.404 -253.847] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-226.404 253.847 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 256.292 253.847] cm
-0 g
-0 G
-[1 0 0 1 -256.292 -253.847] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.316 253.847 Td
-/F128_0 9.963 Tf
-(data) 16.5984 Tj
--203 TJm
-(streams) 30.437 Tj
--203 TJm
-(which) 24.3496 Tj
--203 TJm
-(form) 19.3681 Tj
--203 TJm
-(some) 21.0319 Tj
--203 TJm
-(part) 15.4925 Tj
--203 TJm
-(of) 8.29918 Tj
--203 TJm
-(a) 4.42357 Tj
--203 TJm
-(surrounding,) 50.6419 Tj
--212 TJm
-(lar) 10.511 Tj
-18 TJm
-(ger) 12.7228 Tj
--203 TJm
-(data) 16.5984 Tj
--203 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 72 251.69] cm
-0 g
-0 G
-[1 0 0 1 0 -29.723] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 221.967 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 221.967] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 221.967 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--240 TJm
-(writing,) 31.2739 Tj
--243 TJm
-(the) 12.1748 Tj
--240 TJm
-(library) 26.5614 Tj
--240 TJm
-(tak) 12.1748 Tj
-10 TJm
-(es) 8.29918 Tj
--241 TJm
-(an) 9.40507 Tj
--240 TJm
-(open) 19.3681 Tj
--241 TJm
-(\002le) 12.7327 Tj
--240 TJm
-(handle,) 29.0521 Tj
--242 TJm
-(writes) 24.3496 Tj
--241 TJm
-(compress) 37.6303 Tj
-1 TJm
-(ed) 9.40507 Tj
--241 TJm
-(data) 16.5984 Tj
--240 TJm
-(to) 7.75121 Tj
--241 TJm
-(it,) 8.03018 Tj
-[1 0 0 1 398.926 221.967] cm
-0 g
-0 G
-[1 0 0 1 -398.926 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-398.926 221.967 Td
-/F130_0 9.963 Tf
-(fflush) 35.8668 Tj
-[1 0 0 1 434.791 221.967] cm
-0 g
-0 G
-[1 0 0 1 -434.791 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.791 221.967 Td
-/F128_0 9.963 Tf
-(es) 8.29918 Tj
--240 TJm
-(it) 5.53943 Tj
--241 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--240 TJm
-(does) 18.2622 Tj
--241 TJm
-(not) 12.7327 Tj
-[1 0 0 1 504.135 221.967] cm
-0 g
-0 G
-[1 0 0 1 -504.135 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-504.135 221.967 Td
-/F130_0 9.963 Tf
-(fclose) 35.8668 Tj
-[1 0 0 1 540 221.967] cm
-0 g
-0 G
-[1 0 0 1 -540 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 210.012 Td
-/F128_0 9.963 Tf
-(it.) 8.03018 Tj
--610 TJm
-(The) 15.4925 Tj
--235 TJm
-(calling) 27.1193 Tj
--235 TJm
-(application) 44.2756 Tj
--234 TJm
-(can) 13.8286 Tj
--235 TJm
-(write) 20.474 Tj
--235 TJm
-(its) 9.41504 Tj
--235 TJm
-(o) 4.9815 Tj
-25 TJm
-(wn) 12.1748 Tj
--235 TJm
-(data) 16.5984 Tj
--235 TJm
-(before) 25.4455 Tj
--235 TJm
-(and) 14.3866 Tj
--235 TJm
-(after) 18.2522 Tj
--235 TJm
-(the) 12.1748 Tj
--235 TJm
-(compressed) 47.0353 Tj
--235 TJm
-(dat) 12.1748 Tj
-1 TJm
-(a) 4.42357 Tj
--235 TJm
-(stream,) 29.0521 Tj
--238 TJm
-(using) 21.5898 Tj
--235 TJm
-(that) 14.9445 Tj
--235 TJm
-(same) 20.474 Tj
--235 TJm
-(\002le) 12.7327 Tj
-86.944 198.056 Td
-(handle.) 29.0521 Tj
-[1 0 0 1 115.995 198.056] cm
-0 g
-0 G
-[1 0 0 1 -43.995 -21.917] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -176.139] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 176.139 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 176.139] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -176.139] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 176.139 Td
-/F128_0 9.963 Tf
-(Reading) 33.2067 Tj
--236 TJm
-(is) 6.64532 Tj
--236 TJm
-(m) 7.75121 Tj
-1 TJm
-(ore) 12.7228 Tj
--236 TJm
-(comple) 29.3311 Tj
-15 TJm
-(x,) 7.47225 Tj
--239 TJm
-(and) 14.3866 Tj
--236 TJm
-(the) 12.1748 Tj
--235 TJm
-(f) 3.31768 Tj
-10 TJm
-(acilities) 30.9949 Tj
--236 TJm
-(are) 12.1648 Tj
--236 TJm
-(not) 12.7327 Tj
--236 TJm
-(as) 8.29918 Tj
--235 TJm
-(general) 29.3211 Tj
--236 TJm
-(as) 8.29918 Tj
--236 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--236 TJm
-(could) 22.1378 Tj
--236 TJm
-(b) 4.9815 Tj
-1 TJm
-(e) 4.42357 Tj
--236 TJm
-(since) 20.474 Tj
--236 TJm
-(generality) 39.842 Tj
--236 TJm
-(is) 6.64532 Tj
--236 TJm
-(har) 12.7228 Tj
-1 TJm
-(d) 4.9815 Tj
--236 TJm
-(to) 7.75121 Tj
--236 TJm
-(reconcile) 36.5144 Tj
-86.944 164.183 Td
-(with) 17.7142 Tj
--404 TJm
-(ef) 7.74125 Tj
-25 TJm
-(\002cienc) 26.5614 Tj
-15 TJm
-(y) 4.9815 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 164.811 164.183] cm
-0 g
-0 G
-[1 0 0 1 -164.811 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.811 164.183 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 224.587 164.183] cm
-0 g
-0 G
-[1 0 0 1 -224.587 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-228.614 164.183 Td
-/F128_0 9.963 Tf
-(reads) 21.0219 Tj
--404 TJm
-(from) 19.3681 Tj
--404 TJm
-(the) 12.1748 Tj
--405 TJm
-(com) 17.1563 Tj
-1 TJm
-(pressed) 29.879 Tj
--405 TJm
-(\002le) 12.7327 Tj
--404 TJm
-(in) 7.75121 Tj
--404 TJm
-(blocks) 26.0134 Tj
--404 TJm
-(of) 8.29918 Tj
--404 TJm
-(size) 15.4925 Tj
-[1 0 0 1 434.744 164.183] cm
-0 g
-0 G
-[1 0 0 1 -434.744 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.744 164.183 Td
-/F130_0 9.963 Tf
-(BZ_MAX_UNUSED) 77.7114 Tj
-[1 0 0 1 512.452 164.183] cm
-0 g
-0 G
-[1 0 0 1 -512.452 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.479 164.183 Td
-/F128_0 9.963 Tf
-(bytes,) 23.5226 Tj
-86.944 152.228 Td
-(and) 14.3866 Tj
--413 TJm
-(in) 7.75121 Tj
--413 TJm
-(doing) 22.6957 Tj
--413 TJm
-(so) 8.85711 Tj
--413 TJm
-(probably) 35.4185 Tj
--413 TJm
-(wi) 9.963 Tj
-1 TJm
-(ll) 5.53943 Tj
--413 TJm
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(ershoot) 29.3311 Tj
--413 TJm
-(the) 12.1748 Tj
--413 TJm
-(logical) 27.1193 Tj
--413 TJm
-(end) 14.3866 Tj
--413 TJm
-(of) 8.29918 Tj
--413 TJm
-(compressed) 47.0353 Tj
--413 TJm
-(stream.) 29.0521 Tj
--1597 TJm
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--413 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--413 TJm
-(this) 14.3965 Tj
--413 TJm
-(data) 16.5984 Tj
--413 TJm
-(once) 18.8101 Tj
-86.944 140.273 Td
-(decompression) 59.768 Tj
--252 TJm
-(has) 13.2807 Tj
--252 TJm
-(ended,) 26.2824 Tj
--252 TJm
-(call) 14.3866 Tj
-[1 0 0 1 210.705 140.273] cm
-0 g
-0 G
-[1 0 0 1 -210.705 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.705 140.273 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadGetUnused) 113.578 Tj
-[1 0 0 1 324.279 140.273] cm
-0 g
-0 G
-[1 0 0 1 -324.279 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-326.789 140.273 Td
-/F128_0 9.963 Tf
-(after) 18.2522 Tj
--252 TJm
-(the) 12.1748 Tj
--252 TJm
-(last) 13.8386 Tj
--252 TJm
-(call) 14.3866 Tj
--252 TJm
-(of) 8.29918 Tj
-[1 0 0 1 406.291 140.273] cm
-0 g
-0 G
-[1 0 0 1 -406.291 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.291 140.273 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 466.067 140.273] cm
-0 g
-0 G
-[1 0 0 1 -466.067 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.578 140.273 Td
-/F128_0 9.963 Tf
-(\(the) 15.4925 Tj
--252 TJm
-(one) 14.3866 Tj
--252 TJm
-(returning) 36.5244 Tj
-[1 0 0 1 86.944 128.318] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 128.318 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 164.653 128.318] cm
-0 g
-0 G
-[1 0 0 1 -164.653 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.653 128.318 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(before) 25.4455 Tj
--250 TJm
-(calling) 27.1193 Tj
-[1 0 0 1 243.028 128.318] cm
-0 g
-0 G
-[1 0 0 1 -243.028 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.028 128.318 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadClose) 89.667 Tj
-[1 0 0 1 332.692 128.318] cm
-0 g
-0 G
-[1 0 0 1 -332.692 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.692 128.318 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 335.182 128.318] cm
-0 g
-0 G
-[1 0 0 1 -263.182 -77.466] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.754] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.754] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.852 Td
-/F128_0 9.963 Tf
-(24) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 28 28
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--271 TJm
-(mechanism) 45.3815 Tj
--271 TJm
-(mak) 17.1563 Tj
-10 TJm
-(es) 8.29918 Tj
--272 TJm
-(i) 2.76971 Tj
-1 TJm
-(t) 2.76971 Tj
--272 TJm
-(easy) 17.7043 Tj
--271 TJm
-(to) 7.75121 Tj
--271 TJm
-(decompress) 47.0353 Tj
--271 TJm
-(multiple) 33.2166 Tj
-[1 0 0 1 293.313 710.037] cm
-0 g
-0 G
-[1 0 0 1 -293.313 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.313 710.037 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 323.2 710.037] cm
-0 g
-0 G
-[1 0 0 1 -323.2 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-325.903 710.037 Td
-/F128_0 9.963 Tf
-(streams) 30.437 Tj
--271 TJm
-(placed) 26.0034 Tj
--271 TJm
-(end-to-end.) 45.6505 Tj
--374 TJm
-(As) 11.0689 Tj
--271 TJm
-(the) 12.1748 Tj
--272 TJm
-(end) 14.3866 Tj
--271 TJm
-(of) 8.29918 Tj
--271 TJm
-(one) 14.3866 Tj
--271 TJm
-(stream,) 29.0521 Tj
-72 698.082 Td
-(when) 21.5799 Tj
-[1 0 0 1 96.195 698.082] cm
-0 g
-0 G
-[1 0 0 1 -96.195 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-96.195 698.082 Td
-/F130_0 9.963 Tf
-(BZ2_bzRead) 59.778 Tj
-[1 0 0 1 155.971 698.082] cm
-0 g
-0 G
-[1 0 0 1 -155.971 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.586 698.082 Td
-/F128_0 9.963 Tf
-(returns) 27.6673 Tj
-[1 0 0 1 188.868 698.082] cm
-0 g
-0 G
-[1 0 0 1 -188.868 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.868 698.082 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 266.577 698.082] cm
-0 g
-0 G
-[1 0 0 1 -266.577 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.577 698.082 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--263 TJm
-(c) 4.42357 Tj
-1 TJm
-(all) 9.963 Tj
-[1 0 0 1 288.685 698.082] cm
-0 g
-0 G
-[1 0 0 1 -288.685 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-288.685 698.082 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadGetUnused) 113.578 Tj
-[1 0 0 1 402.259 698.082] cm
-0 g
-0 G
-[1 0 0 1 -402.259 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-404.875 698.082 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--262 TJm
-(collect) 26.5614 Tj
--263 TJm
-(the) 12.1748 Tj
--262 TJm
-(unused) 28.2252 Tj
--263 TJm
-(data) 16.5984 Tj
--262 TJm
-(\(cop) 17.7043 Tj
-10 TJm
-(y) 4.9815 Tj
--263 TJm
-(it) 5.53943 Tj
-72 686.127 Td
-(into) 15.5024 Tj
--265 TJm
-(your) 18.2622 Tj
--265 TJm
-(o) 4.9815 Tj
-25 TJm
-(wn) 12.1748 Tj
--265 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--265 TJm
-(some) 21.0319 Tj
-25 TJm
-(where\).) 30.148 Tj
--710 TJm
-(That) 18.2622 Tj
--265 TJm
-(data) 16.5984 Tj
--265 TJm
-(forms) 23.2437 Tj
--265 TJm
-(the) 12.1748 Tj
--265 TJm
-(start) 17.1563 Tj
--265 TJm
-(of) 8.29918 Tj
--265 TJm
-(the) 12.1748 Tj
--265 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--265 TJm
-(compressed) 47.0353 Tj
--265 TJm
-(stream.) 29.0521 Tj
--710 TJm
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--265 TJm
-(start) 17.1563 Tj
--265 TJm
-(uncompressing) 60.326 Tj
-72 674.172 Td
-(that) 14.9445 Tj
--246 TJm
-(ne) 9.40507 Tj
-15 TJm
-(xt) 7.75121 Tj
--246 TJm
-(stream,) 29.0521 Tj
--247 TJm
-(call) 14.3866 Tj
-[1 0 0 1 157.205 674.172] cm
-0 g
-0 G
-[1 0 0 1 -157.205 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-157.205 674.172 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadOpen) 83.6892 Tj
-[1 0 0 1 240.891 674.172] cm
-0 g
-0 G
-[1 0 0 1 -240.891 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.344 674.172 Td
-/F128_0 9.963 Tf
-(ag) 9.40507 Tj
-5 TJm
-(ain,) 14.6655 Tj
--247 TJm
-(feeding) 29.879 Tj
--246 TJm
-(in) 7.75121 Tj
--246 TJm
-(the) 12.1748 Tj
--246 TJm
-(unused) 28.2252 Tj
--246 TJm
-(data) 16.5984 Tj
--246 TJm
-(via) 12.1748 Tj
--247 TJm
-(the) 12.1748 Tj
-[1 0 0 1 405.967 674.172] cm
-0 g
-0 G
-[1 0 0 1 -405.967 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.967 674.172 Td
-/F130_0 9.963 Tf
-(unused) 35.8668 Tj
-[1 0 0 1 441.833 674.172] cm
-0 g
-0 G
-[1 0 0 1 -441.833 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-444.286 674.172 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 449.508 674.172] cm
-0 g
-0 G
-[1 0 0 1 -449.508 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.508 674.172 Td
-/F130_0 9.963 Tf
-(nUnused) 41.8446 Tj
-[1 0 0 1 491.351 674.172] cm
-0 g
-0 G
-[1 0 0 1 -491.351 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.804 674.172 Td
-/F128_0 9.963 Tf
-(parameters.) 46.1984 Tj
-72 662.217 Td
-(K) 7.19329 Tj
-25 TJm
-(eep) 13.8286 Tj
--263 TJm
-(doing) 22.6957 Tj
--263 TJm
-(this) 14.3965 Tj
--263 TJm
-(until) 18.2721 Tj
-[1 0 0 1 158.622 662.217] cm
-0 g
-0 G
-[1 0 0 1 -158.622 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.622 662.217 Td
-/F130_0 9.963 Tf
-(BZ_STREAM_END) 77.7114 Tj
-[1 0 0 1 236.33 662.217] cm
-0 g
-0 G
-[1 0 0 1 -236.33 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.952 662.217 Td
-/F128_0 9.963 Tf
-(return) 23.7916 Tj
--263 TJm
-(coincides) 37.6303 Tj
--263 TJm
-(with) 17.7142 Tj
--263 TJm
-(the) 12.1748 Tj
--263 TJm
-(ph) 9.963 Tj
-5 TJm
-(ysical) 23.2437 Tj
--263 TJm
-(end) 14.3866 Tj
--263 TJm
-(of) 8.29918 Tj
--264 TJm
-(\002le) 12.7327 Tj
--263 TJm
-(\() 3.31768 Tj
-[1 0 0 1 423.125 662.217] cm
-0 g
-0 G
-[1 0 0 1 -423.125 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-423.125 662.217 Td
-/F130_0 9.963 Tf
-(feof\(f\)) 41.8446 Tj
-[1 0 0 1 464.968 662.217] cm
-0 g
-0 G
-[1 0 0 1 -464.968 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-464.968 662.217 Td
-/F128_0 9.963 Tf
-(\).) 5.80843 Tj
--699 TJm
-(In) 8.29918 Tj
--263 TJm
-(this) 14.3965 Tj
--263 TJm
-(situation) 34.3225 Tj
-[1 0 0 1 72 650.262] cm
-0 g
-0 G
-[1 0 0 1 -72 -650.262] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 650.262 Td
-/F130_0 9.963 Tf
-(BZ2_bzReadGetUnused) 113.578 Tj
-[1 0 0 1 185.574 650.262] cm
-0 g
-0 G
-[1 0 0 1 -185.574 -650.262] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.065 650.262 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(course) 26.0034 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(no) 9.963 Tj
--250 TJm
-(data) 16.5984 Tj
-1 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 649.096] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -639.133] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 628.344 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--240 TJm
-(should) 26.5713 Tj
--241 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--240 TJm
-(some) 21.0319 Tj
--240 TJm
-(feel) 14.9345 Tj
--241 TJm
-(for) 11.6169 Tj
--240 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--240 TJm
-(the) 12.1748 Tj
--241 TJm
-(high-le) 28.2252 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--240 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace) 13.2707 Tj
--240 TJm
-(can) 13.8286 Tj
--241 TJm
-(be) 9.40507 Tj
--240 TJm
-(used.) 20.7529 Tj
--614 TJm
-(If) 6.63536 Tj
--240 TJm
-(you) 14.9445 Tj
--240 TJm
-(require) 28.2152 Tj
--241 TJm
-(e) 4.42357 Tj
-15 TJm
-(xtra) 15.4925 Tj
--240 TJm
-(\003e) 9.963 Tj
-15 TJm
-(xibility) 28.7931 Tj
-65 TJm
-(,) 2.49075 Tj
--242 TJm
-(you') 18.2622 Tj
-10 TJm
-(ll) 5.53943 Tj
--241 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--240 TJm
-(to) 7.75121 Tj
-72 616.389 Td
-(bite) 14.9445 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ullet) 17.7142 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(get) 12.1748 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(grip) 16.0504 Tj
-1 TJm
-(s) 3.87561 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace.) 15.7615 Tj
-[1 0 0 1 72 614.232] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -604.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 585.767 Td
-/F121_0 17.215 Tf
-(3.4.9.) 43.0719 Tj
--278 TJm
-(Standar) 64.0914 Tj
-20 TJm
-(d) 10.5184 Tj
--278 TJm
-(\002le-reading/writing) 154.005 Tj
--278 TJm
-(code) 40.1798 Tj
-[1 0 0 1 72 581.937] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -571.974] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 563.85 Td
-/F128_0 9.963 Tf
-(Here') 22.6758 Tj
-55 TJm
-(s) 3.87561 Tj
--250 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(you') 18.2622 Tj
-50 TJm
-(d) 4.9815 Tj
--250 TJm
-(write) 20.474 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(to) 7.75121 Tj
--249 TJm
-(a) 4.42357 Tj
--250 TJm
-(compressed) 47.0353 Tj
--250 TJm
-(\002le:) 15.5024 Tj
-[1 0 0 1 72 561.693] cm
-0 g
-0 G
-[1 0 0 1 0 -371.607] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 370.61 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 367.023] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -552.328] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 552.328 Td
-/F130_0 9.963 Tf
-(FILE*) 29.889 Tj
--1278 TJm
-(f;) 11.9556 Tj
-90 540.373 Td
-(BZFILE*) 41.8446 Tj
--426 TJm
-(b;) 11.9556 Tj
-90 528.418 Td
-(int) 17.9334 Tj
--2130 TJm
-(nBuf;) 29.889 Tj
-90 516.462 Td
-(char) 23.9112 Tj
--1704 TJm
-(buf[) 23.9112 Tj
--426 TJm
-(/*) 11.9556 Tj
--426 TJm
-(whatever) 47.8224 Tj
--425 TJm
-(size) 23.9112 Tj
--426 TJm
-(you) 17.9334 Tj
--426 TJm
-(like) 23.9112 Tj
--426 TJm
-(*/) 11.9556 Tj
--426 TJm
-(];) 11.9556 Tj
-90 504.507 Td
-(int) 17.9334 Tj
--2130 TJm
-(bzerror;) 47.8224 Tj
-90 492.552 Td
-(int) 17.9334 Tj
--2130 TJm
-(nWritten;) 53.8002 Tj
-90 468.642 Td
-(f) 5.9778 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(fopen) 29.889 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-("myfile.bz2") 71.7336 Tj
-1 TJm
-(,) 5.9778 Tj
--426 TJm
-("w") 17.9334 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 456.687 Td
-(if) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(!f) 11.9556 Tj
--426 TJm
-(\)) 5.9778 Tj
--426 TJm
-({) 5.9778 Tj
-94.244 444.731 Td
-(/*) 11.9556 Tj
--426 TJm
-(handle) 35.8668 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(*/) 11.9556 Tj
-90 432.776 Td
-(}) 5.9778 Tj
-90 420.821 Td
-(b) 5.9778 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ2_bzWriteOpen\() 95.6448 Tj
--426 TJm
-(&bze) 23.9112 Tj
-1 TJm
-(rror,) 29.889 Tj
--426 TJm
-(f,) 11.9556 Tj
--426 TJm
-(9) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 408.866 Td
-(if) 11.9556 Tj
--426 TJm
-(\(bzerror) 47.8224 Tj
--426 TJm
-(!=) 11.9556 Tj
--426 TJm
-(BZ_OK\)) 35.8668 Tj
--426 TJm
-({) 5.9778 Tj
-94.244 396.911 Td
-(BZ2_bzWriteClose) 95.6448 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-94.244 384.955 Td
-(/*) 11.9556 Tj
--426 TJm
-(handle) 35.8668 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(*/) 11.9556 Tj
-90 373 Td
-(}) 5.9778 Tj
-90 349.09 Td
-(while) 29.889 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(/*) 11.9556 Tj
--426 TJm
-(condition) 53.8002 Tj
--426 TJm
-(*/) 11.9556 Tj
--425 TJm
-(\)) 5.9778 Tj
--426 TJm
-({) 5.9778 Tj
-94.244 337.135 Td
-(/*) 11.9556 Tj
--426 TJm
-(get) 17.9334 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(to) 11.9556 Tj
--426 TJm
-(write) 29.889 Tj
--426 TJm
-(int) 17.9334 Tj
-1 TJm
-(o) 5.9778 Tj
--426 TJm
-(buf,) 23.9112 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(set) 17.9334 Tj
--426 TJm
-(nBuf) 23.9112 Tj
--426 TJm
-(appropriately) 77.7114 Tj
--426 TJm
-(*/) 11.9556 Tj
-94.244 325.18 Td
-(nWritten) 47.8224 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ2_bzWrite) 65.7558 Tj
--426 TJm
-(\() 5.9778 Tj
--425 TJm
-(&bzerror,) 53.8002 Tj
--426 TJm
-(b,) 11.9556 Tj
--426 TJm
-(buf,) 23.9112 Tj
--426 TJm
-(nBuf) 23.9112 Tj
--426 TJm
-(\);) 11.9556 Tj
-94.244 313.224 Td
-(if) 11.9556 Tj
--426 TJm
-(\(bzerror) 47.8224 Tj
--426 TJm
-(==) 11.9556 Tj
--426 TJm
-(BZ_IO_ERRO) 59.778 Tj
-1 TJm
-(R\)) 11.9556 Tj
--426 TJm
-({) 5.9778 Tj
-102.732 301.269 Td
-(BZ2_bzWriteClose) 95.6448 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(&bzerr) 35.8668 Tj
-1 TJm
-(or,) 17.9334 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-102.732 289.314 Td
-(/*) 11.9556 Tj
--426 TJm
-(handle) 35.8668 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(*/) 11.9556 Tj
-94.244 277.359 Td
-(}) 5.9778 Tj
-90 265.404 Td
-(}) 5.9778 Tj
-90 241.493 Td
-(BZ2_bzWriteClose\() 101.623 Tj
--426 TJm
-(&bzerro) 41.8446 Tj
-1 TJm
-(r,) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 229.538 Td
-(if) 11.9556 Tj
--426 TJm
-(\(bzerror) 47.8224 Tj
--426 TJm
-(==) 11.9556 Tj
--426 TJm
-(BZ_IO_ERRO) 59.778 Tj
-1 TJm
-(R\)) 11.9556 Tj
--426 TJm
-({) 5.9778 Tj
-94.244 217.583 Td
-(/*) 11.9556 Tj
--426 TJm
-(handle) 35.8668 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(*/) 11.9556 Tj
-90 205.628 Td
-(}) 5.9778 Tj
-[1 0 0 1 72 190.086] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -180.124] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 168.168 Td
-/F128_0 9.963 Tf
-(And) 17.1563 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(read) 17.1463 Tj
--250 TJm
-(from) 19.3681 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(compresse) 42.0538 Tj
-1 TJm
-(d) 4.9815 Tj
--250 TJm
-(\002le:) 15.5024 Tj
-[1 0 0 1 72 166.012] cm
-0 g
-0 G
-[1 0 0 1 0 -115.16] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(25) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 29 29
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -392.164] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 370.61 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 367.024] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(FILE*) 29.889 Tj
--1278 TJm
-(f;) 11.9556 Tj
-90 699.676 Td
-(BZFILE*) 41.8446 Tj
--426 TJm
-(b;) 11.9556 Tj
-90 687.721 Td
-(int) 17.9334 Tj
--2130 TJm
-(nBuf;) 29.889 Tj
-90 675.766 Td
-(char) 23.9112 Tj
--1704 TJm
-(buf[) 23.9112 Tj
--426 TJm
-(/*) 11.9556 Tj
--426 TJm
-(whatever) 47.8224 Tj
--425 TJm
-(size) 23.9112 Tj
--426 TJm
-(you) 17.9334 Tj
--426 TJm
-(like) 23.9112 Tj
--426 TJm
-(*/) 11.9556 Tj
--426 TJm
-(];) 11.9556 Tj
-90 663.811 Td
-(int) 17.9334 Tj
--2130 TJm
-(bzerror;) 47.8224 Tj
-90 651.856 Td
-(int) 17.9334 Tj
--2130 TJm
-(nWritten;) 53.8002 Tj
-90 627.945 Td
-(f) 5.9778 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(fopen) 29.889 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-("myfile.bz2") 71.7336 Tj
-1 TJm
-(,) 5.9778 Tj
--426 TJm
-("r") 17.9334 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 615.99 Td
-(if) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(!f) 11.9556 Tj
--426 TJm
-(\)) 5.9778 Tj
--426 TJm
-({) 5.9778 Tj
-98.488 604.035 Td
-(/*) 11.9556 Tj
--426 TJm
-(handle) 35.8668 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(*/) 11.9556 Tj
-90 592.08 Td
-(}) 5.9778 Tj
-90 580.125 Td
-(b) 5.9778 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ2_bzReadOpen) 83.6892 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(&bz) 17.9334 Tj
-1 TJm
-(error,) 35.8668 Tj
--426 TJm
-(f,) 11.9556 Tj
--426 TJm
-(0,) 11.9556 Tj
--426 TJm
-(NULL,) 29.889 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 568.169 Td
-(if) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(!=) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
--426 TJm
-(\)) 5.9778 Tj
--425 TJm
-({) 5.9778 Tj
-98.488 556.214 Td
-(BZ2_bzReadClose) 89.667 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(&bzerro) 41.8446 Tj
-1 TJm
-(r,) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-98.488 544.259 Td
-(/*) 11.9556 Tj
--426 TJm
-(handle) 35.8668 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(*/) 11.9556 Tj
-90 532.304 Td
-(}) 5.9778 Tj
-90 508.393 Td
-(bzerror) 41.8446 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ_OK;) 35.8668 Tj
-90 496.438 Td
-(while) 29.889 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(==) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
--425 TJm
-(&&) 11.9556 Tj
--426 TJm
-(/*) 11.9556 Tj
--426 TJm
-(arbitrary) 53.8002 Tj
--426 TJm
-(other) 29.889 Tj
--426 TJm
-(conditions) 59.778 Tj
--426 TJm
-(*/\)) 17.9334 Tj
--426 TJm
-({) 5.9778 Tj
-98.488 484.483 Td
-(nBuf) 23.9112 Tj
--426 TJm
-(=) 5.9778 Tj
--426 TJm
-(BZ2_bzRead) 59.778 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(&bze) 23.9112 Tj
-1 TJm
-(rror,) 29.889 Tj
--426 TJm
-(b,) 11.9556 Tj
--426 TJm
-(buf,) 23.9112 Tj
--426 TJm
-(/*) 11.9556 Tj
--426 TJm
-(size) 23.9112 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(buf) 17.9334 Tj
--426 TJm
-(*/) 11.9556 Tj
--426 TJm
-(\);) 11.9556 Tj
-98.488 472.528 Td
-(if) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(==) 11.9556 Tj
--426 TJm
-(BZ_OK) 29.889 Tj
--426 TJm
-(\)) 5.9778 Tj
--425 TJm
-({) 5.9778 Tj
-106.976 460.573 Td
-(/*) 11.9556 Tj
--426 TJm
-(do) 11.9556 Tj
--426 TJm
-(something) 53.8002 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(buf) 17.9334 Tj
-1 TJm
-([0) 11.9556 Tj
--426 TJm
-(..) 11.9556 Tj
--426 TJm
-(nBuf-1]) 41.8446 Tj
--426 TJm
-(*/) 11.9556 Tj
-98.488 448.618 Td
-(}) 5.9778 Tj
-90 436.662 Td
-(}) 5.9778 Tj
-90 424.707 Td
-(if) 11.9556 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(bzerror) 41.8446 Tj
--426 TJm
-(!=) 11.9556 Tj
--426 TJm
-(BZ_STREAM) 53.8002 Tj
-1 TJm
-(_END) 23.9112 Tj
--426 TJm
-(\)) 5.9778 Tj
--426 TJm
-({) 5.9778 Tj
-102.732 412.752 Td
-(BZ2_bzReadClose) 89.667 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(&bzerro) 41.8446 Tj
-1 TJm
-(r,) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-102.732 400.797 Td
-(/*) 11.9556 Tj
--426 TJm
-(handle) 35.8668 Tj
--426 TJm
-(error) 29.889 Tj
--426 TJm
-(*/) 11.9556 Tj
-90 388.842 Td
-(}) 5.9778 Tj
--426 TJm
-(else) 23.9112 Tj
--426 TJm
-({) 5.9778 Tj
-102.732 376.887 Td
-(BZ2_bzReadClose) 89.667 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(&bzerro) 41.8446 Tj
-1 TJm
-(r) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 364.931 Td
-(}) 5.9778 Tj
-[1 0 0 1 72 349.39] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -339.427] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 314.637 Td
-/F121_0 20.659 Tf
-(3.5.) 34.4592 Tj
--278 TJm
-(Utility) 57.3907 Tj
--278 TJm
-(functions) 92.9655 Tj
-[1 0 0 1 72 310.361] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -300.398] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 284.016 Td
-/F121_0 17.215 Tf
-(3.5.1.) 43.0719 Tj
-[1 0 0 1 119.858 284.016] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -284.016] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 284.016 Td
-/F387_0 17.215 Tf
-(BZ2_bzBuffToBuffCompress) 247.896 Tj
-[1 0 0 1 367.76 284.016] cm
-0 g
-0 G
-[1 0 0 1 -295.76 -2.333] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -96.638] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 95.641 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 92.055] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -272.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 272.318 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzBuffToBuffCompr) 125.534 Tj
-1 TJm
-(ess\() 23.9112 Tj
--426 TJm
-(char*) 29.889 Tj
--3834 TJm
-(dest,) 29.889 Tj
-217.319 260.363 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(destLen,) 47.8224 Tj
-217.319 248.408 Td
-(char*) 29.889 Tj
--3834 TJm
-(source,) 41.8446 Tj
-217.319 236.453 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--852 TJm
-(sourceLen,) 59.778 Tj
-217.319 224.498 Td
-(int) 17.9334 Tj
--4686 TJm
-(blockSize) 53.8002 Tj
-1 TJm
-(100k,) 29.889 Tj
-217.319 212.542 Td
-(int) 17.9334 Tj
--4686 TJm
-(verbosity) 53.8002 Tj
-1 TJm
-(,) 5.9778 Tj
-217.319 200.587 Td
-(int) 17.9334 Tj
--4686 TJm
-(workFacto) 53.8002 Tj
-1 TJm
-(r) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 185.045] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -175.083] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 163.128 Td
-/F128_0 9.963 Tf
-(Attempts) 36.5343 Tj
--442 TJm
-(to) 7.75121 Tj
--442 TJm
-(compress) 37.6303 Tj
--442 TJm
-(the) 12.1748 Tj
--442 TJm
-(data) 16.5984 Tj
--443 TJm
-(in) 7.75121 Tj
-[1 0 0 1 216.87 163.128] cm
-0 g
-0 G
-[1 0 0 1 -216.87 -163.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.87 163.128 Td
-/F130_0 9.963 Tf
-(source[0) 47.8224 Tj
--600 TJm
-(..) 11.9556 Tj
--1200 TJm
-(sourceLen-1]) 71.7336 Tj
-[1 0 0 1 366.309 163.128] cm
-0 g
-0 G
-[1 0 0 1 -366.309 -163.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.715 163.128 Td
-/F128_0 9.963 Tf
-(into) 15.5024 Tj
--442 TJm
-(the) 12.1748 Tj
--442 TJm
-(destination) 43.7276 Tj
--442 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-40 TJm
-(,) 2.49075 Tj
-[1 0 0 1 486.202 163.128] cm
-0 g
-0 G
-[1 0 0 1 -486.202 -163.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 163.128 Td
-/F130_0 9.963 Tf
-(dest[0) 35.8668 Tj
--600 TJm
-(..) 11.9556 Tj
-72 151.173 Td
-(*destLen-1]) 65.7558 Tj
-[1 0 0 1 137.753 151.173] cm
-0 g
-0 G
-[1 0 0 1 -137.753 -151.173] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.753 151.173 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1393 TJm
-(If) 6.63536 Tj
--379 TJm
-(the) 12.1748 Tj
--379 TJm
-(destinat) 30.9949 Tj
-1 TJm
-(ion) 12.7327 Tj
--379 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--379 TJm
-(is) 6.64532 Tj
--379 TJm
-(big) 12.7327 Tj
--379 TJm
-(enoug) 24.3496 Tj
-1 TJm
-(h,) 7.47225 Tj
-[1 0 0 1 318.487 151.173] cm
-0 g
-0 G
-[1 0 0 1 -318.487 -151.173] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-318.487 151.173 Td
-/F130_0 9.963 Tf
-(*destLen) 47.8224 Tj
-[1 0 0 1 366.307 151.173] cm
-0 g
-0 G
-[1 0 0 1 -366.307 -151.173] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.082 151.173 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--379 TJm
-(set) 11.0689 Tj
--379 TJm
-(t) 2.76971 Tj
-1 TJm
-(o) 4.9815 Tj
--379 TJm
-(the) 12.1748 Tj
--379 TJm
-(size) 15.4925 Tj
--379 TJm
-(of) 8.29918 Tj
--379 TJm
-(the) 12.1748 Tj
--378 TJm
-(compressed) 47.0353 Tj
--379 TJm
-(data,) 19.0891 Tj
-72 139.217 Td
-(and) 14.3866 Tj
-[1 0 0 1 89.527 139.217] cm
-0 g
-0 G
-[1 0 0 1 -89.527 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-89.527 139.217 Td
-/F130_0 9.963 Tf
-(BZ_OK) 29.889 Tj
-[1 0 0 1 119.415 139.217] cm
-0 g
-0 G
-[1 0 0 1 -119.415 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.556 139.217 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--315 TJm
-(returned.) 35.6875 Tj
--1012 TJm
-(If) 6.63536 Tj
--315 TJm
-(the) 12.1748 Tj
--315 TJm
-(compressed) 47.0353 Tj
--316 TJm
-(da) 9.40507 Tj
-1 TJm
-(ta) 7.19329 Tj
--316 TJm
-(w) 7.19329 Tj
-10 TJm
-(on') 13.2807 Tj
-18 TJm
-(t) 2.76971 Tj
--315 TJm
-(\002t,) 10.7999 Tj
-[1 0 0 1 313.323 139.217] cm
-0 g
-0 G
-[1 0 0 1 -313.323 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-313.323 139.217 Td
-/F130_0 9.963 Tf
-(*destLen) 47.8224 Tj
-[1 0 0 1 361.143 139.217] cm
-0 g
-0 G
-[1 0 0 1 -361.143 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-364.285 139.217 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--315 TJm
-(unchanged,) 45.6505 Tj
--332 TJm
-(and) 14.3866 Tj
-[1 0 0 1 440.551 139.217] cm
-0 g
-0 G
-[1 0 0 1 -440.551 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-440.551 139.217 Td
-/F130_0 9.963 Tf
-(BZ_OUTBUFF_FULL) 89.667 Tj
-[1 0 0 1 530.214 139.217] cm
-0 g
-0 G
-[1 0 0 1 -530.214 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 139.217 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
-72 127.262 Td
-(returned.) 35.6875 Tj
-[1 0 0 1 72 127.163] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -117.2] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 105.344 Td
-/F128_0 9.963 Tf
-(Compression) 52.5847 Tj
--297 TJm
-(in) 7.75121 Tj
--297 TJm
-(this) 14.3965 Tj
--297 TJm
-(manner) 29.879 Tj
--297 TJm
-(is) 6.64532 Tj
--297 TJm
-(a) 4.42357 Tj
--297 TJm
-(one-shot) 34.3126 Tj
--297 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ent,) 14.6655 Tj
--308 TJm
-(done) 19.3681 Tj
--297 TJm
-(with) 17.7142 Tj
--297 TJm
-(a) 4.42357 Tj
--297 TJm
-(single) 23.8016 Tj
--297 TJm
-(call) 14.3866 Tj
--297 TJm
-(to) 7.75121 Tj
--297 TJm
-(this) 14.3965 Tj
--297 TJm
-(function.) 35.6974 Tj
--902 TJm
-(The) 15.4925 Tj
--297 TJm
-(resulting) 34.8705 Tj
--297 TJm
-(compressed) 47.0353 Tj
-72 93.389 Td
-(data) 16.5984 Tj
--296 TJm
-(is) 6.64532 Tj
--296 TJm
-(a) 4.42357 Tj
--296 TJm
-(complete) 36.5244 Tj
-[1 0 0 1 147.987 93.389] cm
-0 g
-0 G
-[1 0 0 1 -147.987 -93.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.987 93.389 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 177.875 93.389] cm
-0 g
-0 G
-[1 0 0 1 -177.875 -93.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-180.825 93.389 Td
-/F128_0 9.963 Tf
-(format) 26.5614 Tj
--296 TJm
-(data) 16.5984 Tj
--296 TJm
-(stream.) 29.0521 Tj
--896 TJm
-(There) 23.2337 Tj
--296 TJm
-(is) 6.64532 Tj
--296 TJm
-(no) 9.963 Tj
--296 TJm
-(mechanism) 45.3815 Tj
--296 TJm
-(for) 11.6169 Tj
--296 TJm
-(making) 29.889 Tj
--296 TJm
-(additional) 39.852 Tj
--296 TJm
-(calls) 18.2622 Tj
--296 TJm
-(to) 7.75121 Tj
--296 TJm
-(pro) 13.2807 Tj
-15 TJm
-(vide) 17.1563 Tj
--296 TJm
-(e) 4.42357 Tj
-15 TJm
-(xtra) 15.4925 Tj
-72 81.434 Td
-(input) 20.4839 Tj
--250 TJm
-(data.) 19.0891 Tj
--620 TJm
-(If) 6.63536 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(k) 4.9815 Tj
-1 TJm
-(ind) 12.7327 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(mechanism,) 47.8722 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(lo) 7.75121 Tj
-25 TJm
-(w-le) 17.7043 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(el) 7.19329 Tj
--250 TJm
-(interf) 21.5799 Tj
-10 TJm
-(ace.) 15.7615 Tj
-[1 0 0 1 72 79.277] cm
-0 g
-0 G
-[1 0 0 1 0 -28.425] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(26) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 30 30
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--223 TJm
-(the) 12.1748 Tj
--224 TJm
-(meaning) 34.3126 Tj
--223 TJm
-(of) 8.29918 Tj
--223 TJm
-(parameters) 43.7077 Tj
-[1 0 0 1 195.306 710.037] cm
-0 g
-0 G
-[1 0 0 1 -195.306 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-195.306 710.037 Td
-/F130_0 9.963 Tf
-(blockSize100k) 77.7114 Tj
-[1 0 0 1 273.015 710.037] cm
-0 g
-0 G
-[1 0 0 1 -273.015 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-273.015 710.037 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 277.784 710.037] cm
-0 g
-0 G
-[1 0 0 1 -277.784 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.784 710.037 Td
-/F130_0 9.963 Tf
-(verbosity) 53.8002 Tj
-[1 0 0 1 331.583 710.037] cm
-0 g
-0 G
-[1 0 0 1 -331.583 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.808 710.037 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 350.42 710.037] cm
-0 g
-0 G
-[1 0 0 1 -350.42 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-350.42 710.037 Td
-/F130_0 9.963 Tf
-(workFactor) 59.778 Tj
-[1 0 0 1 410.196 710.037] cm
-0 g
-0 G
-[1 0 0 1 -410.196 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.196 710.037 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--229 TJm
-(see) 12.7228 Tj
-[1 0 0 1 429.913 710.037] cm
-0 g
-0 G
-[1 0 0 1 -429.913 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.913 710.037 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 537.509 710.037] cm
-0 g
-0 G
-[1 0 0 1 -537.509 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 710.037 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 707.881] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -697.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 688.12 Td
-/F128_0 9.963 Tf
-(T) 6.08739 Tj
-80 TJm
-(o) 4.9815 Tj
--410 TJm
-(guarantee) 38.7262 Tj
--410 TJm
-(that) 14.9445 Tj
--410 TJm
-(the) 12.1748 Tj
--410 TJm
-(compressed) 47.0353 Tj
--410 TJm
-(data) 16.5984 Tj
--410 TJm
-(will) 15.5024 Tj
--410 TJm
-(\002) 5.53943 Tj
-1 TJm
-(t) 2.76971 Tj
--411 TJm
-(i) 2.76971 Tj
-1 TJm
-(n) 4.9815 Tj
--411 TJm
-(i) 2.76971 Tj
-1 TJm
-(ts) 6.64532 Tj
--410 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-40 TJm
-(,) 2.49075 Tj
--450 TJm
-(allocate) 30.9849 Tj
--410 TJm
-(an) 9.40507 Tj
--410 TJm
-(output) 25.4654 Tj
--410 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--410 TJm
-(of) 8.29918 Tj
--410 TJm
-(size) 15.4925 Tj
--410 TJm
-(1%) 13.2807 Tj
--410 TJm
-(lar) 10.511 Tj
-18 TJm
-(ger) 12.7228 Tj
--410 TJm
-(than) 17.1563 Tj
--410 TJm
-(the) 12.1748 Tj
-72 676.164 Td
-(uncompressed) 56.9983 Tj
--250 TJm
-(data,) 19.0891 Tj
--250 TJm
-(plus) 16.6083 Tj
--250 TJm
-(six) 11.6268 Tj
--249 TJm
-(hundred) 32.6488 Tj
--250 TJm
-(e) 4.42357 Tj
-15 TJm
-(xtra) 15.4925 Tj
--250 TJm
-(bytes.) 23.5226 Tj
-[1 0 0 1 72 674.008] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -664.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 654.247 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffDecompress) 155.423 Tj
-[1 0 0 1 227.417 654.247] cm
-0 g
-0 G
-[1 0 0 1 -227.417 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.553 654.247 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--315 TJm
-(not) 12.7327 Tj
--314 TJm
-(write) 20.474 Tj
--315 TJm
-(data) 16.5984 Tj
--315 TJm
-(at) 7.19329 Tj
--315 TJm
-(or) 8.29918 Tj
--314 TJm
-(be) 9.40507 Tj
-15 TJm
-(yond) 19.926 Tj
-[1 0 0 1 362.484 654.247] cm
-0 g
-0 G
-[1 0 0 1 -362.484 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-362.484 654.247 Td
-/F130_0 9.963 Tf
-(dest[*destLen]) 83.6892 Tj
-[1 0 0 1 446.17 654.247] cm
-0 g
-0 G
-[1 0 0 1 -446.17 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.17 654.247 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--331 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--315 TJm
-(in) 7.75121 Tj
--314 TJm
-(case) 17.1463 Tj
--315 TJm
-(of) 8.29918 Tj
--315 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-72 642.291 Td
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er\003o) 18.2622 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 642.192] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -632.229] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 620.374 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 620.274] cm
-0 g
-0 G
-[1 0 0 1 0 -168.369] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 167.372 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 163.786] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -610.909] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 610.909 Td
-/F130_0 9.963 Tf
-(BZ_CONFIG_ERROR) 89.667 Tj
-98.488 598.954 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(library) 41.8446 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--425 TJm
-(mis-compiled) 71.7336 Tj
-90 586.999 Td
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 575.044 Td
-(if) 11.9556 Tj
--426 TJm
-(dest) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(destL) 29.889 Tj
-1 TJm
-(en) 11.9556 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-98.488 563.088 Td
-(or) 11.9556 Tj
--426 TJm
-(blockSize100k) 77.7114 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(1) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--425 TJm
-(blockSize100k) 77.7114 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(9) 5.9778 Tj
-98.488 551.133 Td
-(or) 11.9556 Tj
--426 TJm
-(verbosity) 53.8002 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(verb) 23.9112 Tj
-1 TJm
-(osity) 29.889 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(4) 5.9778 Tj
-98.488 539.178 Td
-(or) 11.9556 Tj
--426 TJm
-(workFactor) 59.778 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(wor) 17.9334 Tj
-1 TJm
-(kFactor) 41.8446 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(250) 17.9334 Tj
-90 527.223 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 515.268 Td
-(if) 11.9556 Tj
--426 TJm
-(insufficient) 71.7336 Tj
--426 TJm
-(memory) 35.8668 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(available) 53.8002 Tj
-90 503.313 Td
-(BZ_OUTBUFF_FULL) 89.667 Tj
-98.488 491.357 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(size) 23.9112 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compr) 29.889 Tj
-1 TJm
-(essed) 29.889 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(exceeds) 41.8446 Tj
--426 TJm
-(*destLen) 47.8224 Tj
-90 479.402 Td
-(BZ_OK) 29.889 Tj
-98.488 467.447 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 451.905] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -441.943] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 421.284 Td
-/F121_0 17.215 Tf
-(3.5.2.) 43.0719 Tj
-[1 0 0 1 119.858 421.284] cm
-0 g
-0 G
-[1 0 0 1 -119.858 -421.284] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 421.284 Td
-/F387_0 17.215 Tf
-(BZ2_bzBuffToBuffDecompress) 268.554 Tj
-[1 0 0 1 388.419 421.284] cm
-0 g
-0 G
-[1 0 0 1 -316.419 -2.332] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -84.683] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 83.686 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 80.099] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -409.587] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 409.587 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzBuffToBuffDecom) 125.534 Tj
-1 TJm
-(press\() 35.8668 Tj
--426 TJm
-(char*) 29.889 Tj
--3834 TJm
-(dest,) 29.889 Tj
-225.807 397.632 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int*) 23.9112 Tj
--426 TJm
-(destLen,) 47.8224 Tj
-225.807 385.676 Td
-(char*) 29.889 Tj
--3834 TJm
-(source,) 41.8446 Tj
-225.807 373.721 Td
-(unsigned) 47.8224 Tj
--426 TJm
-(int) 17.9334 Tj
--852 TJm
-(sourceLen,) 59.778 Tj
-225.807 361.766 Td
-(int) 17.9334 Tj
--4686 TJm
-(small,) 35.8668 Tj
-225.807 349.811 Td
-(int) 17.9334 Tj
--4686 TJm
-(verbosity) 53.8002 Tj
--425 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 334.269] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -324.307] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 312.351 Td
-/F128_0 9.963 Tf
-(Attempts) 36.5343 Tj
--358 TJm
-(to) 7.75121 Tj
--358 TJm
-(decompress) 47.0353 Tj
--359 TJm
-(the) 12.1748 Tj
--358 TJm
-(data) 16.5984 Tj
--358 TJm
-(in) 7.75121 Tj
-[1 0 0 1 221.259 312.351] cm
-0 g
-0 G
-[1 0 0 1 -221.259 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.259 312.351 Td
-/F130_0 9.963 Tf
-(source[0) 47.8224 Tj
--600 TJm
-(..) 11.9556 Tj
--1200 TJm
-(sourceLen-1) 65.7558 Tj
-1 TJm
-(]) 5.9778 Tj
-[1 0 0 1 370.698 312.351] cm
-0 g
-0 G
-[1 0 0 1 -370.698 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.268 312.351 Td
-/F128_0 9.963 Tf
-(into) 15.5024 Tj
--358 TJm
-(the) 12.1748 Tj
--359 TJm
-(des) 13.2807 Tj
-1 TJm
-(tination) 30.4469 Tj
--359 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-40 TJm
-(,) 2.49075 Tj
-[1 0 0 1 486.202 312.351] cm
-0 g
-0 G
-[1 0 0 1 -486.202 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 312.351 Td
-/F130_0 9.963 Tf
-(dest[0) 35.8668 Tj
--600 TJm
-(..) 11.9556 Tj
-72 300.396 Td
-(*destLen-1]) 65.7558 Tj
-[1 0 0 1 137.753 300.396] cm
-0 g
-0 G
-[1 0 0 1 -137.753 -300.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.753 300.396 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1123 TJm
-(If) 6.63536 Tj
--334 TJm
-(the) 12.1748 Tj
--334 TJm
-(destination) 43.7276 Tj
--334 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--334 TJm
-(is) 6.64532 Tj
--333 TJm
-(big) 12.7327 Tj
--334 TJm
-(enough,) 31.8218 Tj
-[1 0 0 1 312.554 300.396] cm
-0 g
-0 G
-[1 0 0 1 -312.554 -300.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-312.554 300.396 Td
-/F130_0 9.963 Tf
-(*destLen) 47.8224 Tj
-[1 0 0 1 360.374 300.396] cm
-0 g
-0 G
-[1 0 0 1 -360.374 -300.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.701 300.396 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--334 TJm
-(set) 11.0689 Tj
--334 TJm
-(to) 7.75121 Tj
--334 TJm
-(th) 7.75121 Tj
-1 TJm
-(e) 4.42357 Tj
--334 TJm
-(size) 15.4925 Tj
--334 TJm
-(of) 8.29918 Tj
--334 TJm
-(the) 12.1748 Tj
--334 TJm
-(uncompressed) 56.9983 Tj
--334 TJm
-(d) 4.9815 Tj
-1 TJm
-(ata,) 14.1076 Tj
-72 288.441 Td
-(and) 14.3866 Tj
-[1 0 0 1 89.527 288.441] cm
-0 g
-0 G
-[1 0 0 1 -89.527 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-89.527 288.441 Td
-/F130_0 9.963 Tf
-(BZ_OK) 29.889 Tj
-[1 0 0 1 119.415 288.441] cm
-0 g
-0 G
-[1 0 0 1 -119.415 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.556 288.441 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--315 TJm
-(returned.) 35.6875 Tj
--1012 TJm
-(If) 6.63536 Tj
--315 TJm
-(the) 12.1748 Tj
--315 TJm
-(compressed) 47.0353 Tj
--316 TJm
-(da) 9.40507 Tj
-1 TJm
-(ta) 7.19329 Tj
--316 TJm
-(w) 7.19329 Tj
-10 TJm
-(on') 13.2807 Tj
-18 TJm
-(t) 2.76971 Tj
--315 TJm
-(\002t,) 10.7999 Tj
-[1 0 0 1 313.323 288.441] cm
-0 g
-0 G
-[1 0 0 1 -313.323 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-313.323 288.441 Td
-/F130_0 9.963 Tf
-(*destLen) 47.8224 Tj
-[1 0 0 1 361.143 288.441] cm
-0 g
-0 G
-[1 0 0 1 -361.143 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-364.285 288.441 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--315 TJm
-(unchanged,) 45.6505 Tj
--332 TJm
-(and) 14.3866 Tj
-[1 0 0 1 440.551 288.441] cm
-0 g
-0 G
-[1 0 0 1 -440.551 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-440.551 288.441 Td
-/F130_0 9.963 Tf
-(BZ_OUTBUFF_FULL) 89.667 Tj
-[1 0 0 1 530.214 288.441] cm
-0 g
-0 G
-[1 0 0 1 -530.214 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 288.441 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
-72 276.486 Td
-(returned.) 35.6875 Tj
-[1 0 0 1 72 276.386] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -266.424] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 254.568 Td
-/F130_0 9.963 Tf
-(source) 35.8668 Tj
-[1 0 0 1 107.865 254.568] cm
-0 g
-0 G
-[1 0 0 1 -107.865 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-110.981 254.568 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--313 TJm
-(assumed) 34.3126 Tj
--312 TJm
-(to) 7.75121 Tj
--313 TJm
-(hold) 17.7142 Tj
--313 TJm
-(a) 4.42357 Tj
--312 TJm
-(complete) 36.5244 Tj
-[1 0 0 1 237.04 254.568] cm
-0 g
-0 G
-[1 0 0 1 -237.04 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.04 254.568 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 266.928 254.568] cm
-0 g
-0 G
-[1 0 0 1 -266.928 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-270.044 254.568 Td
-/F128_0 9.963 Tf
-(format) 26.5614 Tj
--313 TJm
-(dat) 12.1748 Tj
-1 TJm
-(a) 4.42357 Tj
--313 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 353.446 254.568] cm
-0 g
-0 G
-[1 0 0 1 -353.446 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.446 254.568 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffDecompres) 149.445 Tj
-1 TJm
-(s) 5.9778 Tj
-[1 0 0 1 508.863 254.568] cm
-0 g
-0 G
-[1 0 0 1 -508.863 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.979 254.568 Td
-/F128_0 9.963 Tf
-(tries) 17.1563 Tj
--313 TJm
-(to) 7.75121 Tj
-72 242.613 Td
-(decompress) 47.0353 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(entirety) 30.437 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--250 TJm
-(stream) 26.5614 Tj
--250 TJm
-(into) 15.5024 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(output) 25.4654 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 240.456] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -230.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 220.695 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(meaning) 34.3126 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(parameter) 39.8321 Tj
-1 TJm
-(s) 3.87561 Tj
-[1 0 0 1 196.631 220.695] cm
-0 g
-0 G
-[1 0 0 1 -196.631 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.631 220.695 Td
-/F130_0 9.963 Tf
-(small) 29.889 Tj
-[1 0 0 1 226.519 220.695] cm
-0 g
-0 G
-[1 0 0 1 -226.519 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.01 220.695 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 245.887 220.695] cm
-0 g
-0 G
-[1 0 0 1 -245.887 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.887 220.695 Td
-/F130_0 9.963 Tf
-(verbosity) 53.8002 Tj
-[1 0 0 1 299.685 220.695] cm
-0 g
-0 G
-[1 0 0 1 -299.685 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.685 220.695 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(see) 12.7228 Tj
-[1 0 0 1 319.879 220.695] cm
-0 g
-0 G
-[1 0 0 1 -319.879 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-319.879 220.695 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressInit) 119.556 Tj
-[1 0 0 1 439.431 220.695] cm
-0 g
-0 G
-[1 0 0 1 -439.431 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-439.431 220.695 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 218.538] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -208.576] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 198.777 Td
-/F128_0 9.963 Tf
-(Because) 33.1967 Tj
--249 TJm
-(the) 12.1748 Tj
--250 TJm
-(compression) 50.363 Tj
--249 TJm
-(ratio) 18.2622 Tj
--250 TJm
-(of) 8.29918 Tj
--249 TJm
-(the) 12.1748 Tj
--250 TJm
-(compressed) 47.0353 Tj
--249 TJm
-(data) 16.5984 Tj
--250 TJm
-(canno) 23.7916 Tj
-1 TJm
-(t) 2.76971 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(kno) 14.9445 Tj
-25 TJm
-(w) 7.19329 Tj
-1 TJm
-(n) 4.9815 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(adv) 14.3866 Tj
-25 TJm
-(a) 4.42357 Tj
-1 TJm
-(nce,) 16.3194 Tj
--250 TJm
-(there) 19.916 Tj
--250 TJm
-(is) 6.64532 Tj
--249 TJm
-(no) 9.963 Tj
--250 TJm
-(easy) 17.7043 Tj
--249 TJm
-(w) 7.19329 Tj
-10 TJm
-(ay) 9.40507 Tj
--250 TJm
-(to) 7.75121 Tj
--249 TJm
-(guarantee) 38.7262 Tj
-72 186.822 Td
-(that) 14.9445 Tj
--286 TJm
-(the) 12.1748 Tj
--287 TJm
-(output) 25.4654 Tj
--286 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
--286 TJm
-(will) 15.5024 Tj
--287 TJm
-(be) 9.40507 Tj
--286 TJm
-(big) 12.7327 Tj
--286 TJm
-(enough.) 31.8218 Tj
--839 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--286 TJm
-(may) 17.1563 Tj
--286 TJm
-(of) 8.29918 Tj
--287 TJm
-(course) 26.0034 Tj
--286 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--286 TJm
-(arrangements) 53.6707 Tj
--287 TJm
-(in) 7.75121 Tj
--286 TJm
-(your) 18.2622 Tj
--286 TJm
-(code) 18.8101 Tj
--287 TJm
-(to) 7.75121 Tj
--286 TJm
-(record) 25.4455 Tj
--286 TJm
-(the) 12.1748 Tj
--287 TJm
-(size) 15.4925 Tj
--286 TJm
-(of) 8.29918 Tj
-72 174.867 Td
-(the) 12.1748 Tj
--250 TJm
-(uncompressed) 56.9983 Tj
--250 TJm
-(data,) 19.0891 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(su) 8.85711 Tj
-1 TJm
-(ch) 9.40507 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(mechanism) 45.3815 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(be) 9.40507 Tj
-15 TJm
-(yond) 19.926 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(scope) 22.6858 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(library) 26.5614 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 172.71] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -162.747] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 152.949 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffDecompress) 155.423 Tj
-[1 0 0 1 227.417 152.949] cm
-0 g
-0 G
-[1 0 0 1 -227.417 -152.949] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.553 152.949 Td
-/F128_0 9.963 Tf
-(will) 15.5024 Tj
--315 TJm
-(not) 12.7327 Tj
--314 TJm
-(write) 20.474 Tj
--315 TJm
-(data) 16.5984 Tj
--315 TJm
-(at) 7.19329 Tj
--315 TJm
-(or) 8.29918 Tj
--314 TJm
-(be) 9.40507 Tj
-15 TJm
-(yond) 19.926 Tj
-[1 0 0 1 362.484 152.949] cm
-0 g
-0 G
-[1 0 0 1 -362.484 -152.949] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-362.484 152.949 Td
-/F130_0 9.963 Tf
-(dest[*destLen]) 83.6892 Tj
-[1 0 0 1 446.17 152.949] cm
-0 g
-0 G
-[1 0 0 1 -446.17 -152.949] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.17 152.949 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--331 TJm
-(e) 4.42357 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(en) 9.40507 Tj
--315 TJm
-(in) 7.75121 Tj
--314 TJm
-(case) 17.1463 Tj
--315 TJm
-(of) 8.29918 Tj
--315 TJm
-(b) 4.9815 Tj
-20 TJm
-(uf) 8.29918 Tj
-25 TJm
-(fer) 11.0589 Tj
-72 140.994 Td
-(o) 4.9815 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(er\003o) 18.2622 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 140.894] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -130.932] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 119.076 Td
-/F128_0 9.963 Tf
-(Possible) 33.2166 Tj
--250 TJm
-(return) 23.7916 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues:) 23.2437 Tj
-[1 0 0 1 72 118.977] cm
-0 g
-0 G
-[1 0 0 1 0 -68.125] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(27) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 31 31
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 4.384 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -352.044 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-436.124 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip) 27.6772 Tj
-1 TJm
-(2) 4.9815 Tj
-[1 0 0 1 267.964 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -15.037 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -248.702] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 227.148 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 223.562] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F130_0 9.963 Tf
-(BZ_CONFIG_ERROR) 89.667 Tj
-98.488 699.676 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(library) 41.8446 Tj
--426 TJm
-(has) 17.9334 Tj
--426 TJm
-(been) 23.9112 Tj
--425 TJm
-(mis-compiled) 71.7336 Tj
-90 687.721 Td
-(BZ_PARAM_ERROR) 83.6892 Tj
-98.488 675.766 Td
-(if) 11.9556 Tj
--426 TJm
-(dest) 23.9112 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(destL) 29.889 Tj
-1 TJm
-(en) 11.9556 Tj
--426 TJm
-(is) 11.9556 Tj
--426 TJm
-(NULL) 23.9112 Tj
-98.488 663.811 Td
-(or) 11.9556 Tj
--426 TJm
-(small) 29.889 Tj
--426 TJm
-(!=) 11.9556 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(&&) 11.9556 Tj
--426 TJm
-(small) 29.889 Tj
--426 TJm
-(!) 5.9778 Tj
-1 TJm
-(=) 5.9778 Tj
--426 TJm
-(1) 5.9778 Tj
-98.488 651.856 Td
-(or) 11.9556 Tj
--426 TJm
-(verbosity) 53.8002 Tj
--426 TJm
-(<) 5.9778 Tj
--426 TJm
-(0) 5.9778 Tj
--426 TJm
-(or) 11.9556 Tj
--426 TJm
-(verb) 23.9112 Tj
-1 TJm
-(osity) 29.889 Tj
--426 TJm
-(>) 5.9778 Tj
--426 TJm
-(4) 5.9778 Tj
-90 639.9 Td
-(BZ_MEM_ERROR) 71.7336 Tj
-98.488 627.945 Td
-(if) 11.9556 Tj
--426 TJm
-(insufficient) 71.7336 Tj
--426 TJm
-(memory) 35.8668 Tj
--426 TJm
-(is) 11.9556 Tj
--425 TJm
-(available) 53.8002 Tj
-90 615.99 Td
-(BZ_OUTBUFF_FULL) 89.667 Tj
-98.488 604.035 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(size) 23.9112 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compr) 29.889 Tj
-1 TJm
-(essed) 29.889 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(exceeds) 41.8446 Tj
--426 TJm
-(*destLen) 47.8224 Tj
-90 592.08 Td
-(BZ_DATA_ERROR) 77.7114 Tj
-98.488 580.124 Td
-(if) 11.9556 Tj
--426 TJm
-(a) 5.9778 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(integrity) 53.8002 Tj
--426 TJm
-(erro) 23.9112 Tj
-1 TJm
-(r) 5.9778 Tj
--426 TJm
-(was) 17.9334 Tj
--426 TJm
-(detected) 47.8224 Tj
--426 TJm
-(in) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(data) 23.9112 Tj
-90 568.169 Td
-(BZ_DATA_ERROR_MAGIC) 113.578 Tj
-98.488 556.214 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(d) 5.9778 Tj
-1 TJm
-(oesn't) 35.8668 Tj
--426 TJm
-(begin) 29.889 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(right) 29.889 Tj
--426 TJm
-(magic) 29.889 Tj
--426 TJm
-(bytes) 29.889 Tj
-90 544.259 Td
-(BZ_UNEXPECTED_EOF) 101.623 Tj
-98.488 532.304 Td
-(if) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(compressed) 59.778 Tj
--426 TJm
-(data) 23.9112 Tj
--426 TJm
-(e) 5.9778 Tj
-1 TJm
-(nds) 17.9334 Tj
--426 TJm
-(unexpectedly) 71.7336 Tj
-90 520.349 Td
-(BZ_OK) 29.889 Tj
-98.488 508.393 Td
-(otherwise) 53.8002 Tj
-[1 0 0 1 72 492.852] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -482.889] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 458.099 Td
-/F121_0 20.659 Tf
-(3.6.) 34.4592 Tj
-[1 0 0 1 112.201 458.099] cm
-0 g
-0 G
-[1 0 0 1 -112.201 -458.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-112.201 458.099 Td
-/F387_0 20.659 Tf
-(zlib) 49.5816 Tj
-[1 0 0 1 161.781 458.099] cm
-0 g
-0 G
-[1 0 0 1 -161.781 -458.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.524 458.099 Td
-/F121_0 20.659 Tf
-(compatibility) 127.425 Tj
--278 TJm
-(functions) 92.9655 Tj
-[1 0 0 1 72 453.823] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -443.86] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 436.181 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(oshioka) 30.9949 Tj
--604 TJm
-(Tsuneo) 29.3311 Tj
--604 TJm
-(has) 13.2807 Tj
--604 TJm
-(contrib) 28.2252 Tj
-20 TJm
-(uted) 17.1563 Tj
--604 TJm
-(some) 21.0319 Tj
--604 TJm
-(funct) 20.474 Tj
-1 TJm
-(ions) 16.6083 Tj
--604 TJm
-(to) 7.75121 Tj
--604 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--604 TJm
-(better) 22.6858 Tj
-[1 0 0 1 356.347 436.181] cm
-0 g
-0 G
-[1 0 0 1 -356.347 -436.181] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-356.347 436.181 Td
-/F130_0 9.963 Tf
-(zlib) 23.9112 Tj
-[1 0 0 1 380.257 436.181] cm
-0 g
-0 G
-[1 0 0 1 -380.257 -436.181] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-386.275 436.181 Td
-/F128_0 9.963 Tf
-(compatibility) 53.1426 Tj
-65 TJm
-(.) 2.49075 Tj
--1372 TJm
-(These) 23.7916 Tj
--604 TJm
-(functions) 37.0823 Tj
--604 TJm
-(are) 12.1648 Tj
-[1 0 0 1 72 424.226] cm
-0 g
-0 G
-[1 0 0 1 -72 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 424.226 Td
-/F130_0 9.963 Tf
-(BZ2_bzopen) 59.778 Tj
-[1 0 0 1 131.776 424.226] cm
-0 g
-0 G
-[1 0 0 1 -131.776 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.776 424.226 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 144.283 424.226] cm
-0 g
-0 G
-[1 0 0 1 -144.283 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.283 424.226 Td
-/F130_0 9.963 Tf
-(BZ2_bzread) 59.778 Tj
-[1 0 0 1 204.059 424.226] cm
-0 g
-0 G
-[1 0 0 1 -204.059 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.059 424.226 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 216.567 424.226] cm
-0 g
-0 G
-[1 0 0 1 -216.567 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.567 424.226 Td
-/F130_0 9.963 Tf
-(BZ2_bzwrite) 65.7558 Tj
-[1 0 0 1 282.32 424.226] cm
-0 g
-0 G
-[1 0 0 1 -282.32 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.32 424.226 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 294.827 424.226] cm
-0 g
-0 G
-[1 0 0 1 -294.827 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.827 424.226 Td
-/F130_0 9.963 Tf
-(BZ2_bzflush) 65.7558 Tj
-[1 0 0 1 360.581 424.226] cm
-0 g
-0 G
-[1 0 0 1 -360.581 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.581 424.226 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 373.088 424.226] cm
-0 g
-0 G
-[1 0 0 1 -373.088 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-373.088 424.226 Td
-/F130_0 9.963 Tf
-(BZ2_bzclose) 65.7558 Tj
-[1 0 0 1 438.842 424.226] cm
-0 g
-0 G
-[1 0 0 1 -438.842 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.842 424.226 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 451.349 424.226] cm
-0 g
-0 G
-[1 0 0 1 -451.349 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-451.349 424.226 Td
-/F130_0 9.963 Tf
-(BZ2_bzerror) 65.7558 Tj
-[1 0 0 1 517.102 424.226] cm
-0 g
-0 G
-[1 0 0 1 -517.102 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 424.226 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 72 412.271] cm
-0 g
-0 G
-[1 0 0 1 -72 -412.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 412.271 Td
-/F130_0 9.963 Tf
-(BZ2_bzlibVersion) 95.6448 Tj
-[1 0 0 1 167.641 412.271] cm
-0 g
-0 G
-[1 0 0 1 -167.641 -412.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.641 412.271 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1419 TJm
-(These) 23.7916 Tj
--384 TJm
-(functi) 23.2437 Tj
-1 TJm
-(ons) 13.8386 Tj
--384 TJm
-(are) 12.1648 Tj
--383 TJm
-(not) 12.7327 Tj
--383 TJm
-(\(yet\)) 18.8101 Tj
--383 TJm
-(of) 8.29918 Tj
-25 TJm
-(\002cially) 27.6772 Tj
--383 TJm
-(part) 15.4925 Tj
--383 TJm
-(of) 8.29918 Tj
--384 TJm
-(the) 12.1748 Tj
--383 TJm
-(library) 26.5614 Tj
-65 TJm
-(.) 2.49075 Tj
--1419 TJm
-(If) 6.63536 Tj
--383 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--383 TJm
-(break,) 24.6186 Tj
--417 TJm
-(you) 14.9445 Tj
--383 TJm
-(get) 12.1748 Tj
--383 TJm
-(to) 7.75121 Tj
-72 400.316 Td
-(k) 4.9815 Tj
-10 TJm
-(eep) 13.8286 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(pieces.) 27.3883 Tj
--620 TJm
-(Ne) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(erth) 15.4925 Tj
-1 TJm
-(eless,) 21.8588 Tj
--250 TJm
-(I) 3.31768 Tj
--250 TJm
-(think) 20.4839 Tj
--250 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--250 TJm
-(ok.) 12.4538 Tj
-[1 0 0 1 72 398.159] cm
-0 g
-0 G
-[1 0 0 1 0 -48.817] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 47.821 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 44.235] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -388.794] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 388.794 Td
-/F130_0 9.963 Tf
-(typedef) 41.8446 Tj
--426 TJm
-(void) 23.9112 Tj
--426 TJm
-(BZFILE;) 41.8446 Tj
-90 364.884 Td
-(const) 29.889 Tj
--426 TJm
-(char) 23.9112 Tj
--426 TJm
-(*) 5.9778 Tj
--426 TJm
-(BZ2_bzlibVer) 71.7336 Tj
-1 TJm
-(sion) 23.9112 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(void) 23.9112 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 349.342] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -339.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 327.424 Td
-/F128_0 9.963 Tf
-(Returns) 30.9949 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(string) 22.6957 Tj
--250 TJm
-(indicating) 39.852 Tj
--250 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--250 TJm
-(library) 26.5614 Tj
--250 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion.) 26.8403 Tj
-[1 0 0 1 72 325.267] cm
-0 g
-0 G
-[1 0 0 1 0 -36.862] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -315.902] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 315.902 Td
-/F130_0 9.963 Tf
-(BZFILE) 35.8668 Tj
--426 TJm
-(*) 5.9778 Tj
--426 TJm
-(BZ2_bzopen) 59.778 Tj
--852 TJm
-(\() 5.9778 Tj
--426 TJm
-(c) 5.9778 Tj
-1 TJm
-(onst) 23.9112 Tj
--426 TJm
-(char) 23.9112 Tj
--426 TJm
-(*path,) 35.8668 Tj
--426 TJm
-(const) 29.889 Tj
--426 TJm
-(char) 23.9112 Tj
--426 TJm
-(*mode) 29.889 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 303.947 Td
-(BZFILE) 35.8668 Tj
--426 TJm
-(*) 5.9778 Tj
--426 TJm
-(BZ2_bzdopen) 65.7558 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(i) 5.9778 Tj
-1 TJm
-(nt) 11.9556 Tj
--3408 TJm
-(fd,) 17.9334 Tj
--1704 TJm
-(const) 29.889 Tj
--426 TJm
-(char) 23.9112 Tj
--426 TJm
-(*mode) 29.889 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 288.405] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -278.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 266.488 Td
-/F128_0 9.963 Tf
-(Opens) 25.4555 Tj
--243 TJm
-(a) 4.42357 Tj
-[1 0 0 1 106.713 266.488] cm
-0 g
-0 G
-[1 0 0 1 -106.713 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-106.713 266.488 Td
-/F130_0 9.963 Tf
-(.bz2) 23.9112 Tj
-[1 0 0 1 130.624 266.488] cm
-0 g
-0 G
-[1 0 0 1 -130.624 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-133.041 266.488 Td
-/F128_0 9.963 Tf
-(\002le) 12.7327 Tj
--243 TJm
-(for) 11.6169 Tj
--242 TJm
-(reading) 29.879 Tj
--243 TJm
-(or) 8.29918 Tj
--242 TJm
-(writing,) 31.2739 Tj
--244 TJm
-(using) 21.5898 Tj
--243 TJm
-(either) 22.6858 Tj
--243 TJm
-(its) 9.41504 Tj
--242 TJm
-(name) 21.5799 Tj
--243 TJm
-(or) 8.29918 Tj
--242 TJm
-(a) 4.42357 Tj
--243 TJm
-(pre-e) 20.464 Tj
-15 TJm
-(xisting) 27.1292 Tj
--243 TJm
-(\002le) 12.7327 Tj
--242 TJm
-(descriptor) 39.842 Tj
-55 TJm
-(.) 2.49075 Tj
--615 TJm
-(Analogous) 43.1697 Tj
--243 TJm
-(to) 7.75121 Tj
-[1 0 0 1 510.112 266.488] cm
-0 g
-0 G
-[1 0 0 1 -510.112 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 266.488 Td
-/F130_0 9.963 Tf
-(fopen) 29.889 Tj
-[1 0 0 1 540 266.488] cm
-0 g
-0 G
-[1 0 0 1 -540 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 254.532 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 88.877 254.532] cm
-0 g
-0 G
-[1 0 0 1 -88.877 -254.532] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-88.877 254.532 Td
-/F130_0 9.963 Tf
-(fdopen) 35.8668 Tj
-[1 0 0 1 124.742 254.532] cm
-0 g
-0 G
-[1 0 0 1 -124.742 -254.532] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.742 254.532 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 252.968] cm
-0 g
-0 G
-[1 0 0 1 0 -36.861] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -243.604] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 243.604 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzread) 59.778 Tj
--852 TJm
-(\() 5.9778 Tj
--426 TJm
-(BZFILE) 35.8668 Tj
-1 TJm
-(*) 5.9778 Tj
--426 TJm
-(b,) 11.9556 Tj
--426 TJm
-(void*) 29.889 Tj
--426 TJm
-(buf,) 23.9112 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(len) 17.9334 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 231.648 Td
-(int) 17.9334 Tj
--426 TJm
-(BZ2_bzwrite) 65.7558 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(BZFILE*) 41.8446 Tj
--425 TJm
-(b,) 11.9556 Tj
--426 TJm
-(void*) 29.889 Tj
--426 TJm
-(buf,) 23.9112 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(len) 17.9334 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 216.107] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -206.144] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 194.189 Td
-/F128_0 9.963 Tf
-(Reads/writes) 51.4689 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(from/to) 29.889 Tj
--249 TJm
-(a) 4.42357 Tj
--250 TJm
-(pre) 12.7228 Tj
-25 TJm
-(viously) 29.341 Tj
--250 TJm
-(opened) 28.7731 Tj
-[1 0 0 1 259.903 194.189] cm
-0 g
-0 G
-[1 0 0 1 -259.903 -194.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.903 194.189 Td
-/F130_0 9.963 Tf
-(BZFILE) 35.8668 Tj
-[1 0 0 1 295.769 194.189] cm
-0 g
-0 G
-[1 0 0 1 -295.769 -194.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-295.769 194.189 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--500 TJm
-(Analogous) 43.1697 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 359.141 194.189] cm
-0 g
-0 G
-[1 0 0 1 -359.141 -194.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-359.141 194.189 Td
-/F130_0 9.963 Tf
-(fread) 29.889 Tj
-[1 0 0 1 389.029 194.189] cm
-0 g
-0 G
-[1 0 0 1 -389.029 -194.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-391.519 194.189 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 408.396 194.189] cm
-0 g
-0 G
-[1 0 0 1 -408.396 -194.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-408.396 194.189 Td
-/F130_0 9.963 Tf
-(fwrite) 35.8668 Tj
-[1 0 0 1 444.261 194.189] cm
-0 g
-0 G
-[1 0 0 1 -444.261 -194.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-444.261 194.189 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 192.032] cm
-0 g
-0 G
-[1 0 0 1 0 -36.862] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -182.667] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 182.667 Td
-/F130_0 9.963 Tf
-(int) 17.9334 Tj
--852 TJm
-(BZ2_bzflush) 65.7558 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(BZFIL) 29.889 Tj
-1 TJm
-(E*) 11.9556 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-90 170.712 Td
-(void) 23.9112 Tj
--426 TJm
-(BZ2_bzclose) 65.7558 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(BZFILE) 35.8668 Tj
-1 TJm
-(*) 5.9778 Tj
--426 TJm
-(b) 5.9778 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 155.17] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -145.208] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 133.252 Td
-/F128_0 9.963 Tf
-(Flushes/closes) 57.5662 Tj
--250 TJm
-(a) 4.42357 Tj
-[1 0 0 1 138.968 133.252] cm
-0 g
-0 G
-[1 0 0 1 -138.968 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.968 133.252 Td
-/F130_0 9.963 Tf
-(BZFILE) 35.8668 Tj
-[1 0 0 1 174.833 133.252] cm
-0 g
-0 G
-[1 0 0 1 -174.833 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-174.833 133.252 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 179.815 133.252] cm
-0 g
-0 G
-[1 0 0 1 -179.815 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.815 133.252 Td
-/F130_0 9.963 Tf
-(BZ2_bzflush) 65.7558 Tj
-[1 0 0 1 245.568 133.252] cm
-0 g
-0 G
-[1 0 0 1 -245.568 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.059 133.252 Td
-/F128_0 9.963 Tf
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(actually) 31.5429 Tj
--250 TJm
-(do) 9.963 Tj
--250 TJm
-(an) 9.40507 Tj
-15 TJm
-(ything.) 27.9562 Tj
--619 TJm
-(Analogous) 43.1697 Tj
--250 TJm
-(to) 7.75121 Tj
-[1 0 0 1 425.472 133.252] cm
-0 g
-0 G
-[1 0 0 1 -425.472 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.472 133.252 Td
-/F130_0 9.963 Tf
-(fflush) 35.8668 Tj
-[1 0 0 1 461.338 133.252] cm
-0 g
-0 G
-[1 0 0 1 -461.338 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-463.828 133.252 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 480.705 133.252] cm
-0 g
-0 G
-[1 0 0 1 -480.705 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-480.705 133.252 Td
-/F130_0 9.963 Tf
-(fclose) 35.8668 Tj
-[1 0 0 1 516.57 133.252] cm
-0 g
-0 G
-[1 0 0 1 -516.57 -133.252] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.57 133.252 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 131.096] cm
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.323] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -121.731] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 121.731 Td
-/F130_0 9.963 Tf
-(const) 29.889 Tj
--426 TJm
-(char) 23.9112 Tj
--426 TJm
-(*) 5.9778 Tj
--426 TJm
-(BZ2_bzerror) 65.7558 Tj
--425 TJm
-(\() 5.9778 Tj
--426 TJm
-(BZFILE) 35.8668 Tj
--426 TJm
-(*b,) 17.9334 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(*errnum) 41.8446 Tj
--426 TJm
-(\)) 5.9778 Tj
-[1 0 0 1 72 106.189] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -96.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 84.271 Td
-/F128_0 9.963 Tf
-(Returns) 30.9949 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(string) 22.6957 Tj
--250 TJm
-(describing) 41.5059 Tj
--250 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--250 TJm
-(more) 20.474 Tj
--250 TJm
-(recent) 24.3396 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(status) 22.6957 Tj
--250 TJm
-(of) 8.29918 Tj
-[1 0 0 1 303.858 84.271] cm
-0 g
-0 G
-[1 0 0 1 -303.858 -84.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-303.858 84.271 Td
-/F130_0 9.963 Tf
-(b) 5.9778 Tj
-[1 0 0 1 309.835 84.271] cm
-0 g
-0 G
-[1 0 0 1 -309.835 -84.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.835 84.271 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(also) 16.0504 Tj
--250 TJm
-(sets) 14.9445 Tj
-[1 0 0 1 367.668 84.271] cm
-0 g
-0 G
-[1 0 0 1 -367.668 -84.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-367.668 84.271 Td
-/F130_0 9.963 Tf
-(*errnum) 41.8446 Tj
-[1 0 0 1 409.511 84.271] cm
-0 g
-0 G
-[1 0 0 1 -409.511 -84.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-412.002 84.271 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(its) 9.41504 Tj
--250 TJm
-(numerical) 39.842 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alue.) 19.0891 Tj
-[1 0 0 1 72 82.114] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -21.3] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 4.384 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.573 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -495.734 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-536.307 50.951 Td
-/F128_0 9.963 Tf
-(28) 9.963 Tj
-[1 0 0 1 455.161 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.599 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -15.037 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 32 32
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 704.93 Td
-/F121_0 20.659 Tf
-(3.7.) 34.4592 Tj
--449 TJm
-(Using) 57.3907 Tj
--449 TJm
-(the) 30.9885 Tj
--449 TJm
-(librar) 51.6682 Tj
--10 TJm
-(y) 11.4864 Tj
--449 TJm
-(in) 18.3659 Tj
--450 TJm
-(a) 11.4864 Tj
-[1 0 0 1 343.721 704.93] cm
-0 g
-0 G
-[1 0 0 1 -343.721 -704.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-343.721 704.93 Td
-/F387_0 20.659 Tf
-(stdio) 61.977 Tj
-[1 0 0 1 405.696 704.93] cm
-0 g
-0 G
-[1 0 0 1 -405.696 -704.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.696 704.93 Td
-/F121_0 20.659 Tf
-(-free) 44.7681 Tj
--449 TJm
-(en) 24.1091 Tj
-40 TJm
-(vir) 25.266 Tj
-20 TJm
-(on-) 32.1247 Tj
-72 680.139 Td
-(ment) 49.3544 Tj
-[1 0 0 1 72 679.881] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -669.919] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 649.518 Td
-/F121_0 17.215 Tf
-(3.7.1.) 43.0719 Tj
--278 TJm
-(Getting) 60.2525 Tj
--278 TJm
-(rid) 22.0008 Tj
--278 TJm
-(of) 16.251 Tj
-[1 0 0 1 232.721 649.518] cm
-0 g
-0 G
-[1 0 0 1 -232.721 -649.518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.721 649.518 Td
-/F387_0 17.215 Tf
-(stdio) 51.645 Tj
-[1 0 0 1 284.367 649.518] cm
-0 g
-0 G
-[1 0 0 1 -212.367 -3.83] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -635.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 627.6 Td
-/F128_0 9.963 Tf
-(In) 8.29918 Tj
--319 TJm
-(a) 4.42357 Tj
--319 TJm
-(deeply) 26.5614 Tj
--319 TJm
-(embedded) 40.9479 Tj
--319 TJm
-(application,) 46.7663 Tj
--336 TJm
-(you) 14.9445 Tj
--319 TJm
-(might) 23.2536 Tj
--319 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--319 TJm
-(to) 7.75121 Tj
--319 TJm
-(use) 13.2807 Tj
--319 TJm
-(just) 14.3965 Tj
--319 TJm
-(t) 2.76971 Tj
-1 TJm
-(he) 9.40507 Tj
--319 TJm
-(memory-to-memory) 80.7999 Tj
--319 TJm
-(functions.) 39.573 Tj
--1034 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--319 TJm
-(can) 13.8286 Tj
--319 TJm
-(do) 9.963 Tj
--319 TJm
-(this) 14.3965 Tj
-72 615.645 Td
-(con) 14.3866 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(eniently) 32.1008 Tj
--327 TJm
-(by) 9.963 Tj
--327 TJm
-(compiling) 40.4099 Tj
--327 TJm
-(the) 12.1748 Tj
--327 TJm
-(library) 26.5614 Tj
--327 TJm
-(with) 17.7142 Tj
--327 TJm
-(preprocessor) 50.901 Tj
--327 TJm
-(symbol) 29.341 Tj
-[1 0 0 1 336.045 615.645] cm
-0 g
-0 G
-[1 0 0 1 -336.045 -615.645] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-336.045 615.645 Td
-/F130_0 9.963 Tf
-(BZ_NO_STDIO) 65.7558 Tj
-[1 0 0 1 401.799 615.645] cm
-0 g
-0 G
-[1 0 0 1 -401.799 -615.645] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.057 615.645 Td
-/F128_0 9.963 Tf
-(de\002ned.) 31.8218 Tj
--1082 TJm
-(Doing) 24.9075 Tj
--327 TJm
-(this) 14.3965 Tj
--327 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--327 TJm
-(you) 14.9445 Tj
--327 TJm
-(a) 4.42357 Tj
-72 603.69 Td
-(library) 26.5614 Tj
--250 TJm
-(containing) 42.0638 Tj
--250 TJm
-(only) 17.7142 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(fo) 8.29918 Tj
-1 TJm
-(llo) 10.5209 Tj
-25 TJm
-(wing) 19.926 Tj
--250 TJm
-(eight) 19.926 Tj
--250 TJm
-(functions:) 39.852 Tj
-[1 0 0 1 72 601.533] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -591.571] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 581.772 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressInit) 107.6 Tj
-[1 0 0 1 179.597 581.772] cm
-0 g
-0 G
-[1 0 0 1 -179.597 -581.772] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.597 581.772 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 199.079 581.772] cm
-0 g
-0 G
-[1 0 0 1 -199.079 -581.772] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.079 581.772 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompress) 83.6892 Tj
-[1 0 0 1 282.765 581.772] cm
-0 g
-0 G
-[1 0 0 1 -282.765 -581.772] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.765 581.772 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 302.247 581.772] cm
-0 g
-0 G
-[1 0 0 1 -302.247 -581.772] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.247 581.772 Td
-/F130_0 9.963 Tf
-(BZ2_bzCompressEnd) 101.623 Tj
-[1 0 0 1 403.866 581.772] cm
-0 g
-0 G
-[1 0 0 1 14.092 0] cm
-0 g
-0 G
-[1 0 0 1 -417.958 -581.772] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-417.958 581.772 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressInit) 119.556 Tj
-[1 0 0 1 537.509 581.772] cm
-0 g
-0 G
-[1 0 0 1 -537.509 -581.772] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 581.772 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 72 569.817] cm
-0 g
-0 G
-[1 0 0 1 -72 -569.817] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 569.817 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompress) 95.6448 Tj
-[1 0 0 1 167.641 569.817] cm
-0 g
-0 G
-[1 0 0 1 -167.641 -569.817] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.641 569.817 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 172.144 569.817] cm
-0 g
-0 G
-[1 0 0 1 -172.144 -569.817] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.144 569.817 Td
-/F130_0 9.963 Tf
-(BZ2_bzDecompressEnd) 113.578 Tj
-[1 0 0 1 285.719 569.817] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 -287.612 -569.817] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-287.612 569.817 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffCompres) 137.489 Tj
-1 TJm
-(s) 5.9778 Tj
-[1 0 0 1 431.074 569.817] cm
-0 g
-0 G
-[1 0 0 1 -431.074 -569.817] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.074 569.817 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 435.577 569.817] cm
-0 g
-0 G
-[1 0 0 1 -435.577 -569.817] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-435.577 569.817 Td
-/F130_0 9.963 Tf
-(BZ2_bzBuffToBuffDecompre) 143.467 Tj
-1 TJm
-(ss) 11.9556 Tj
-[1 0 0 1 590.994 569.817] cm
-0 g
-0 G
-[1 0 0 1 -518.994 -1.564] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -558.29] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 547.899 Td
-/F128_0 9.963 Tf
-(When) 23.7916 Tj
--250 TJm
-(compiled) 37.0823 Tj
--250 TJm
-(lik) 10.5209 Tj
-10 TJm
-(e) 4.42357 Tj
--250 TJm
-(this,) 16.8873 Tj
--250 TJm
-(all) 9.963 Tj
--249 TJm
-(functions) 37.0823 Tj
--250 TJm
-(will) 15.5024 Tj
--250 TJm
-(ignore) 25.4555 Tj
-[1 0 0 1 272.526 547.899] cm
-0 g
-0 G
-[1 0 0 1 -272.526 -547.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.526 547.899 Td
-/F130_0 9.963 Tf
-(verbosity) 53.8002 Tj
-[1 0 0 1 326.324 547.899] cm
-0 g
-0 G
-[1 0 0 1 -326.324 -547.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-328.815 547.899 Td
-/F128_0 9.963 Tf
-(settings.) 32.9377 Tj
-[1 0 0 1 72 545.742] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -535.78] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 517.278 Td
-/F121_0 17.215 Tf
-(3.7.2.) 43.0719 Tj
--278 TJm
-(Critical) 58.3589 Tj
--278 TJm
-(err) 22.9648 Tj
-20 TJm
-(or) 17.215 Tj
--278 TJm
-(handling) 71.7349 Tj
-[1 0 0 1 72 513.448] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -503.485] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 495.36 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 119.821 495.36] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -495.36] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.529 495.36 Td
-/F128_0 9.963 Tf
-(contains) 33.2067 Tj
--472 TJm
-(a) 4.42357 Tj
--473 TJm
-(number) 30.437 Tj
--472 TJm
-(of) 8.29918 Tj
--473 TJm
-(internal) 30.437 Tj
--472 TJm
-(assertion) 35.4185 Tj
--473 TJm
-(checks) 27.1093 Tj
--472 TJm
-(which) 24.3496 Tj
--473 TJm
-(sho) 13.8386 Tj
-1 TJm
-(uld,) 15.2235 Tj
--529 TJm
-(needles) 29.879 Tj
-1 TJm
-(s) 3.87561 Tj
--473 TJm
-(to) 7.75121 Tj
--473 TJm
-(sa) 8.29918 Tj
-1 TJm
-(y) 4.9815 Tj
-65 TJm
-(,) 2.49075 Tj
--529 TJm
-(ne) 9.40507 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--472 TJm
-(be) 9.40507 Tj
--473 TJm
-(acti) 14.3866 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ated.) 19.0891 Tj
-72 483.405 Td
-(Ne) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ertheless,) 37.3513 Tj
--532 TJm
-(if) 6.08739 Tj
--476 TJm
-(an) 9.40507 Tj
--476 TJm
-(assertion) 35.4185 Tj
--476 TJm
-(should) 26.5713 Tj
--476 TJm
-(f) 3.31768 Tj
-10 TJm
-(ail,) 12.4538 Tj
--533 TJm
-(beha) 18.8101 Tj
-21 TJm
-(viour) 21.0319 Tj
--476 TJm
-(depends) 32.6488 Tj
--476 TJm
-(on) 9.963 Tj
--476 TJm
-(whether) 32.0908 Tj
--476 TJm
-(or) 8.29918 Tj
--476 TJm
-(not) 12.7327 Tj
--476 TJm
-(the) 12.1748 Tj
--476 TJm
-(library) 26.5614 Tj
--476 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--476 TJm
-(compiled) 37.0823 Tj
--476 TJm
-(with) 17.7142 Tj
-[1 0 0 1 72 471.45] cm
-0 g
-0 G
-[1 0 0 1 -72 -471.45] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 471.45 Td
-/F130_0 9.963 Tf
-(BZ_NO_STDIO) 65.7558 Tj
-[1 0 0 1 137.753 471.45] cm
-0 g
-0 G
-[1 0 0 1 -137.753 -471.45] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.244 471.45 Td
-/F128_0 9.963 Tf
-(set.) 13.5596 Tj
-[1 0 0 1 72 470.284] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -460.322] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 449.532 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(normal) 28.2252 Tj
--250 TJm
-(compile,) 34.5915 Tj
--250 TJm
-(an) 9.40507 Tj
--250 TJm
-(asse) 16.5984 Tj
-1 TJm
-(rtion) 18.8201 Tj
--250 TJm
-(f) 3.31768 Tj
-10 TJm
-(ailure) 22.6858 Tj
--250 TJm
-(yields) 23.8016 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(message:) 36.5244 Tj
-[1 0 0 1 72 447.375] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -437.413] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 427.614 Td
-/F128_0 9.963 Tf
-(bzip2/libbzip2:) 60.3359 Tj
--310 TJm
-(internal) 30.437 Tj
--250 TJm
-(err) 11.0589 Tj
-1 TJm
-(or) 8.29918 Tj
--250 TJm
-(number) 30.437 Tj
--250 TJm
-(N.) 9.68404 Tj
-[1 0 0 1 72 425.458] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -415.495] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 405.697 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--475 TJm
-(is) 6.64532 Tj
--476 TJm
-(a) 4.42357 Tj
--476 TJm
-(b) 4.9815 Tj
-20 TJm
-(u) 4.9815 Tj
-1 TJm
-(g) 4.9815 Tj
--476 TJm
-(in) 7.75121 Tj
--476 TJm
-(bzi) 12.1748 Tj
-1 TJm
-(p2/libbzip2,) 47.8822 Tj
--532 TJm
-(1.0.3) 19.926 Tj
--476 TJm
-(of) 8.29918 Tj
--475 TJm
-(15) 9.963 Tj
--476 TJm
-(February) 35.9664 Tj
--475 TJm
-(2005.) 22.4168 Tj
--987 TJm
-(Please) 25.4555 Tj
--475 TJm
-(report) 23.7916 Tj
--476 TJm
-(it) 5.53943 Tj
--475 TJm
-(to) 7.75121 Tj
--476 TJm
-(me) 12.1748 Tj
--475 TJm
-(at:) 9.963 Tj
--761 TJm
-(jse-) 14.3866 Tj
-108 393.741 Td
-(w) 7.19329 Tj
-10 TJm
-(ard@bzip.or) 49.8449 Tj
-18 TJm
-(g.) 7.47225 Tj
--1091 TJm
-(If) 6.63536 Tj
--329 TJm
-(this) 14.3965 Tj
--328 TJm
-(happened) 38.1782 Tj
--329 TJm
-(wh) 12.1748 Tj
-1 TJm
-(en) 9.40507 Tj
--329 TJm
-(you) 14.9445 Tj
--329 TJm
-(w) 7.19329 Tj
-1 TJm
-(ere) 12.1648 Tj
--329 TJm
-(using) 21.5898 Tj
--328 TJm
-(some) 21.0319 Tj
--329 TJm
-(program) 33.7546 Tj
--328 TJm
-(which) 24.3496 Tj
--329 TJm
-(uses) 17.1563 Tj
--328 TJm
-(libbzip2) 32.6587 Tj
--329 TJm
-(as) 8.29918 Tj
--328 TJm
-(a) 4.42357 Tj
-108 381.786 Td
-(component,) 46.7663 Tj
--323 TJm
-(you) 14.9445 Tj
--309 TJm
-(should) 26.5713 Tj
--308 TJm
-(also) 16.0504 Tj
--309 TJm
-(report) 23.7916 Tj
--309 TJm
-(this) 14.3965 Tj
--308 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--309 TJm
-(to) 7.75121 Tj
--309 TJm
-(the) 12.1748 Tj
--308 TJm
-(author\(s\)) 35.9664 Tj
--309 TJm
-(of) 8.29918 Tj
--309 TJm
-(tha) 12.1748 Tj
-1 TJm
-(t) 2.76971 Tj
--309 TJm
-(program.) 36.2454 Tj
--972 TJm
-(Please) 25.4555 Tj
--309 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--309 TJm
-(an) 9.40507 Tj
--308 TJm
-(ef-) 11.0589 Tj
-108 369.831 Td
-(fort) 14.3866 Tj
--315 TJm
-(to) 7.75121 Tj
--315 TJm
-(report) 23.7916 Tj
--316 TJm
-(this) 14.3965 Tj
--315 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug;) 12.7327 Tj
--348 TJm
-(timely) 25.4654 Tj
--315 TJm
-(and) 14.3866 Tj
--315 TJm
-(accurate) 33.1868 Tj
--315 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--315 TJm
-(reports) 27.6673 Tj
--316 TJm
-(e) 4.42357 Tj
-26 TJm
-(v) 4.9815 Tj
-15 TJm
-(entually) 32.1008 Tj
--316 TJm
-(lead) 16.5984 Tj
--315 TJm
-(to) 7.75121 Tj
--315 TJm
-(higher) 25.4555 Tj
--315 TJm
-(quality) 27.6772 Tj
--315 TJm
-(softw) 22.1378 Tj
-10 TJm
-(are.) 14.6556 Tj
-108 357.876 Td
-(Thanks.) 31.8218 Tj
--620 TJm
-(Julian) 23.8016 Tj
--250 TJm
-(Se) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(ard,) 15.2135 Tj
--250 TJm
-(15) 9.963 Tj
--250 TJm
-(Fe) 9.963 Tj
-1 TJm
-(bruary) 26.0034 Tj
--250 TJm
-(2005.) 22.4168 Tj
-[1 0 0 1 72 355.719] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -335.794] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 325.995 Td
-/F128_0 9.963 Tf
-(where) 24.3396 Tj
-[1 0 0 1 98.831 325.995] cm
-0 g
-0 G
-[1 0 0 1 -98.831 -325.995] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-98.831 325.995 Td
-/F130_0 9.963 Tf
-(N) 5.9778 Tj
-[1 0 0 1 104.809 325.995] cm
-0 g
-0 G
-[1 0 0 1 -104.809 -325.995] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-107.301 325.995 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(some) 21.0319 Tj
--250 TJm
-(error) 19.3581 Tj
--250 TJm
-(code) 18.8101 Tj
--251 TJm
-(nu) 9.963 Tj
-1 TJm
-(mber) 20.474 Tj
-55 TJm
-(.) 2.49075 Tj
--622 TJm
-(If) 6.63536 Tj
-[1 0 0 1 230.81 325.995] cm
-0 g
-0 G
-[1 0 0 1 -230.81 -325.995] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.81 325.995 Td
-/F130_0 9.963 Tf
-(N) 5.9778 Tj
--600 TJm
-(==) 11.9556 Tj
--600 TJm
-(1007) 23.9112 Tj
-[1 0 0 1 284.608 325.995] cm
-0 g
-0 G
-[1 0 0 1 -284.608 -325.995] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.608 325.995 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(also) 16.0504 Tj
--250 TJm
-(prints) 22.6957 Tj
--251 TJm
-(som) 16.6083 Tj
-1 TJm
-(e) 4.42357 Tj
--251 TJm
-(e) 4.42357 Tj
-15 TJm
-(xtra) 15.4925 Tj
--250 TJm
-(te) 7.19329 Tj
-15 TJm
-(xt) 7.75121 Tj
--250 TJm
-(advising) 33.7646 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(reader) 24.8876 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(unreliable) 39.842 Tj
-72 314.04 Td
-(memory) 33.2067 Tj
--425 TJm
-(i) 2.76971 Tj
-1 TJm
-(s) 3.87561 Tj
--425 TJm
-(often) 20.474 Tj
--425 TJm
-(associate) 35.9664 Tj
-1 TJm
-(d) 4.9815 Tj
--425 TJm
-(with) 17.7142 Tj
--425 TJm
-(internal) 30.437 Tj
--424 TJm
-(error) 19.3581 Tj
--425 TJm
-(1007.) 22.4168 Tj
--834 TJm
-(\(This) 21.0319 Tj
--424 TJm
-(is) 6.64532 Tj
--425 TJm
-(a) 4.42357 Tj
--424 TJm
-(frequently-observ) 70.827 Tj
-15 TJm
-(ed-phenomenon) 64.1916 Tj
--425 TJm
-(w) 7.19329 Tj
-1 TJm
-(ith) 10.5209 Tj
--425 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
-72 302.085 Td
-(1.0.0/1.0.1\).) 48.4301 Tj
-[1 0 0 1 72 300.302] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -290.339] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 280.167 Td
-/F130_0 9.963 Tf
-(exit\(3\)) 41.8446 Tj
-[1 0 0 1 113.843 280.167] cm
-0 g
-0 G
-[1 0 0 1 -113.843 -280.167] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.334 280.167 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(then) 17.1563 Tj
--250 TJm
-(called.) 26.2824 Tj
-[1 0 0 1 72 279.002] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -269.039] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 258.25 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--250 TJm
-(a) 4.42357 Tj
-[1 0 0 1 95.093 258.25] cm
-0 g
-0 G
-[1 0 0 1 -95.093 -258.25] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.093 258.25 Td
-/F130_0 9.963 Tf
-(stdio) 29.889 Tj
-[1 0 0 1 124.981 258.25] cm
-0 g
-0 G
-[1 0 0 1 -124.981 -258.25] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.981 258.25 Td
-/F128_0 9.963 Tf
-(-free) 18.8002 Tj
--250 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(assertion) 35.4185 Tj
--250 TJm
-(f) 3.31768 Tj
-10 TJm
-(ailure) 22.6858 Tj
-1 TJm
-(s) 3.87561 Tj
--250 TJm
-(result) 22.1378 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(call) 14.3866 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(function) 33.2067 Tj
--250 TJm
-(declared) 33.7447 Tj
--250 TJm
-(as:) 11.0689 Tj
-[1 0 0 1 72 256.093] cm
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.323] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -246.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 246.728 Td
-/F130_0 9.963 Tf
-(extern) 35.8668 Tj
--426 TJm
-(void) 23.9112 Tj
--426 TJm
-(bz_internal_e) 77.7114 Tj
-1 TJm
-(rror) 23.9112 Tj
--426 TJm
-(\() 5.9778 Tj
--426 TJm
-(int) 17.9334 Tj
--426 TJm
-(errcode) 41.8446 Tj
--426 TJm
-(\);) 11.9556 Tj
-[1 0 0 1 72 231.186] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -221.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 209.268 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--250 TJm
-(rele) 14.9345 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ant) 12.1748 Tj
--250 TJm
-(code) 18.8101 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(passed) 26.5614 Tj
--250 TJm
-(a) 4.42357 Tj
-1 TJm
-(s) 3.87561 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(parameter) 39.8321 Tj
-55 TJm
-(.) 2.49075 Tj
--620 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(supply) 26.5713 Tj
--250 TJm
-(such) 18.2622 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(function.) 35.6974 Tj
-[1 0 0 1 72 207.111] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -197.149] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 187.35 Td
-/F128_0 9.963 Tf
-(In) 8.29918 Tj
--294 TJm
-(either) 22.6858 Tj
--294 TJm
-(case,) 19.6371 Tj
--305 TJm
-(once) 18.8101 Tj
--295 TJm
-(an) 9.40507 Tj
--294 TJm
-(assertion) 35.4185 Tj
--294 TJm
-(f) 3.31768 Tj
-10 TJm
-(ailure) 22.6858 Tj
--294 TJm
-(has) 13.2807 Tj
--294 TJm
-(occurred,) 37.3413 Tj
--305 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
-[1 0 0 1 306.541 187.35] cm
-0 g
-0 G
-[1 0 0 1 -306.541 -187.35] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-306.541 187.35 Td
-/F130_0 9.963 Tf
-(bz_stream) 53.8002 Tj
-[1 0 0 1 360.34 187.35] cm
-0 g
-0 G
-[1 0 0 1 -360.34 -187.35] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.271 187.35 Td
-/F128_0 9.963 Tf
-(records) 29.3211 Tj
--294 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-20 TJm
-(olv) 12.7327 Tj
-15 TJm
-(ed) 9.40507 Tj
--294 TJm
-(can) 13.8286 Tj
--294 TJm
-(be) 9.40507 Tj
--294 TJm
-(re) 7.74125 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(arded) 22.1278 Tj
--295 TJm
-(as) 8.29918 Tj
--294 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-25 TJm
-(alid.) 17.4353 Tj
-72 175.395 Td
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(attempt) 29.889 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(res) 11.6169 Tj
-1 TJm
-(ume) 17.1563 Tj
--250 TJm
-(normal) 28.2252 Tj
--250 TJm
-(operation) 37.6303 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(them.) 22.4168 Tj
-[1 0 0 1 72 173.238] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -163.276] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 153.477 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--299 TJm
-(m) 7.75121 Tj
-1 TJm
-(ay) 9.40507 Tj
-65 TJm
-(,) 2.49075 Tj
--311 TJm
-(of) 8.29918 Tj
--299 TJm
-(course,) 28.4942 Tj
--310 TJm
-(change) 28.2152 Tj
--299 TJm
-(critical) 27.6673 Tj
--298 TJm
-(error) 19.3581 Tj
--299 TJm
-(ha) 9.40507 Tj
-1 TJm
-(ndling) 25.4654 Tj
--299 TJm
-(to) 7.75121 Tj
--298 TJm
-(suit) 14.3965 Tj
--299 TJm
-(your) 18.2622 Tj
--298 TJm
-(needs.) 25.1765 Tj
--912 TJm
-(As) 11.0689 Tj
--298 TJm
-(I) 3.31768 Tj
--299 TJm
-(said) 16.0504 Tj
--298 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e,) 6.91432 Tj
--311 TJm
-(critical) 27.6673 Tj
--298 TJm
-(errors) 23.2337 Tj
--299 TJm
-(indic) 19.926 Tj
-1 TJm
-(ate) 11.6169 Tj
--299 TJm
-(b) 4.9815 Tj
-20 TJm
-(ugs) 13.8386 Tj
-72 141.522 Td
-(in) 7.75121 Tj
--263 TJm
-(the) 12.1748 Tj
--263 TJm
-(library) 26.5614 Tj
--263 TJm
-(and) 14.3866 Tj
--263 TJm
-(s) 3.87561 Tj
-1 TJm
-(hould) 22.6957 Tj
--263 TJm
-(not) 12.7327 Tj
--263 TJm
-(occur) 22.1278 Tj
-55 TJm
-(.) 2.49075 Tj
--698 TJm
-(All) 12.7327 Tj
--263 TJm
-("normal") 36.355 Tj
--263 TJm
-(er) 7.74125 Tj
-1 TJm
-(ror) 11.6169 Tj
--263 TJm
-(situations) 38.1981 Tj
--263 TJm
-(are) 12.1648 Tj
--263 TJm
-(indicated) 36.5244 Tj
--263 TJm
-(via) 12.1748 Tj
--263 TJm
-(error) 19.3581 Tj
--263 TJm
-(retu) 15.4925 Tj
-1 TJm
-(rn) 8.29918 Tj
--263 TJm
-(codes) 22.6858 Tj
--263 TJm
-(from) 19.3681 Tj
--263 TJm
-(functions,) 39.573 Tj
-72 129.567 Td
-(and) 14.3866 Tj
--250 TJm
-(can) 13.8286 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(reco) 17.1463 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(ered) 17.1463 Tj
--250 TJm
-(from.) 21.8588 Tj
-[1 0 0 1 72 129.468] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -119.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 94.814 Td
-/F121_0 20.659 Tf
-(3.8.) 34.4592 Tj
--278 TJm
-(Making) 71.1703 Tj
--278 TJm
-(a) 11.4864 Tj
--278 TJm
-(Windo) 63.1132 Tj
-15 TJm
-(ws) 27.5591 Tj
--278 TJm
-(DLL) 40.1611 Tj
-[1 0 0 1 72 90.218] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 0 -29.403] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.974] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -51.071] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 51.071 Td
-/F128_0 9.963 Tf
-(29) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 33 33
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -8.911] cm
-0 g
-0 G
-[1 0 0 1 0 8.911] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 84.08 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -350.151 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.231 749.245 Td
-/F128_0 9.963 Tf
-(Programming) 54.7965 Tj
--250 TJm
-(with) 17.7142 Tj
--250 TJm
-(libbzip2) 32.6587 Tj
-[1 0 0 1 266.071 747.089] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -5.037] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(Ev) 11.0689 Tj
-15 TJm
-(erything) 33.2067 Tj
--452 TJm
-(related) 27.1093 Tj
--452 TJm
-(to) 7.75121 Tj
--453 TJm
-(W) 9.40507 Tj
-40 TJm
-(indo) 17.7142 Tj
-25 TJm
-(ws) 11.0689 Tj
--452 TJm
-(has) 13.2807 Tj
--452 TJm
-(been) 18.8101 Tj
--453 TJm
-(c) 4.42357 Tj
-1 TJm
-(ontrib) 23.8016 Tj
-20 TJm
-(uted) 17.1563 Tj
--453 TJm
-(by) 9.963 Tj
--452 TJm
-(Y) 7.19329 Tj
-110 TJm
-(oshioka) 30.9949 Tj
--452 TJm
-(Tsuneo) 29.3311 Tj
--452 TJm
-(\() 3.31768 Tj
-[1 0 0 1 390.56 710.037] cm
-0 g
-0 G
-[1 0 0 1 -390.56 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-390.56 710.037 Td
-/F130_0 9.963 Tf
-(QWF00133@niftyserve.or.jp) 149.445 Tj
-[1 0 0 1 540 710.037] cm
-0 g
-0 G
-[1 0 0 1 -540 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 698.082 Td
-/F128_0 9.963 Tf
-(/) 2.76971 Tj
-[1 0 0 1 80.825 698.082] cm
-0 g
-0 G
-[1 0 0 1 -80.825 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-80.825 698.082 Td
-/F130_0 9.963 Tf
-(tsuneo-y@is.aist-nara.ac.) 149.445 Tj
-1 TJm
-(jp) 11.9556 Tj
-[1 0 0 1 242.22 698.082] cm
-0 g
-0 G
-[1 0 0 1 -242.22 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-242.22 698.082 Td
-/F128_0 9.963 Tf
-(\),) 5.80843 Tj
--697 TJm
-(so) 8.85711 Tj
--608 TJm
-(you) 14.9445 Tj
--608 TJm
-(should) 26.5713 Tj
--607 TJm
-(send) 18.2622 Tj
--608 TJm
-(your) 18.2622 Tj
--608 TJm
-(queries) 28.7731 Tj
--607 TJm
-(to) 7.75121 Tj
--608 TJm
-(him) 15.5024 Tj
--608 TJm
-(\(b) 8.29918 Tj
-20 TJm
-(ut) 7.75121 Tj
--608 TJm
-(perha) 22.1278 Tj
-1 TJm
-(ps) 8.85711 Tj
--608 TJm
-(Cc:) 13.8386 Tj
--1026 TJm
-(me,) 14.6655 Tj
-[1 0 0 1 72 686.127] cm
-0 g
-0 G
-[1 0 0 1 -72 -686.127] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 686.127 Td
-/F130_0 9.963 Tf
-(jseward@bzip.org) 95.6448 Tj
-[1 0 0 1 167.641 686.127] cm
-0 g
-0 G
-[1 0 0 1 -167.641 -686.127] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.641 686.127 Td
-/F128_0 9.963 Tf
-(\).) 5.80843 Tj
-[1 0 0 1 72 684.344] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -674.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 664.209 Td
-/F128_0 9.963 Tf
-(My) 13.8386 Tj
--367 TJm
-(v) 4.9815 Tj
-25 TJm
-(ague) 18.8101 Tj
--367 TJm
-(understanding) 56.4504 Tj
--367 TJm
-(of) 8.29918 Tj
--367 TJm
-(what) 19.3681 Tj
--367 TJm
-(to) 7.75121 Tj
--367 TJm
-(do) 9.963 Tj
--367 TJm
-(is:) 9.41504 Tj
--544 TJm
-(using) 21.5898 Tj
--367 TJm
-(V) 7.19329 Tj
-60 TJm
-(isual) 18.8201 Tj
--367 TJm
-(C++) 17.8836 Tj
--367 TJm
-(5.0,) 14.9445 Tj
--397 TJm
-(open) 19.3681 Tj
--367 TJm
-(the) 12.1748 Tj
--367 TJm
-(project) 27.6673 Tj
--367 TJm
-(\002le) 12.7327 Tj
-[1 0 0 1 432.966 664.209] cm
-0 g
-0 G
-[1 0 0 1 -432.966 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-432.966 664.209 Td
-/F130_0 9.963 Tf
-(libbz2.dsp) 59.778 Tj
-[1 0 0 1 492.742 664.209] cm
-0 g
-0 G
-[1 0 0 1 -492.742 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-492.742 664.209 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--396 TJm
-(and) 14.3866 Tj
--367 TJm
-(b) 4.9815 Tj
-20 TJm
-(uild.) 17.9932 Tj
-72 652.254 Td
-(That') 21.5799 Tj
-55 TJm
-(s) 3.87561 Tj
--250 TJm
-(all.) 12.4538 Tj
-[1 0 0 1 72 652.155] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -642.192] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 630.336 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--284 TJm
-(you) 14.9445 Tj
--284 TJm
-(can') 17.1463 Tj
-18 TJm
-(t) 2.76971 Tj
--284 TJm
-(open) 19.3681 Tj
--285 TJm
-(the) 12.1748 Tj
--284 TJm
-(project) 27.6673 Tj
--284 TJm
-(\002le) 12.7327 Tj
--284 TJm
-(for) 11.6169 Tj
--284 TJm
-(some) 21.0319 Tj
--284 TJm
-(reason,) 28.4942 Tj
--293 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--284 TJm
-(a) 4.42357 Tj
--284 TJm
-(ne) 9.40507 Tj
-25 TJm
-(w) 7.19329 Tj
--284 TJm
-(one,) 16.8773 Tj
--293 TJm
-(naming) 29.889 Tj
--284 TJm
-(these) 20.474 Tj
--284 TJm
-(\002les:) 19.378 Tj
-[1 0 0 1 424.505 630.336] cm
-0 g
-0 G
-[1 0 0 1 -424.505 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-424.505 630.336 Td
-/F130_0 9.963 Tf
-(blocksort.c) 65.7558 Tj
-[1 0 0 1 490.259 630.336] cm
-0 g
-0 G
-[1 0 0 1 -490.259 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-490.259 630.336 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 495.666 630.336] cm
-0 g
-0 G
-[1 0 0 1 -495.666 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-495.666 630.336 Td
-/F130_0 9.963 Tf
-(bzlib.c) 41.8446 Tj
-[1 0 0 1 537.509 630.336] cm
-0 g
-0 G
-[1 0 0 1 -537.509 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 630.336 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 72 618.381] cm
-0 g
-0 G
-[1 0 0 1 -72 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 618.381 Td
-/F130_0 9.963 Tf
-(compress.c) 59.778 Tj
-[1 0 0 1 131.776 618.381] cm
-0 g
-0 G
-[1 0 0 1 -131.776 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.776 618.381 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 136.436 618.381] cm
-0 g
-0 G
-[1 0 0 1 -136.436 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-136.436 618.381 Td
-/F130_0 9.963 Tf
-(crctable.c) 59.778 Tj
-[1 0 0 1 196.211 618.381] cm
-0 g
-0 G
-[1 0 0 1 -196.211 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.211 618.381 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 200.871 618.381] cm
-0 g
-0 G
-[1 0 0 1 -200.871 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.871 618.381 Td
-/F130_0 9.963 Tf
-(decompress.c) 71.7336 Tj
-[1 0 0 1 272.602 618.381] cm
-0 g
-0 G
-[1 0 0 1 -272.602 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.602 618.381 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 277.262 618.381] cm
-0 g
-0 G
-[1 0 0 1 -277.262 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.262 618.381 Td
-/F130_0 9.963 Tf
-(huffman.c) 53.8002 Tj
-[1 0 0 1 331.06 618.381] cm
-0 g
-0 G
-[1 0 0 1 -331.06 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-331.06 618.381 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 335.72 618.381] cm
-0 g
-0 G
-[1 0 0 1 -335.72 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.72 618.381 Td
-/F130_0 9.963 Tf
-(randtable.c) 65.7558 Tj
-[1 0 0 1 401.473 618.381] cm
-0 g
-0 G
-[1 0 0 1 -401.473 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-403.562 618.381 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 420.037 618.381] cm
-0 g
-0 G
-[1 0 0 1 -420.037 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-420.037 618.381 Td
-/F130_0 9.963 Tf
-(libbz2.def) 59.778 Tj
-[1 0 0 1 479.812 618.381] cm
-0 g
-0 G
-[1 0 0 1 -479.812 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-479.812 618.381 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--593 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--210 TJm
-(will) 15.5024 Tj
--209 TJm
-(also) 16.0504 Tj
-72 606.426 Td
-(need) 18.8101 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(name) 21.5799 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(header) 26.5514 Tj
--250 TJm
-(\002les) 16.6083 Tj
-[1 0 0 1 190.415 606.426] cm
-0 g
-0 G
-[1 0 0 1 -190.415 -606.426] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-190.415 606.426 Td
-/F130_0 9.963 Tf
-(bzlib.h) 41.8446 Tj
-[1 0 0 1 232.258 606.426] cm
-0 g
-0 G
-[1 0 0 1 -232.258 -606.426] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.749 606.426 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 251.625 606.426] cm
-0 g
-0 G
-[1 0 0 1 -251.625 -606.426] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-251.625 606.426 Td
-/F130_0 9.963 Tf
-(bzlib_private.h) 89.667 Tj
-[1 0 0 1 341.289 606.426] cm
-0 g
-0 G
-[1 0 0 1 -341.289 -606.426] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.289 606.426 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 604.862] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -594.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 584.508 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(don') 18.2622 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(VC++,) 27.5676 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(ma) 12.1748 Tj
-1 TJm
-(y) 4.9815 Tj
--250 TJm
-(need) 18.8101 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(de\002ne) 24.3496 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(proprocessor) 51.4589 Tj
--250 TJm
-(symbol) 29.341 Tj
-[1 0 0 1 363.634 584.508] cm
-0 g
-0 G
-[1 0 0 1 -363.634 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.634 584.508 Td
-/F130_0 9.963 Tf
-(_WIN32) 35.8668 Tj
-[1 0 0 1 399.5 584.508] cm
-0 g
-0 G
-[1 0 0 1 -399.5 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-399.5 584.508 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 582.351] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -572.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 562.59 Td
-/F128_0 9.963 Tf
-(Finally) 28.2351 Tj
-65 TJm
-(,) 2.49075 Tj
-[1 0 0 1 104.568 562.59] cm
-0 g
-0 G
-[1 0 0 1 -104.568 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.568 562.59 Td
-/F130_0 9.963 Tf
-(dlltest.c) 53.8002 Tj
-[1 0 0 1 158.366 562.59] cm
-0 g
-0 G
-[1 0 0 1 -158.366 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-160.856 562.59 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(sample) 28.2252 Tj
--250 TJm
-(program) 33.7546 Tj
--250 TJm
-(using) 21.5898 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(D) 7.19329 Tj
-1 TJm
-(LL.) 14.6655 Tj
--500 TJm
-(It) 6.08739 Tj
--250 TJm
-(has) 13.2807 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(project) 27.6673 Tj
--250 TJm
-(\002le,) 15.2235 Tj
-[1 0 0 1 388.58 562.59] cm
-0 g
-0 G
-[1 0 0 1 -388.58 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-388.58 562.59 Td
-/F130_0 9.963 Tf
-(dlltest.dsp) 65.7558 Tj
-[1 0 0 1 454.333 562.59] cm
-0 g
-0 G
-[1 0 0 1 -454.333 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-454.333 562.59 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 560.433] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -550.471] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 540.672 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(just) 14.3965 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e\002le) 17.1563 Tj
--250 TJm
-(fo) 8.29918 Tj
-1 TJm
-(r) 3.31768 Tj
--250 TJm
-(V) 7.19329 Tj
-60 TJm
-(isual) 18.8201 Tj
--250 TJm
-(C,) 9.13607 Tj
--250 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(look) 17.7142 Tj
--250 TJm
-(at) 7.19329 Tj
-[1 0 0 1 292.212 540.672] cm
-0 g
-0 G
-[1 0 0 1 -292.212 -540.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.212 540.672 Td
-/F130_0 9.963 Tf
-(makefile.msc) 71.7336 Tj
-[1 0 0 1 363.943 540.672] cm
-0 g
-0 G
-[1 0 0 1 -363.943 -540.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.943 540.672 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 538.516] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -528.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 518.755 Td
-/F128_0 9.963 Tf
-(Be) 11.0689 Tj
--291 TJm
-(a) 4.42357 Tj
-15 TJm
-(w) 7.19329 Tj
-10 TJm
-(are) 12.1648 Tj
--291 TJm
-(that) 14.9445 Tj
--291 TJm
-(if) 6.08739 Tj
--291 TJm
-(you) 14.9445 Tj
--291 TJm
-(compile) 32.1008 Tj
-[1 0 0 1 192.07 518.755] cm
-0 g
-0 G
-[1 0 0 1 -192.07 -518.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.07 518.755 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 221.957 518.755] cm
-0 g
-0 G
-[1 0 0 1 -221.957 -518.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.857 518.755 Td
-/F128_0 9.963 Tf
-(itself) 19.926 Tj
--291 TJm
-(on) 9.963 Tj
--291 TJm
-(W) 9.40507 Tj
-40 TJm
-(in32,) 20.205 Tj
--301 TJm
-(you) 14.9445 Tj
--291 TJm
-(must) 19.378 Tj
--291 TJm
-(set) 11.0689 Tj
-[1 0 0 1 346.842 518.755] cm
-0 g
-0 G
-[1 0 0 1 -346.842 -518.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-346.842 518.755 Td
-/F130_0 9.963 Tf
-(BZ_UNIX) 41.8446 Tj
-[1 0 0 1 388.685 518.755] cm
-0 g
-0 G
-[1 0 0 1 -388.685 -518.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-391.584 518.755 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--291 TJm
-(0) 4.9815 Tj
--291 TJm
-(and) 14.3866 Tj
-[1 0 0 1 427.399 518.755] cm
-0 g
-0 G
-[1 0 0 1 -427.399 -518.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.399 518.755 Td
-/F130_0 9.963 Tf
-(BZ_LCCWIN32) 65.7558 Tj
-[1 0 0 1 493.153 518.755] cm
-0 g
-0 G
-[1 0 0 1 -493.153 -518.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.052 518.755 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--291 TJm
-(1,) 7.47225 Tj
--301 TJm
-(in) 7.75121 Tj
--291 TJm
-(the) 12.1748 Tj
-72 506.8 Td
-(\002le) 12.7327 Tj
-[1 0 0 1 87.223 506.799] cm
-0 g
-0 G
-[1 0 0 1 -87.223 -506.799] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-87.223 506.799 Td
-/F130_0 9.963 Tf
-(bzip2.c) 41.8446 Tj
-[1 0 0 1 129.066 506.799] cm
-0 g
-0 G
-[1 0 0 1 -129.066 -506.799] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-129.066 506.799 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(before) 25.4455 Tj
--250 TJm
-(compiling.) 42.9007 Tj
--310 TJm
-(Otherwi) 32.6488 Tj
-1 TJm
-(se) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(resulting) 34.8705 Tj
--250 TJm
-(binary) 25.4555 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(on') 13.2807 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--250 TJm
-(correctly) 35.4085 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 504.643] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -494.68] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 484.882 Td
-/F128_0 9.963 Tf
-(I) 3.31768 Tj
--250 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(en') 12.7228 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(tried) 18.2622 Tj
--250 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(stuf) 14.9445 Tj
-25 TJm
-(f) 3.31768 Tj
--249 TJm
-(myself,) 29.61 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(looks) 21.5898 Tj
--250 TJm
-(plausible.) 38.4671 Tj
-[1 0 0 1 72 482.725] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -431.873] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(30) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 34 34
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 140.398 0] cm
-0 g
-0 G
-[1 0 0 1 -140.398 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -13.948] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -21.554] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F121_0 24.79 Tf
-(4.) 20.6749 Tj
--278 TJm
-(Miscellanea) 139.171 Tj
-[1 0 0 1 72 701.606] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.135] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -14.116] cm
-0 g
-0 G
-[1 0 0 1 -72 -678.355] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 658.006 Td
-/F121_0 17.215 Tf
-(T) 10.5184 Tj
-80 TJm
-(ab) 20.0899 Tj
-10 TJm
-(le) 14.3573 Tj
--278 TJm
-(of) 16.251 Tj
--278 TJm
-(Contents) 74.5926 Tj
-[1 0 0 1 72 649.183] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -11.74] cm
-0 g
-0 G
-[1 0 0 1 -72 -637.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 637.443 Td
-/F128_0 9.963 Tf
-(4.1.) 14.9445 Tj
--310 TJm
-(Limitations) 45.9494 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(comp) 22.1378 Tj
-1 TJm
-(ressed) 24.8975 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(format) 26.5614 Tj
-[1 0 0 1 255.231 637.443] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -260.212 -637.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.154 637.443 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 637.443] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -637.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 637.443 Td
-/F128_0 9.963 Tf
-(31) 9.963 Tj
-[1 0 0 1 516.09 637.443] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -625.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 625.488 Td
-/F128_0 9.963 Tf
-(4.2.) 14.9445 Tj
--310 TJm
-(Portability) 42.0737 Tj
--250 TJm
-(issues) 23.8016 Tj
-[1 0 0 1 158.395 625.488] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -163.376 -625.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.03 625.488 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 625.488] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -625.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 625.488 Td
-/F128_0 9.963 Tf
-(32) 9.963 Tj
-[1 0 0 1 516.09 625.488] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -613.533] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 613.533 Td
-/F128_0 9.963 Tf
-(4.3.) 14.9445 Tj
--310 TJm
-(Reporting) 39.852 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ugs) 13.8386 Tj
-[1 0 0 1 150.993 613.533] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 -155.975 -613.533] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.115 613.533 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 613.533] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -613.533] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 613.533 Td
-/F128_0 9.963 Tf
-(32) 9.963 Tj
-[1 0 0 1 516.09 613.533] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -601.578] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 601.578 Td
-/F128_0 9.963 Tf
-(4.4.) 14.9445 Tj
--310 TJm
-(Did) 14.9445 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(get) 12.1748 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(right) 18.8201 Tj
--250 TJm
-(packa) 23.2337 Tj
-1 TJm
-(ge?) 13.8286 Tj
-[1 0 0 1 212.602 601.578] cm
-0 g
-0 G
-[1 0 0 1 3.088 0] cm
-0 g
-0 G
-[1 0 0 1 3.088 0] cm
-0 g
-0 G
-[1 0 0 1 -218.778 -601.578] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.109 601.578 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 601.578] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -601.578] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 601.578 Td
-/F128_0 9.963 Tf
-(33) 9.963 Tj
-[1 0 0 1 516.09 601.578] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.798] cm
-0 g
-0 G
-[1 0 0 1 -72 -589.623] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 589.623 Td
-/F128_0 9.963 Tf
-(4.5.) 14.9445 Tj
--310 TJm
-(Further) 29.3311 Tj
--250 TJm
-(Reading) 33.2067 Tj
-[1 0 0 1 155.058 589.623] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 -160.039 -589.623] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.361 589.623 Td
-/F143_0 9.963 Tf
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
--166 TJm
-(:) 2.76971 Tj
--167 TJm
-(:) 2.76971 Tj
-[1 0 0 1 506.127 589.623] cm
-0 g
-0 G
-[1 0 0 1 -506.127 -589.623] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 589.623 Td
-/F128_0 9.963 Tf
-(34) 9.963 Tj
-[1 0 0 1 516.09 589.623] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -444.09 -2.157] cm
-0 g
-0 G
-[1 0 0 1 0 -9.135] cm
-0 g
-0 G
-[1 0 0 1 0 -9.631] cm
-0 g
-0 G
-[1 0 0 1 -72 -568.7] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 558.901 Td
-/F128_0 9.963 Tf
-(These) 23.7916 Tj
--250 TJm
-(are) 12.1648 Tj
--250 TJm
-(just) 14.3965 Tj
--250 TJm
-(some) 21.0319 Tj
--250 TJm
-(random) 30.437 Tj
--249 TJm
-(thoughts) 34.3225 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(mine.) 22.4168 Tj
--620 TJm
-(Y) 7.19329 Tj
-110 TJm
-(our) 13.2807 Tj
--250 TJm
-(mileage) 31.5429 Tj
--250 TJm
-(may) 17.1563 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(ary) 12.7228 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 556.744] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.631] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -547.113] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 524.48 Td
-/F121_0 20.659 Tf
-(4.1.) 34.4592 Tj
--278 TJm
-(Limitations) 110.195 Tj
--278 TJm
-(of) 19.5021 Tj
--278 TJm
-(the) 30.9885 Tj
--278 TJm
-(compres) 86.1067 Tj
-1 TJm
-(sed) 35.5955 Tj
--278 TJm
-(\002le) 29.8523 Tj
--278 TJm
-(f) 6.87945 Tj
-20 TJm
-(ormat) 57.3907 Tj
-[1 0 0 1 72 520.203] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.631] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -510.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 502.893 Td
-/F130_0 9.963 Tf
-(bzip2-1.0.X) 65.7558 Tj
-[1 0 0 1 137.753 502.893] cm
-0 g
-0 G
-[1 0 0 1 -137.753 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.753 502.893 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
-[1 0 0 1 143.405 502.893] cm
-0 g
-0 G
-[1 0 0 1 -143.405 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.405 502.893 Td
-/F130_0 9.963 Tf
-(0.9.5) 29.889 Tj
-[1 0 0 1 173.293 502.893] cm
-0 g
-0 G
-[1 0 0 1 -173.293 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.453 502.893 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 194 502.893] cm
-0 g
-0 G
-[1 0 0 1 -194 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194 502.893 Td
-/F130_0 9.963 Tf
-(0.9.0) 29.889 Tj
-[1 0 0 1 223.888 502.893] cm
-0 g
-0 G
-[1 0 0 1 -223.888 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-227.048 502.893 Td
-/F128_0 9.963 Tf
-(use) 13.2807 Tj
--317 TJm
-(e) 4.42357 Tj
-15 TJm
-(xactly) 24.3496 Tj
--317 TJm
-(the) 12.1748 Tj
--318 TJm
-(s) 3.87561 Tj
-1 TJm
-(ame) 16.5984 Tj
--318 TJm
-(\002le) 12.7327 Tj
--317 TJm
-(format) 26.5614 Tj
--317 TJm
-(as) 8.29918 Tj
--317 TJm
-(the) 12.1748 Tj
--317 TJm
-(original) 30.9949 Tj
--317 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion,) 26.8403 Tj
-[1 0 0 1 455.801 502.893] cm
-0 g
-0 G
-[1 0 0 1 -455.801 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-455.801 502.893 Td
-/F130_0 9.963 Tf
-(bzip2-0.1) 53.8002 Tj
-[1 0 0 1 509.599 502.893] cm
-0 g
-0 G
-[1 0 0 1 -509.599 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-509.599 502.893 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--1023 TJm
-(This) 17.7142 Tj
-72 490.938 Td
-(decision) 33.2067 Tj
--222 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--221 TJm
-(made) 21.5799 Tj
--222 TJm
-(in) 7.75121 Tj
--222 TJm
-(the) 12.1748 Tj
--222 TJm
-(interests) 33.2067 Tj
--221 TJm
-(of) 8.29918 Tj
--222 TJm
-(stability) 32.1107 Tj
-65 TJm
-(.) 2.49075 Tj
--601 TJm
-(Creating) 34.3126 Tj
--222 TJm
-(yet) 12.1748 Tj
--222 TJm
-(another) 29.879 Tj
--222 TJm
-(inc) 12.1748 Tj
-1 TJm
-(ompatible) 39.852 Tj
--222 TJm
-(compressed) 47.0353 Tj
--222 TJm
-(\002le) 12.7327 Tj
--222 TJm
-(form) 19.3681 Tj
-1 TJm
-(at) 7.19329 Tj
--222 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--222 TJm
-(create) 23.7817 Tj
-72 478.983 Td
-(further) 27.1093 Tj
--250 TJm
-(confusion) 39.2941 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(disrupti) 30.4469 Tj
-1 TJm
-(on) 9.963 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(users.) 22.9647 Tj
-[1 0 0 1 72 476.826] cm
-0 g
-0 G
-[1 0 0 1 0 -9.632] cm
-0 g
-0 G
-[1 0 0 1 -72 -467.194] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 457.396 Td
-/F128_0 9.963 Tf
-(Ne) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ertheless,) 37.3513 Tj
--233 TJm
-(this) 14.3965 Tj
--230 TJm
-(is) 6.64532 Tj
--229 TJm
-(not) 12.7327 Tj
--230 TJm
-(a) 4.42357 Tj
--229 TJm
-(painless) 32.1008 Tj
--230 TJm
-(decisio) 28.2252 Tj
-1 TJm
-(n.) 7.47225 Tj
--607 TJm
-(De) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(elopment) 37.0823 Tj
--229 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--230 TJm
-(si) 6.64532 Tj
-1 TJm
-(nce) 13.8286 Tj
--230 TJm
-(the) 12.1748 Tj
--229 TJm
-(release) 27.6573 Tj
--230 TJm
-(of) 8.29918 Tj
-[1 0 0 1 407.317 457.396] cm
-0 g
-0 G
-[1 0 0 1 -407.317 -457.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-407.317 457.396 Td
-/F130_0 9.963 Tf
-(bzip2-0.1) 53.8002 Tj
-[1 0 0 1 461.115 457.396] cm
-0 g
-0 G
-[1 0 0 1 -461.115 -457.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-463.402 457.396 Td
-/F128_0 9.963 Tf
-(in) 7.75121 Tj
--229 TJm
-(August) 28.7831 Tj
--230 TJm
-(1997) 19.926 Tj
--229 TJm
-(has) 13.2807 Tj
-72 445.441 Td
-(sho) 13.8386 Tj
-25 TJm
-(wn) 12.1748 Tj
--226 TJm
-(comple) 29.3311 Tj
-15 TJm
-(xities) 21.5898 Tj
--225 TJm
-(in) 7.75121 Tj
--226 TJm
-(the) 12.1748 Tj
--226 TJm
-(\002le) 12.7327 Tj
--226 TJm
-(forma) 23.7916 Tj
-1 TJm
-(t) 2.76971 Tj
--226 TJm
-(which) 24.3496 Tj
--226 TJm
-(slo) 11.6268 Tj
-25 TJm
-(w) 7.19329 Tj
--226 TJm
-(do) 9.963 Tj
-25 TJm
-(wn) 12.1748 Tj
--225 TJm
-(decompression) 59.768 Tj
--226 TJm
-(and,) 16.8773 Tj
--231 TJm
-(in) 7.75121 Tj
--225 TJm
-(retrospect,) 41.7749 Tj
--231 TJm
-(are) 12.1648 Tj
--226 TJm
-(unnecess) 35.9664 Tj
-1 TJm
-(ary) 12.7228 Tj
-65 TJm
-(.) 2.49075 Tj
--604 TJm
-(These) 23.7916 Tj
--226 TJm
-(are:) 14.9345 Tj
-[1 0 0 1 72 443.284] cm
-0 g
-0 G
-[1 0 0 1 0 -29.062] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -414.222] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 414.222 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 414.222] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -414.222] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 414.222 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--265 TJm
-(run-length) 41.5059 Tj
--265 TJm
-(encoder) 31.5329 Tj
-40 TJm
-(,) 2.49075 Tj
--269 TJm
-(which) 24.3496 Tj
--266 TJm
-(is) 6.64532 Tj
--265 TJm
-(the) 12.1748 Tj
--265 TJm
-(\002rst) 15.5024 Tj
--265 TJm
-(of) 8.29918 Tj
--266 TJm
-(the) 12.1748 Tj
--265 TJm
-(compression) 50.363 Tj
--265 TJm
-(transformations,) 65.0285 Tj
--269 TJm
-(is) 6.64532 Tj
--265 TJm
-(entirely) 30.437 Tj
--265 TJm
-(irrele) 21.0219 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ant.) 14.6655 Tj
--712 TJm
-(The) 15.4925 Tj
--265 TJm
-(original) 30.9949 Tj
-86.944 402.267 Td
-(purpose) 31.5429 Tj
--301 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--301 TJm
-(to) 7.75121 Tj
--301 TJm
-(protect) 27.6673 Tj
--301 TJm
-(the) 12.1748 Tj
--301 TJm
-(sorting) 27.6772 Tj
--301 TJm
-(algorit) 26.0134 Tj
-1 TJm
-(hm) 12.7327 Tj
--301 TJm
-(from) 19.3681 Tj
--301 TJm
-(the) 12.1748 Tj
--301 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
--301 TJm
-(w) 7.19329 Tj
-10 TJm
-(orst) 14.9445 Tj
--301 TJm
-(case) 17.1463 Tj
--301 TJm
-(input:) 23.2536 Tj
--412 TJm
-(a) 4.42357 Tj
--301 TJm
-(string) 22.6957 Tj
--301 TJm
-(of) 8.29918 Tj
--301 TJm
-(repeated) 33.7447 Tj
--301 TJm
-(symbols.) 35.7074 Tj
--926 TJm
-(But) 14.3965 Tj
-86.944 390.312 Td
-(algorithm) 38.7461 Tj
--274 TJm
-(steps) 19.926 Tj
--274 TJm
-(Q6a) 16.5984 Tj
--275 TJm
-(and) 14.3866 Tj
--274 TJm
-(Q6b) 17.1563 Tj
--274 TJm
-(in) 7.75121 Tj
--274 TJm
-(the) 12.1748 Tj
--275 TJm
-(original) 30.9949 Tj
--274 TJm
-(Burro) 23.2437 Tj
-25 TJm
-(ws-Wheeler) 48.1313 Tj
--274 TJm
-(technical) 35.9664 Tj
--274 TJm
-(report) 23.7916 Tj
--274 TJm
-(\(SRC-124\)) 43.7276 Tj
--274 TJm
-(sho) 13.8386 Tj
-25 TJm
-(w) 7.19329 Tj
--275 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--274 TJm
-(repeats) 28.2152 Tj
--274 TJm
-(can) 13.8286 Tj
-86.944 378.357 Td
-(be) 9.40507 Tj
--250 TJm
-(handled) 31.5429 Tj
--250 TJm
-(without) 30.4469 Tj
--250 TJm
-(dif) 11.0689 Tj
-25 TJm
-(\002culty) 25.4654 Tj
--249 TJm
-(in) 7.75121 Tj
--250 TJm
-(block) 22.1378 Tj
--250 TJm
-(sorting.) 30.168 Tj
-[1 0 0 1 269.617 378.357] cm
-0 g
-0 G
-[1 0 0 1 -197.617 -21.587] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -356.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 356.77 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 356.77] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -356.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 356.77 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--293 TJm
-(randomisation) 57.0083 Tj
--293 TJm
-(mechanism) 45.3815 Tj
--293 TJm
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--293 TJm
-(really) 22.6858 Tj
--293 TJm
-(need) 18.8101 Tj
--293 TJm
-(to) 7.75121 Tj
--293 TJm
-(be) 9.40507 Tj
--293 TJm
-(there.) 22.4068 Tj
--879 TJm
-(Udi) 14.9445 Tj
--294 TJm
-(Man) 18.2622 Tj
-1 TJm
-(ber) 12.7228 Tj
--294 TJm
-(and) 14.3866 Tj
--293 TJm
-(Gene) 21.0219 Tj
--293 TJm
-(Myers) 25.4555 Tj
--293 TJm
-(published) 38.7461 Tj
--293 TJm
-(a) 4.42357 Tj
--293 TJm
-(suf) 12.1748 Tj
-25 TJm
-(\002x) 10.5209 Tj
-86.944 344.815 Td
-(array) 20.464 Tj
--238 TJm
-(construction) 49.2571 Tj
--238 TJm
-(algorithm) 38.7461 Tj
--239 TJm
-(a) 4.42357 Tj
--238 TJm
-(fe) 7.74125 Tj
-25 TJm
-(w) 7.19329 Tj
--238 TJm
-(years) 21.0219 Tj
--238 TJm
-(back,) 21.3009 Tj
--241 TJm
-(which) 24.3496 Tj
--238 TJm
-(can) 13.8286 Tj
--238 TJm
-(be) 9.40507 Tj
--239 TJm
-(emplo) 24.9075 Tj
-10 TJm
-(yed) 14.3866 Tj
--238 TJm
-(to) 7.75121 Tj
--238 TJm
-(sort) 14.9445 Tj
--239 TJm
-(a) 4.42357 Tj
-1 TJm
-(n) 4.9815 Tj
-15 TJm
-(y) 4.9815 Tj
--239 TJm
-(block,) 24.6285 Tj
--240 TJm
-(no) 9.963 Tj
--239 TJm
-(matter) 25.4555 Tj
--238 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--238 TJm
-(repetiti) 28.2252 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e,) 6.91432 Tj
-86.944 332.86 Td
-(in) 7.75121 Tj
--229 TJm
-(O\(N) 17.7043 Tj
--230 TJm
-(log) 12.7327 Tj
--229 TJm
-(N\)) 10.511 Tj
--230 TJm
-(time.) 20.205 Tj
--606 TJm
-(Subsequent) 45.9394 Tj
--229 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--229 TJm
-(by) 9.963 Tj
--230 TJm
-(K) 7.19329 Tj
-15 TJm
-(unihik) 25.4654 Tj
-10 TJm
-(o) 4.9815 Tj
--229 TJm
-(Sadakane) 38.1782 Tj
--230 TJm
-(ha) 9.40507 Tj
-1 TJm
-(s) 3.87561 Tj
--230 TJm
-(produced) 37.0723 Tj
--229 TJm
-(a) 4.42357 Tj
--230 TJm
-(deri) 15.4925 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ati) 9.963 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--229 TJm
-(O\(N) 17.7043 Tj
--229 TJm
-(\(log) 16.0504 Tj
--230 TJm
-(N\)^2\)) 23.4828 Tj
--229 TJm
-(algorithm) 38.7461 Tj
-86.944 320.905 Td
-(which) 24.3496 Tj
--250 TJm
-(usually) 28.7831 Tj
--250 TJm
-(outperforms) 48.6991 Tj
--250 TJm
-(th) 7.75121 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(Manber) 30.9849 Tj
-20 TJm
-(-Myers) 28.7731 Tj
--250 TJm
-(algorithm.) 41.2369 Tj
-[1 0 0 1 314.189 320.905] cm
-0 g
-0 G
-[1 0 0 1 -242.189 -11.789] cm
-0 g
-0 G
-[1 0 0 1 -72 -309.116] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 299.318 Td
-/F128_0 9.963 Tf
-(I) 3.31768 Tj
--248 TJm
-(could) 22.1378 Tj
--248 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--248 TJm
-(changed) 33.1967 Tj
--248 TJm
-(to) 7.75121 Tj
--248 TJm
-(Sadakane') 41.4959 Tj
-55 TJm
-(s) 3.87561 Tj
--248 TJm
-(algor) 20.474 Tj
-1 TJm
-(ithm,) 20.7629 Tj
--249 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--248 TJm
-(I) 3.31768 Tj
--248 TJm
-(\002nd) 15.5024 Tj
--248 TJm
-(it) 5.53943 Tj
--248 TJm
-(to) 7.75121 Tj
--248 TJm
-(be) 9.40507 Tj
--248 TJm
-(slo) 11.6268 Tj
-25 TJm
-(wer) 14.9345 Tj
--248 TJm
-(than) 17.1563 Tj
-[1 0 0 1 392.444 299.318] cm
-0 g
-0 G
-[1 0 0 1 -392.444 -299.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.444 299.318 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 422.332 299.318] cm
-0 g
-0 G
-[1 0 0 1 -422.332 -299.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.332 299.318 Td
-/F128_0 9.963 Tf
-(') 3.31768 Tj
-55 TJm
-(s) 3.87561 Tj
--248 TJm
-(e) 4.42357 Tj
-15 TJm
-(xisting) 27.1292 Tj
--248 TJm
-(algorithm) 38.7461 Tj
--248 TJm
-(for) 11.6169 Tj
--248 TJm
-(most) 19.378 Tj
-86.944 287.363 Td
-(inputs,) 26.8503 Tj
--369 TJm
-(and) 14.3866 Tj
--346 TJm
-(the) 12.1748 Tj
--346 TJm
-(randomis) 37.0823 Tj
-1 TJm
-(ation) 19.926 Tj
--346 TJm
-(mechanism) 45.3815 Tj
--346 TJm
-(p) 4.9815 Tj
-1 TJm
-(rotects) 26.5614 Tj
--346 TJm
-(adequately) 43.1597 Tj
--345 TJm
-(ag) 9.40507 Tj
-5 TJm
-(ainst) 18.8201 Tj
--346 TJm
-(bad) 14.3866 Tj
--346 TJm
-(cases) 21.0219 Tj
-1 TJm
-(.) 2.49075 Tj
--1194 TJm
-(I) 3.31768 Tj
--346 TJm
-(didn') 21.0319 Tj
-18 TJm
-(t) 2.76971 Tj
--346 TJm
-(think) 20.4839 Tj
--345 TJm
-(it) 5.53943 Tj
--346 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--345 TJm
-(a) 4.42357 Tj
--346 TJm
-(good) 19.926 Tj
-86.944 275.408 Td
-(tradeof) 28.2152 Tj
-25 TJm
-(f) 3.31768 Tj
--261 TJm
-(to) 7.75121 Tj
--262 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e.) 6.91432 Tj
--690 TJm
-(P) 5.53943 Tj
-15 TJm
-(artly) 18.2622 Tj
--261 TJm
-(this) 14.3965 Tj
--262 TJm
-(is) 6.64532 Tj
--261 TJm
-(due) 14.3866 Tj
--262 TJm
-(to) 7.75121 Tj
--261 TJm
-(the) 12.1748 Tj
--262 TJm
-(f) 3.31768 Tj
-10 TJm
-(act) 11.6169 Tj
--261 TJm
-(that) 14.9445 Tj
--262 TJm
-(I) 3.31768 Tj
--262 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--261 TJm
-(not) 12.7327 Tj
--262 TJm
-(\003ooded) 29.889 Tj
--261 TJm
-(with) 17.7142 Tj
--262 TJm
-(email) 22.1378 Tj
--261 TJm
-(complaints) 43.7276 Tj
--262 TJm
-(about) 22.1378 Tj
-[1 0 0 1 479.557 275.408] cm
-0 g
-0 G
-[1 0 0 1 -479.557 -275.408] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-479.557 275.408 Td
-/F130_0 9.963 Tf
-(bzip2-0.1) 53.8002 Tj
-[1 0 0 1 533.355 275.408] cm
-0 g
-0 G
-[1 0 0 1 -533.355 -275.408] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 275.408 Td
-/F128_0 9.963 Tf
-(') 3.31768 Tj
-55 TJm
-(s) 3.87561 Tj
-86.944 263.453 Td
-(performance) 50.343 Tj
--250 TJm
-(on) 9.963 Tj
--250 TJm
-(repetiti) 28.2252 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(dat) 12.1748 Tj
-1 TJm
-(a,) 6.91432 Tj
--250 TJm
-(so) 8.85711 Tj
--250 TJm
-(perhaps) 30.9849 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(isn') 14.9445 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(problem) 33.2067 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(real) 14.9345 Tj
--250 TJm
-(inputs.) 26.8503 Tj
-[1 0 0 1 72 261.296] cm
-0 g
-0 G
-[1 0 0 1 0 -9.632] cm
-0 g
-0 G
-[1 0 0 1 -72 -251.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 241.866 Td
-/F128_0 9.963 Tf
-(Probably) 35.9764 Tj
--289 TJm
-(the) 12.1748 Tj
--288 TJm
-(best) 16.0504 Tj
--289 TJm
-(long-term) 39.2941 Tj
--288 TJm
-(solution,) 34.6015 Tj
--299 TJm
-(and) 14.3866 Tj
--288 TJm
-(the) 12.1748 Tj
--289 TJm
-(one) 14.3866 Tj
--289 TJm
-(I) 3.31768 Tj
--288 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--289 TJm
-(incorporated) 50.353 Tj
--288 TJm
-(into) 15.5024 Tj
--289 TJm
-(0.9.5) 19.926 Tj
--289 TJm
-(and) 14.3866 Tj
--288 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e,) 6.91432 Tj
--298 TJm
-(is) 6.64532 Tj
--289 TJm
-(to) 7.75121 Tj
--289 TJm
-(use) 13.2807 Tj
--288 TJm
-(the) 12.1748 Tj
--289 TJm
-(e) 4.42357 Tj
-15 TJm
-(xisting) 27.1292 Tj
-86.944 229.911 Td
-(sorting) 27.6772 Tj
--451 TJm
-(algorithm) 38.7461 Tj
--451 TJm
-(initially) 31.0049 Tj
-65 TJm
-(,) 2.49075 Tj
--502 TJm
-(and) 14.3866 Tj
--451 TJm
-(f) 3.31768 Tj
-10 TJm
-(all) 9.963 Tj
--452 TJm
-(back) 18.8101 Tj
--451 TJm
-(to) 7.75121 Tj
--451 TJm
-(a) 4.42357 Tj
--452 TJm
-(O\(N) 17.7043 Tj
--451 TJm
-(\(log) 16.0504 Tj
--451 TJm
-(N\)^2\)) 23.4828 Tj
--451 TJm
-(algorithm) 38.7461 Tj
--452 TJm
-(if) 6.08739 Tj
--451 TJm
-(the) 12.1748 Tj
--451 TJm
-(standard) 33.7546 Tj
--452 TJm
-(al) 7.19329 Tj
-1 TJm
-(gorithm) 31.5528 Tj
--452 TJm
-(gets) 16.0504 Tj
--451 TJm
-(into) 15.5024 Tj
-86.944 217.956 Td
-(dif) 11.0689 Tj
-25 TJm
-(\002culties.) 34.0436 Tj
-[1 0 0 1 72 217.856] cm
-0 g
-0 G
-[1 0 0 1 0 -21.487] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -196.369] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 196.369 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 196.369] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -196.369] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 196.369 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--299 TJm
-(compressed) 47.0353 Tj
--299 TJm
-(\002le) 12.7327 Tj
--299 TJm
-(format) 26.5614 Tj
--299 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--299 TJm
-(ne) 9.40507 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--299 TJm
-(designed) 35.4185 Tj
--299 TJm
-(to) 7.75121 Tj
--299 TJm
-(be) 9.40507 Tj
--299 TJm
-(handled) 31.5429 Tj
--299 TJm
-(by) 9.963 Tj
--299 TJm
-(a) 4.42357 Tj
--299 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--312 TJm
-(and) 14.3866 Tj
--299 TJm
-(I) 3.31768 Tj
--299 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--299 TJm
-(had) 14.3866 Tj
--299 TJm
-(to) 7.75121 Tj
--299 TJm
-(jump) 20.4839 Tj
--299 TJm
-(though) 27.6772 Tj
--299 TJm
-(some) 21.0319 Tj
-86.944 184.414 Td
-(hoops) 23.8016 Tj
--278 TJm
-(to) 7.75121 Tj
--277 TJm
-(produce) 32.0908 Tj
--278 TJm
-(an) 9.40507 Tj
--277 TJm
-(ef) 7.74125 Tj
-25 TJm
-(\002cient) 24.9075 Tj
--278 TJm
-(implementation) 62.5477 Tj
--277 TJm
-(of) 8.29918 Tj
--278 TJm
-(decompression.) 62.2588 Tj
--786 TJm
-(It') 9.40507 Tj
-55 TJm
-(s) 3.87561 Tj
--278 TJm
-(a) 4.42357 Tj
--277 TJm
-(bit) 10.5209 Tj
--278 TJm
-(hairy) 20.474 Tj
-65 TJm
-(.) 2.49075 Tj
--786 TJm
-(T) 6.08739 Tj
-35 TJm
-(ry) 8.29918 Tj
--278 TJm
-(passing) 29.889 Tj
-[1 0 0 1 468.269 184.414] cm
-0 g
-0 G
-[1 0 0 1 -468.269 -184.414] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.269 184.414 Td
-/F130_0 9.963 Tf
-(decompress.c) 71.7336 Tj
-[1 0 0 1 540 184.414] cm
-0 g
-0 G
-[1 0 0 1 -540 -184.414] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 172.459 Td
-/F128_0 9.963 Tf
-(through) 30.9949 Tj
--268 TJm
-(the) 12.1748 Tj
--268 TJm
-(C) 6.64532 Tj
--268 TJm
-(preprocessor) 50.901 Tj
--268 TJm
-(and) 14.3866 Tj
--268 TJm
-(you') 18.2622 Tj
-10 TJm
-(ll) 5.53943 Tj
--268 TJm
-(see) 12.7228 Tj
--268 TJm
-(what) 19.3681 Tj
--268 TJm
-(I) 3.31768 Tj
--269 TJm
-(mea) 16.5984 Tj
-1 TJm
-(n.) 7.47225 Tj
--729 TJm
-(Much) 23.2437 Tj
--268 TJm
-(of) 8.29918 Tj
--269 TJm
-(this) 14.3965 Tj
--268 TJm
-(comple) 29.3311 Tj
-15 TJm
-(xit) 10.5209 Tj
-1 TJm
-(y) 4.9815 Tj
--269 TJm
-(could) 22.1378 Tj
--268 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--268 TJm
-(been) 18.8101 Tj
--268 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-20 TJm
-(oided) 22.1378 Tj
--268 TJm
-(if) 6.08739 Tj
--268 TJm
-(the) 12.1748 Tj
-86.944 160.503 Td
-(compressed) 47.0353 Tj
--250 TJm
-(size) 15.4925 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(each) 18.2522 Tj
--250 TJm
-(bloc) 17.1563 Tj
-1 TJm
-(k) 4.9815 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--250 TJm
-(recorded) 34.8506 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(data) 16.5984 Tj
--250 TJm
-(stream.) 29.0521 Tj
-[1 0 0 1 368.754 160.503] cm
-0 g
-0 G
-[1 0 0 1 -296.754 -21.586] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -138.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 138.917 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 138.917] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -138.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 138.917 Td
-/F128_0 9.963 Tf
-(An) 12.1748 Tj
--250 TJm
-(Adler) 22.6858 Tj
-20 TJm
-(-32) 13.2807 Tj
--250 TJm
-(checksum,) 42.3328 Tj
--250 TJm
-(rather) 23.2337 Tj
--249 TJm
-(than) 17.1563 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(CRC32) 29.899 Tj
--250 TJm
-(checksum,) 42.3328 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(f) 3.31768 Tj
-10 TJm
-(aster) 18.8101 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(compute.) 36.8033 Tj
-[1 0 0 1 424.934 138.917] cm
-0 g
-0 G
-[1 0 0 1 -352.934 -11.789] cm
-0 g
-0 G
-[1 0 0 1 -72 -127.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 117.33 Td
-/F128_0 9.963 Tf
-(It) 6.08739 Tj
--349 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--349 TJm
-(be) 9.40507 Tj
--348 TJm
-(f) 3.31768 Tj
-10 TJm
-(air) 10.511 Tj
--349 TJm
-(to) 7.75121 Tj
--349 TJm
-(say) 13.2807 Tj
--349 TJm
-(that) 14.9445 Tj
--348 TJm
-(the) 12.1748 Tj
-[1 0 0 1 201.979 117.33] cm
-0 g
-0 G
-[1 0 0 1 -201.979 -117.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.979 117.33 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 231.867 117.33] cm
-0 g
-0 G
-[1 0 0 1 -231.867 -117.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.342 117.33 Td
-/F128_0 9.963 Tf
-(format) 26.5614 Tj
--349 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--348 TJm
-(frozen) 25.4455 Tj
--349 TJm
-(before) 25.4455 Tj
--349 TJm
-(I) 3.31768 Tj
--349 TJm
-(properl) 28.7731 Tj
-1 TJm
-(y) 4.9815 Tj
--349 TJm
-(and) 14.3866 Tj
--349 TJm
-(fully) 18.8201 Tj
--349 TJm
-(understood) 44.2756 Tj
--348 TJm
-(the) 12.1748 Tj
--349 TJm
-(performance) 50.343 Tj
-72 105.375 Td
-(consequences) 54.7766 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(doing) 22.6957 Tj
--250 TJm
-(so.) 11.3479 Tj
-[1 0 0 1 72 103.218] cm
-0 g
-0 G
-[1 0 0 1 0 -9.631] cm
-0 g
-0 G
-[1 0 0 1 -72 -93.587] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 83.788 Td
-/F128_0 9.963 Tf
-(Impro) 24.3496 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(ements) 28.2252 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(I) 3.31768 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(as) 8.29918 Tj
--250 TJm
-(abl) 12.1748 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(incorporate) 45.3715 Tj
--250 TJm
-(into) 15.5024 Tj
--250 TJm
-(0.9.0,) 22.4168 Tj
--250 TJm
-(despite) 28.2252 Tj
--250 TJm
-(using) 21.5898 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(same) 20.474 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(for) 11.6169 Tj
-1 TJm
-(mat,) 17.4353 Tj
--250 TJm
-(are:) 14.9345 Tj
-[1 0 0 1 72 81.631] cm
-0 g
-0 G
-[1 0 0 1 0 -30.779] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(31) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 35 35
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -6.854] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 116.329 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F128_0 9.963 Tf
-(Miscellanea) 48.1412 Tj
-[1 0 0 1 266.071 749.146] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -7.094] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -31.517] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 710.037 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 710.037] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 710.037 Td
-/F128_0 9.963 Tf
-(Single) 25.4654 Tj
--202 TJm
-(ar) 7.74125 Tj
-1 TJm
-(ray) 12.7228 Tj
--202 TJm
-(implementation) 62.5477 Tj
--201 TJm
-(of) 8.29918 Tj
--202 TJm
-(the) 12.1748 Tj
--202 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(erse) 16.0404 Tj
--201 TJm
-(BWT) 22.1378 Tj
-74 TJm
-(.) 2.49075 Tj
--403 TJm
-(This) 17.7142 Tj
--202 TJm
-(signi\002cantly) 49.267 Tj
--201 TJm
-(speeds) 26.5614 Tj
--202 TJm
-(up) 9.963 Tj
--202 TJm
-(decom) 26.5614 Tj
-1 TJm
-(pression,) 35.6974 Tj
--212 TJm
-(presuma) 33.7546 Tj
-1 TJm
-(bly) 12.7327 Tj
--202 TJm
-(because) 31.5329 Tj
-86.944 698.082 Td
-(it) 5.53943 Tj
--250 TJm
-(reduces) 30.427 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(number) 30.437 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(cach) 18.2522 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(misses.) 29.0621 Tj
-[1 0 0 1 240.496 698.082] cm
-0 g
-0 G
-[1 0 0 1 -168.496 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 676.164 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 676.164] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 676.164 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(aster) 18.8101 Tj
--314 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(erse) 16.0404 Tj
--315 TJm
-(MTF) 20.4839 Tj
--314 TJm
-(transform) 38.7361 Tj
--314 TJm
-(for) 11.6169 Tj
--315 TJm
-(lar) 10.511 Tj
-18 TJm
-(ge) 9.40507 Tj
--314 TJm
-(MTF) 20.4839 Tj
--314 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues.) 22.9647 Tj
--504 TJm
-(The) 15.4925 Tj
--314 TJm
-(ne) 9.40507 Tj
-25 TJm
-(w) 7.19329 Tj
--315 TJm
-(i) 2.76971 Tj
-1 TJm
-(mplementation) 59.778 Tj
--315 TJm
-(is) 6.64532 Tj
--314 TJm
-(based) 22.6858 Tj
--314 TJm
-(on) 9.963 Tj
--315 TJm
-(the) 12.1748 Tj
--314 TJm
-(notion) 25.4654 Tj
--315 TJm
-(of) 8.29918 Tj
--314 TJm
-(sliding) 27.1292 Tj
-86.944 664.209 Td
-(blocks) 26.0134 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(v) 4.9815 Tj
-25 TJm
-(alues.) 22.9647 Tj
-[1 0 0 1 153.932 664.209] cm
-0 g
-0 G
-[1 0 0 1 -81.932 -21.918] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 642.291 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 642.291] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -86.944 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 642.291 Td
-/F130_0 9.963 Tf
-(bzip2-0.9.0) 65.7558 Tj
-[1 0 0 1 152.697 642.291] cm
-0 g
-0 G
-[1 0 0 1 -152.697 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.412 642.291 Td
-/F128_0 9.963 Tf
-(no) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--272 TJm
-(reads) 21.0219 Tj
--273 TJm
-(and) 14.3866 Tj
--272 TJm
-(writes) 24.3496 Tj
--272 TJm
-(\002les) 16.6083 Tj
--273 TJm
-(with) 17.7142 Tj
-[1 0 0 1 282.68 642.291] cm
-0 g
-0 G
-[1 0 0 1 -282.68 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.68 642.291 Td
-/F130_0 9.963 Tf
-(fread) 29.889 Tj
-[1 0 0 1 312.568 642.291] cm
-0 g
-0 G
-[1 0 0 1 -312.568 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.282 642.291 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 332.383 642.291] cm
-0 g
-0 G
-[1 0 0 1 -332.383 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.383 642.291 Td
-/F130_0 9.963 Tf
-(fwrite) 35.8668 Tj
-[1 0 0 1 368.248 642.291] cm
-0 g
-0 G
-[1 0 0 1 -368.248 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-368.248 642.291 Td
-/F128_0 9.963 Tf
-(;) 2.76971 Tj
--284 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersion) 24.3496 Tj
--272 TJm
-(0.1) 12.4538 Tj
--272 TJm
-(used) 18.2622 Tj
-[1 0 0 1 441.882 642.291] cm
-0 g
-0 G
-[1 0 0 1 -441.882 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.882 642.291 Td
-/F130_0 9.963 Tf
-(putc) 23.9112 Tj
-[1 0 0 1 465.792 642.291] cm
-0 g
-0 G
-[1 0 0 1 -465.792 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.507 642.291 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 485.607 642.291] cm
-0 g
-0 G
-[1 0 0 1 -485.607 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-485.607 642.291 Td
-/F130_0 9.963 Tf
-(getc) 23.9112 Tj
-[1 0 0 1 509.517 642.291] cm
-0 g
-0 G
-[1 0 0 1 -509.517 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-509.517 642.291 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--755 TJm
-(Duh!) 20.474 Tj
-86.944 630.336 Td
-(W) 9.40507 Tj
-80 TJm
-(ell,) 12.4538 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(li) 5.53943 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(learn.) 22.4068 Tj
-[1 0 0 1 184.248 630.336] cm
-0 g
-0 G
-[1 0 0 1 -112.248 -12.119] cm
-0 g
-0 G
-[1 0 0 1 -72 -618.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 608.418 Td
-/F128_0 9.963 Tf
-(Further) 29.3311 Tj
--304 TJm
-(ahead,) 25.7245 Tj
--318 TJm
-(it) 5.53943 Tj
--305 TJm
-(w) 7.19329 Tj
-10 TJm
-(ould) 17.7142 Tj
--304 TJm
-(be) 9.40507 Tj
--304 TJm
-(nice) 16.5984 Tj
--305 TJm
-(to) 7.75121 Tj
--304 TJm
-(be) 9.40507 Tj
--304 TJm
-(able) 16.5984 Tj
--305 TJm
-(to) 7.75121 Tj
--304 TJm
-(do) 9.963 Tj
--305 TJm
-(random) 30.437 Tj
--304 TJm
-(access) 25.4455 Tj
--304 TJm
-(into) 15.5024 Tj
--305 TJm
-(\002l) 8.30914 Tj
-1 TJm
-(es.) 10.7899 Tj
--947 TJm
-(This) 17.7142 Tj
--304 TJm
-(will) 15.5024 Tj
--305 TJm
-(require) 28.2152 Tj
--304 TJm
-(some) 21.0319 Tj
--304 TJm
-(careful) 27.6573 Tj
--305 TJm
-(design) 26.0134 Tj
--304 TJm
-(of) 8.29918 Tj
-72 596.463 Td
-(compressed) 47.0353 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(formats.) 32.9277 Tj
-[1 0 0 1 72 594.306] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -584.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 561.71 Td
-/F121_0 20.659 Tf
-(4.2.) 34.4592 Tj
--278 TJm
-(P) 13.7796 Tj
-40 TJm
-(or) 20.659 Tj
--20 TJm
-(tability) 66.584 Tj
--278 TJm
-(issues) 64.3115 Tj
-[1 0 0 1 72 557.434] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -547.472] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 539.793 Td
-/F128_0 9.963 Tf
-(After) 21.0219 Tj
--250 TJm
-(some) 21.0319 Tj
--250 TJm
-(consideration,) 56.1714 Tj
--250 TJm
-(I) 3.31768 Tj
--250 TJm
-(h) 4.9815 Tj
-1 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(decided) 30.9849 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(use) 13.2807 Tj
--250 TJm
-(GNU) 21.5799 Tj
-[1 0 0 1 303.231 539.793] cm
-0 g
-0 G
-[1 0 0 1 -303.231 -539.793] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-303.231 539.793 Td
-/F130_0 9.963 Tf
-(autoconf) 47.8224 Tj
-[1 0 0 1 351.052 539.793] cm
-0 g
-0 G
-[1 0 0 1 -351.052 -539.793] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.542 539.793 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--250 TJm
-(con\002gure) 37.6303 Tj
--250 TJm
-(0.9.5) 19.926 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(1.0.) 14.9445 Tj
-[1 0 0 1 72 537.636] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -527.673] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 517.875 Td
-/F130_0 9.963 Tf
-(autoconf) 47.8224 Tj
-[1 0 0 1 119.821 517.875] cm
-0 g
-0 G
-[1 0 0 1 -119.821 -517.875] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 517.875 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--502 TJm
-(admirable) 39.842 Tj
--452 TJm
-(and) 14.3866 Tj
--452 TJm
-(w) 7.19329 Tj
-10 TJm
-(onderful) 33.7546 Tj
--452 TJm
-(though) 27.6772 Tj
--451 TJm
-(it) 5.53943 Tj
--452 TJm
-(is,) 9.13607 Tj
--503 TJm
-(mainly) 27.6772 Tj
--451 TJm
-(assists) 25.4654 Tj
--452 TJm
-(with) 17.7142 Tj
--452 TJm
-(portability) 41.5158 Tj
--452 TJm
-(problems) 37.0823 Tj
--451 TJm
-(between) 33.1967 Tj
--452 TJm
-(Unix-lik) 33.7646 Tj
-10 TJm
-(e) 4.42357 Tj
-72 505.92 Td
-(platforms.) 40.6789 Tj
--1398 TJm
-(But) 14.3965 Tj
-[1 0 0 1 144.784 505.92] cm
-0 g
-0 G
-[1 0 0 1 -144.784 -505.92] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.784 505.92 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 174.672 505.92] cm
-0 g
-0 G
-[1 0 0 1 -174.672 -505.92] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-178.455 505.92 Td
-/F128_0 9.963 Tf
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--380 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-16 TJm
-(e) 4.42357 Tj
--380 TJm
-(much) 22.1378 Tj
--380 TJm
-(in) 7.75121 Tj
--379 TJm
-(the) 12.1748 Tj
--380 TJm
-(w) 7.19329 Tj
-10 TJm
-(ay) 9.40507 Tj
--380 TJm
-(of) 8.29918 Tj
--379 TJm
-(portability) 41.5158 Tj
--380 TJm
-(problems) 37.0823 Tj
--379 TJm
-(on) 9.963 Tj
--380 TJm
-(Unix;) 22.6957 Tj
--444 TJm
-(most) 19.378 Tj
--380 TJm
-(of) 8.29918 Tj
--379 TJm
-(the) 12.1748 Tj
--380 TJm
-(dif) 11.0689 Tj
-25 TJm
-(\002culties) 31.5528 Tj
-72 493.964 Td
-(appear) 26.5514 Tj
--297 TJm
-(when) 21.5799 Tj
--296 TJm
-(porting) 28.7831 Tj
--297 TJm
-(to) 7.75121 Tj
--297 TJm
-(the) 12.1748 Tj
--296 TJm
-(Mac,) 20.195 Tj
--309 TJm
-(or) 8.29918 Tj
--296 TJm
-(to) 7.75121 Tj
--297 TJm
-(Microsoft') 42.6118 Tj
-55 TJm
-(s) 3.87561 Tj
--297 TJm
-(oper) 17.7043 Tj
-1 TJm
-(ating) 19.926 Tj
--297 TJm
-(systems.) 34.0436 Tj
-[1 0 0 1 361.339 493.964] cm
-0 g
-0 G
-[1 0 0 1 -361.339 -493.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-361.339 493.964 Td
-/F130_0 9.963 Tf
-(autoconf) 47.8224 Tj
-[1 0 0 1 409.16 493.964] cm
-0 g
-0 G
-[1 0 0 1 -409.16 -493.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-412.116 493.964 Td
-/F128_0 9.963 Tf
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--297 TJm
-(help) 17.1563 Tj
--296 TJm
-(in) 7.75121 Tj
--297 TJm
-(those) 21.0319 Tj
--297 TJm
-(cases,) 23.5127 Tj
--308 TJm
-(and) 14.3866 Tj
-72 482.009 Td
-(brings) 24.9075 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(whole) 24.3496 Tj
--250 TJm
-(load) 17.1563 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(ne) 9.40507 Tj
-25 TJm
-(w) 7.19329 Tj
--250 TJm
-(c) 4.42357 Tj
-1 TJm
-(omple) 24.9075 Tj
-15 TJm
-(xity) 15.5024 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 479.852] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -469.89] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 460.091 Td
-/F128_0 9.963 Tf
-(Most) 20.4839 Tj
--392 TJm
-(people) 26.5614 Tj
--392 TJm
-(should) 26.5713 Tj
--392 TJm
-(be) 9.40507 Tj
--393 TJm
-(able) 16.5984 Tj
--392 TJm
-(to) 7.75121 Tj
--392 TJm
-(compile) 32.1008 Tj
--392 TJm
-(the) 12.1748 Tj
--392 TJm
-(library) 26.5614 Tj
--392 TJm
-(and) 14.3866 Tj
--393 TJm
-(prog) 18.2622 Tj
-1 TJm
-(ram) 15.4925 Tj
--393 TJm
-(under) 22.6858 Tj
--392 TJm
-(Unix) 19.926 Tj
--392 TJm
-(straight) 29.889 Tj
--392 TJm
-(out-of-the-box,) 60.595 Tj
--428 TJm
-(so) 8.85711 Tj
--392 TJm
-(to) 7.75121 Tj
--392 TJm
-(speak,) 25.1765 Tj
-72 448.136 Td
-(especially) 39.842 Tj
--250 TJm
-(if) 6.08739 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersio) 19.3681 Tj
-1 TJm
-(n) 4.9815 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(GNU) 21.5799 Tj
--250 TJm
-(C) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailable.) 29.0521 Tj
-[1 0 0 1 72 445.979] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -436.017] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 426.218 Td
-/F128_0 9.963 Tf
-(There) 23.2337 Tj
--258 TJm
-(are) 12.1648 Tj
--259 TJm
-(a) 4.42357 Tj
--259 TJm
-(coupl) 22.1378 Tj
-1 TJm
-(e) 4.42357 Tj
--259 TJm
-(of) 8.29918 Tj
-[1 0 0 1 159.561 426.218] cm
-0 g
-0 G
-[1 0 0 1 -159.561 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.561 426.218 Td
-/F130_0 9.963 Tf
-(__inline__) 59.778 Tj
-[1 0 0 1 219.337 426.218] cm
-0 g
-0 G
-[1 0 0 1 -219.337 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.913 426.218 Td
-/F128_0 9.963 Tf
-(directi) 25.4555 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--258 TJm
-(in) 7.75121 Tj
--259 TJm
-(the) 12.1748 Tj
--258 TJm
-(code.) 21.3009 Tj
--672 TJm
-(GNU) 21.5799 Tj
--258 TJm
-(C) 6.64532 Tj
--259 TJm
-(\() 3.31768 Tj
-[1 0 0 1 352.587 426.218] cm
-0 g
-0 G
-[1 0 0 1 -352.587 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-352.587 426.218 Td
-/F130_0 9.963 Tf
-(gcc) 17.9334 Tj
-[1 0 0 1 370.52 426.218] cm
-0 g
-0 G
-[1 0 0 1 -370.52 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.52 426.218 Td
-/F128_0 9.963 Tf
-(\)) 3.31768 Tj
--259 TJm
-(sho) 13.8386 Tj
-1 TJm
-(uld) 12.7327 Tj
--259 TJm
-(be) 9.40507 Tj
--259 TJm
-(able) 16.5984 Tj
--258 TJm
-(to) 7.75121 Tj
--259 TJm
-(handle) 26.5614 Tj
--258 TJm
-(them.) 22.4168 Tj
--672 TJm
-(If) 6.63536 Tj
--258 TJm
-(you') 18.2622 Tj
-50 TJm
-(re) 7.74125 Tj
-72 414.263 Td
-(not) 12.7327 Tj
--279 TJm
-(using) 21.5898 Tj
--279 TJm
-(GNU) 21.5799 Tj
--279 TJm
-(C,) 9.13607 Tj
--279 TJm
-(your) 18.2622 Tj
--279 TJm
-(C) 6.64532 Tj
--279 TJm
-(compile) 32.1008 Tj
-1 TJm
-(r) 3.31768 Tj
--279 TJm
-(shouldn') 34.8705 Tj
-18 TJm
-(t) 2.76971 Tj
--279 TJm
-(see) 12.7228 Tj
--279 TJm
-(them) 19.926 Tj
--279 TJm
-(at) 7.19329 Tj
--279 TJm
-(all.) 12.4538 Tj
--794 TJm
-(If) 6.63536 Tj
--279 TJm
-(your) 18.2622 Tj
--279 TJm
-(compiler) 35.4185 Tj
--279 TJm
-(does,) 20.7529 Tj
--286 TJm
-(for) 11.6169 Tj
--279 TJm
-(some) 21.0319 Tj
--279 TJm
-(reason,) 28.4942 Tj
--286 TJm
-(see) 12.7228 Tj
--279 TJm
-(them) 19.926 Tj
--279 TJm
-(and) 14.3866 Tj
-72 402.308 Td
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--283 TJm
-(lik) 10.5209 Tj
-10 TJm
-(e) 4.42357 Tj
--283 TJm
-(them,) 22.4168 Tj
--291 TJm
-(just) 14.3965 Tj
-[1 0 0 1 164.167 402.308] cm
-0 g
-0 G
-[1 0 0 1 -164.167 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.167 402.308 Td
-/F130_0 9.963 Tf
-(#define) 41.8446 Tj
-[1 0 0 1 206.01 402.308] cm
-0 g
-0 G
-[1 0 0 1 2.819 0] cm
-0 g
-0 G
-[1 0 0 1 -208.829 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.829 402.308 Td
-/F130_0 9.963 Tf
-(__inline__) 59.778 Tj
-[1 0 0 1 268.605 402.308] cm
-0 g
-0 G
-[1 0 0 1 -268.605 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-271.425 402.308 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--283 TJm
-(be) 9.40507 Tj
-[1 0 0 1 294.22 402.308] cm
-0 g
-0 G
-[1 0 0 1 -294.22 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.22 402.308 Td
-/F130_0 9.963 Tf
-(/*) 11.9556 Tj
--600 TJm
-(*/) 11.9556 Tj
-[1 0 0 1 324.108 402.308] cm
-0 g
-0 G
-[1 0 0 1 -324.108 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-324.108 402.308 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--818 TJm
-(One) 16.5984 Tj
--283 TJm
-(easy) 17.7043 Tj
--283 TJm
-(w) 7.19329 Tj
-10 TJm
-(ay) 9.40507 Tj
--283 TJm
-(to) 7.75121 Tj
--283 TJm
-(do) 9.963 Tj
--283 TJm
-(this) 14.3965 Tj
--283 TJm
-(is) 6.64532 Tj
--283 TJm
-(to) 7.75121 Tj
--283 TJm
-(compile) 32.1008 Tj
--283 TJm
-(with) 17.7142 Tj
--283 TJm
-(th) 7.75121 Tj
-1 TJm
-(e) 4.42357 Tj
--283 TJm
-(\003ag) 14.9445 Tj
-[1 0 0 1 72 390.353] cm
-0 g
-0 G
-[1 0 0 1 -72 -390.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 390.353 Td
-/F130_0 9.963 Tf
-(-D__inline__=) 77.7114 Tj
-[1 0 0 1 149.709 390.353] cm
-0 g
-0 G
-[1 0 0 1 -149.709 -390.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-149.709 390.353 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--250 TJm
-(which) 24.3496 Tj
--250 TJm
-(should) 26.5713 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(understood) 44.2756 Tj
--249 TJm
-(by) 9.963 Tj
--250 TJm
-(most) 19.378 Tj
--250 TJm
-(Unix) 19.926 Tj
--250 TJm
-(compilers.) 41.7848 Tj
-[1 0 0 1 72 388.196] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -378.234] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 368.435 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--321 TJm
-(you) 14.9445 Tj
--321 TJm
-(still) 14.9545 Tj
--321 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--322 TJm
-(dif) 11.0689 Tj
-25 TJm
-(\002cul) 17.7142 Tj
-1 TJm
-(ties,) 16.3294 Tj
--339 TJm
-(try) 11.0689 Tj
--322 TJm
-(compi) 24.9075 Tj
-1 TJm
-(ling) 15.5024 Tj
--322 TJm
-(with) 17.7142 Tj
--321 TJm
-(the) 12.1748 Tj
--321 TJm
-(macro) 24.8975 Tj
-[1 0 0 1 310.295 368.435] cm
-0 g
-0 G
-[1 0 0 1 -310.295 -368.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.295 368.435 Td
-/F130_0 9.963 Tf
-(BZ_STRICT_ANSI) 83.6892 Tj
-[1 0 0 1 393.981 368.435] cm
-0 g
-0 G
-[1 0 0 1 -393.981 -368.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-397.18 368.435 Td
-/F128_0 9.963 Tf
-(de\002ned.) 31.8218 Tj
--524 TJm
-(This) 17.7142 Tj
--321 TJm
-(should) 26.5713 Tj
--321 TJm
-(enable) 26.0034 Tj
--321 TJm
-(you) 14.9445 Tj
--321 TJm
-(to) 7.75121 Tj
-72 356.48 Td
-(b) 4.9815 Tj
-20 TJm
-(uild) 15.5024 Tj
--321 TJm
-(the) 12.1748 Tj
--321 TJm
-(library) 26.5614 Tj
--321 TJm
-(in) 7.75121 Tj
--322 TJm
-(a) 4.42357 Tj
--321 TJm
-(strictly) 27.6772 Tj
--321 TJm
-(ANSI) 23.2437 Tj
--321 TJm
-(compliant) 39.852 Tj
--321 TJm
-(en) 9.40507 Tj
-40 TJm
-(vironment.) 43.4486 Tj
--1047 TJm
-(Building) 34.8805 Tj
--321 TJm
-(the) 12.1748 Tj
--321 TJm
-(program) 33.7546 Tj
--321 TJm
-(itself) 19.926 Tj
--321 TJm
-(lik) 10.5209 Tj
-10 TJm
-(e) 4.42357 Tj
--322 TJm
-(this) 14.3965 Tj
--321 TJm
-(is) 6.64532 Tj
--321 TJm
-(dangerous) 40.9479 Tj
--321 TJm
-(and) 14.3866 Tj
-72 344.525 Td
-(not) 12.7327 Tj
--260 TJm
-(supported,) 41.7848 Tj
--263 TJm
-(since) 20.474 Tj
--260 TJm
-(you) 14.9445 Tj
--260 TJm
-(remo) 20.474 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-[1 0 0 1 204.498 344.525] cm
-0 g
-0 G
-[1 0 0 1 -204.498 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.498 344.525 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 234.385 344.525] cm
-0 g
-0 G
-[1 0 0 1 -234.385 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.385 344.525 Td
-/F128_0 9.963 Tf
-(') 3.31768 Tj
-55 TJm
-(s) 3.87561 Tj
--260 TJm
-(checks) 27.1093 Tj
--260 TJm
-(ag) 9.40507 Tj
-5 TJm
-(ainst) 18.8201 Tj
--260 TJm
-(compressing) 50.363 Tj
--260 TJm
-(directories,) 44.5446 Tj
--263 TJm
-(symbolic) 36.5343 Tj
--260 TJm
-(links,) 21.8688 Tj
--262 TJm
-(de) 9.40507 Tj
-25 TJm
-(vices,) 22.9647 Tj
--263 TJm
-(and) 14.3866 Tj
--260 TJm
-(other) 20.474 Tj
-72 332.57 Td
-(not-really-a-\002le) 62.5278 Tj
--250 TJm
-(entities.) 31.2739 Tj
--619 TJm
-(This) 17.7142 Tj
--250 TJm
-(could) 22.1378 Tj
--250 TJm
-(cause) 22.1278 Tj
--250 TJm
-(\002lesystem) 40.4099 Tj
--250 TJm
-(corruption!) 44.8235 Tj
-[1 0 0 1 72 330.413] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -320.45] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 310.652 Td
-/F128_0 9.963 Tf
-(One) 16.5984 Tj
--392 TJm
-(othe) 17.1563 Tj
-1 TJm
-(r) 3.31768 Tj
--392 TJm
-(thing:) 23.2536 Tj
--593 TJm
-(if) 6.08739 Tj
--392 TJm
-(you) 14.9445 Tj
--391 TJm
-(create) 23.7817 Tj
--392 TJm
-(a) 4.42357 Tj
-[1 0 0 1 210.879 310.652] cm
-0 g
-0 G
-[1 0 0 1 -210.879 -310.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.879 310.652 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 240.767 310.652] cm
-0 g
-0 G
-[1 0 0 1 -240.767 -310.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-244.669 310.652 Td
-/F128_0 9.963 Tf
-(binary) 25.4555 Tj
--392 TJm
-(fo) 8.29918 Tj
-1 TJm
-(r) 3.31768 Tj
--392 TJm
-(public) 24.9075 Tj
--392 TJm
-(distrib) 25.4654 Tj
-20 TJm
-(u) 4.9815 Tj
-1 TJm
-(tion,) 17.9932 Tj
--427 TJm
-(please) 24.8975 Tj
--392 TJm
-(consider) 33.7546 Tj
--391 TJm
-(linking) 28.2351 Tj
--392 TJm
-(it) 5.53943 Tj
--392 TJm
-(s) 3.87561 Tj
-1 TJm
-(tatically) 32.1008 Tj
--392 TJm
-(\() 3.31768 Tj
-[1 0 0 1 522.067 310.652] cm
-0 g
-0 G
-[1 0 0 1 -522.067 -310.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-522.067 310.652 Td
-/F130_0 9.963 Tf
-(gcc) 17.9334 Tj
-72 298.697 Td
-(-static) 41.8446 Tj
-[1 0 0 1 113.843 298.697] cm
-0 g
-0 G
-[1 0 0 1 -113.843 -298.697] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.843 298.697 Td
-/F128_0 9.963 Tf
-(\).) 5.80843 Tj
--620 TJm
-(This) 17.7142 Tj
--250 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-20 TJm
-(oids) 16.6083 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(sorts) 18.8201 Tj
--250 TJm
-(of) 8.29918 Tj
--250 TJm
-(lib) 10.5209 Tj
-1 TJm
-(rary-v) 24.3396 Tj
-15 TJm
-(ersion) 24.3496 Tj
--250 TJm
-(issues) 23.8016 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(others) 24.3496 Tj
--250 TJm
-(may) 17.1563 Tj
--250 TJm
-(encounter) 39.2841 Tj
--250 TJm
-(later) 17.7043 Tj
--250 TJm
-(on.) 12.4538 Tj
-[1 0 0 1 72 296.54] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -286.577] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 276.779 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--296 TJm
-(you) 14.9445 Tj
--296 TJm
-(b) 4.9815 Tj
-20 TJm
-(uild) 15.5024 Tj
-[1 0 0 1 122.708 276.779] cm
-0 g
-0 G
-[1 0 0 1 -122.708 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.708 276.779 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 152.596 276.779] cm
-0 g
-0 G
-[1 0 0 1 -152.596 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.545 276.779 Td
-/F128_0 9.963 Tf
-(on) 9.963 Tj
--296 TJm
-(W) 9.40507 Tj
-40 TJm
-(in32,) 20.205 Tj
--307 TJm
-(you) 14.9445 Tj
--296 TJm
-(must) 19.378 Tj
--296 TJm
-(set) 11.0689 Tj
-[1 0 0 1 254.965 276.779] cm
-0 g
-0 G
-[1 0 0 1 -254.965 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-254.965 276.779 Td
-/F130_0 9.963 Tf
-(BZ_UNIX) 41.8446 Tj
-[1 0 0 1 296.808 276.779] cm
-0 g
-0 G
-[1 0 0 1 -296.808 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.756 276.779 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--296 TJm
-(0) 4.9815 Tj
--296 TJm
-(and) 14.3866 Tj
-[1 0 0 1 335.72 276.779] cm
-0 g
-0 G
-[1 0 0 1 -335.72 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.72 276.779 Td
-/F130_0 9.963 Tf
-(BZ_LCCWIN32) 65.7558 Tj
-[1 0 0 1 401.473 276.779] cm
-0 g
-0 G
-[1 0 0 1 -401.473 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-404.422 276.779 Td
-/F128_0 9.963 Tf
-(to) 7.75121 Tj
--296 TJm
-(1,) 7.47225 Tj
--307 TJm
-(in) 7.75121 Tj
--296 TJm
-(the) 12.1748 Tj
--296 TJm
-(\002le) 12.7327 Tj
-[1 0 0 1 467.159 276.779] cm
-0 g
-0 G
-[1 0 0 1 -467.159 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-467.159 276.779 Td
-/F130_0 9.963 Tf
-(bzip2.c) 41.8446 Tj
-[1 0 0 1 509.002 276.779] cm
-0 g
-0 G
-[1 0 0 1 -509.002 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-509.002 276.779 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--307 TJm
-(before) 25.4455 Tj
-72 264.824 Td
-(compiling.) 42.9007 Tj
--310 TJm
-(Otherwise) 40.9479 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(re) 7.74125 Tj
-1 TJm
-(sulting) 27.1292 Tj
--250 TJm
-(binary) 25.4555 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(on') 13.2807 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork) 13.2807 Tj
--250 TJm
-(correctly) 35.4085 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 262.667] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -252.704] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 230.071 Td
-/F121_0 20.659 Tf
-(4.3.) 34.4592 Tj
--278 TJm
-(Repor) 59.6839 Tj
--20 TJm
-(ting) 37.8679 Tj
--278 TJm
-(b) 12.6226 Tj
-20 TJm
-(ugs) 36.7317 Tj
-[1 0 0 1 72 225.475] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -215.512] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 208.153 Td
-/F128_0 9.963 Tf
-(I) 3.31768 Tj
--228 TJm
-(tried) 18.2622 Tj
--228 TJm
-(pretty) 23.2437 Tj
--228 TJm
-(hard) 17.7043 Tj
--228 TJm
-(t) 2.76971 Tj
-1 TJm
-(o) 4.9815 Tj
--228 TJm
-(mak) 17.1563 Tj
-10 TJm
-(e) 4.42357 Tj
--228 TJm
-(sure) 16.5984 Tj
-[1 0 0 1 196.25 208.153] cm
-0 g
-0 G
-[1 0 0 1 -196.25 -208.153] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.25 208.153 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 226.138 208.153] cm
-0 g
-0 G
-[1 0 0 1 -226.138 -208.153] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-228.409 208.153 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--228 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--228 TJm
-(free,) 17.9733 Tj
--232 TJm
-(both) 17.7142 Tj
--228 TJm
-(by) 9.963 Tj
--228 TJm
-(design) 26.0134 Tj
--228 TJm
-(and) 14.3866 Tj
--228 TJm
-(by) 9.963 Tj
--228 TJm
-(te) 7.19329 Tj
-1 TJm
-(sting.) 21.8688 Tj
--606 TJm
-(Hopefully) 40.4 Tj
--227 TJm
-(you') 18.2622 Tj
-10 TJm
-(ll) 5.53943 Tj
--228 TJm
-(ne) 9.40507 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
--228 TJm
-(need) 18.8101 Tj
--228 TJm
-(to) 7.75121 Tj
--228 TJm
-(read) 17.1463 Tj
-72 196.198 Td
-(this) 14.3965 Tj
--250 TJm
-(section) 28.2252 Tj
--250 TJm
-(for) 11.6169 Tj
--250 TJm
-(real.) 17.4253 Tj
-[1 0 0 1 72 196.098] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -186.136] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 174.28 Td
-/F128_0 9.963 Tf
-(Ne) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ertheless,) 37.3513 Tj
--313 TJm
-(if) 6.08739 Tj
-[1 0 0 1 137.751 174.28] cm
-0 g
-0 G
-[1 0 0 1 -137.751 -174.28] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.751 174.28 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 167.639 174.28] cm
-0 g
-0 G
-[1 0 0 1 -167.639 -174.28] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.634 174.28 Td
-/F128_0 9.963 Tf
-(dies) 16.0504 Tj
--301 TJm
-(w) 7.19329 Tj
-1 TJm
-(ith) 10.5209 Tj
--301 TJm
-(a) 4.42357 Tj
--301 TJm
-(se) 8.29918 Tj
-15 TJm
-(gm) 12.7327 Tj
-1 TJm
-(entation) 32.1008 Tj
--301 TJm
-(f) 3.31768 Tj
-10 TJm
-(ault,) 17.4353 Tj
--313 TJm
-(a) 4.42357 Tj
--301 TJm
-(b) 4.9815 Tj
-20 TJm
-(us) 8.85711 Tj
--300 TJm
-(error) 19.3581 Tj
--301 TJm
-(or) 8.29918 Tj
--300 TJm
-(an) 9.40507 Tj
--301 TJm
-(internal) 30.437 Tj
--300 TJm
-(assertion) 35.4185 Tj
--301 TJm
-(f) 3.31768 Tj
-10 TJm
-(ailure,) 25.1765 Tj
--313 TJm
-(it) 5.53943 Tj
--300 TJm
-(will) 15.5024 Tj
--301 TJm
-(ask) 13.2807 Tj
--300 TJm
-(you) 14.9445 Tj
--301 TJm
-(to) 7.75121 Tj
-72 162.325 Td
-(email) 22.1378 Tj
--242 TJm
-(me) 12.1748 Tj
--243 TJm
-(a) 4.42357 Tj
--242 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--243 TJm
-(r) 3.31768 Tj
-1 TJm
-(eport.) 22.9647 Tj
--615 TJm
-(Experience) 44.8136 Tj
--243 TJm
-(from) 19.3681 Tj
--242 TJm
-(years) 21.0219 Tj
--242 TJm
-(of) 8.29918 Tj
--243 TJm
-(feedback) 35.9565 Tj
--242 TJm
-(of) 8.29918 Tj
--242 TJm
-(bzip2) 22.1378 Tj
--243 TJm
-(users) 20.474 Tj
--242 TJm
-(indicates) 35.4185 Tj
--242 TJm
-(that) 14.9445 Tj
--243 TJm
-(almost) 26.5713 Tj
--242 TJm
-(all) 9.963 Tj
--242 TJm
-(these) 20.474 Tj
--243 TJm
-(problems) 37.0823 Tj
--242 TJm
-(can) 13.8286 Tj
-72 150.37 Td
-(be) 9.40507 Tj
--250 TJm
-(traced) 24.3396 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(either) 22.6858 Tj
--250 TJm
-(compiler) 35.4185 Tj
--249 TJm
-(b) 4.9815 Tj
-20 TJm
-(ugs) 13.8386 Tj
--250 TJm
-(or) 8.29918 Tj
--250 TJm
-(hardw) 24.8975 Tj
-10 TJm
-(are) 12.1648 Tj
--250 TJm
-(problems.) 39.573 Tj
-[1 0 0 1 72 148.213] cm
-0 g
-0 G
-[1 0 0 1 0 -97.361] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(32) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 36 36
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -6.854] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 116.329 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F128_0 9.963 Tf
-(Miscellanea) 48.1412 Tj
-[1 0 0 1 266.071 749.146] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -7.094] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -468 -31.517] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 710.037 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 710.037] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 710.037 Td
-/F128_0 9.963 Tf
-(Recompile) 43.1697 Tj
--306 TJm
-(the) 12.1748 Tj
--306 TJm
-(program) 33.7546 Tj
--306 TJm
-(with) 17.7142 Tj
--305 TJm
-(no) 9.963 Tj
--306 TJm
-(optimisation,) 52.3157 Tj
--320 TJm
-(and) 14.3866 Tj
--306 TJm
-(see) 12.7228 Tj
--306 TJm
-(if) 6.08739 Tj
--306 TJm
-(it) 5.53943 Tj
--306 TJm
-(w) 7.19329 Tj
-10 TJm
-(orks.) 19.647 Tj
--956 TJm
-(And/or) 28.2252 Tj
--306 TJm
-(try) 11.0689 Tj
--306 TJm
-(a) 4.42357 Tj
--306 TJm
-(dif) 11.0689 Tj
-25 TJm
-(fe) 7.74125 Tj
-1 TJm
-(rent) 15.4925 Tj
--306 TJm
-(compiler) 35.4185 Tj
-55 TJm
-(.) 2.49075 Tj
--956 TJm
-(I) 3.31768 Tj
--306 TJm
-(heard) 22.1278 Tj
--306 TJm
-(all) 9.963 Tj
-86.944 698.082 Td
-(sorts) 18.8201 Tj
--282 TJm
-(of) 8.29918 Tj
--282 TJm
-(stories) 26.0134 Tj
--282 TJm
-(about) 22.1378 Tj
--282 TJm
-(v) 4.9815 Tj
-25 TJm
-(arious) 24.3496 Tj
--282 TJm
-(\003a) 9.963 Tj
-20 TJm
-(v) 4.9815 Tj
-20 TJm
-(ours) 17.1563 Tj
--282 TJm
-(of) 8.29918 Tj
--282 TJm
-(GNU) 21.5799 Tj
--282 TJm
-(C) 6.64532 Tj
--283 TJm
-(\(a) 7.74125 Tj
-1 TJm
-(nd) 9.963 Tj
--283 TJm
-(other) 20.474 Tj
--282 TJm
-(compiler) 35.4185 Tj
-1 TJm
-(s\)) 7.19329 Tj
--283 TJm
-(genera) 26.5514 Tj
-1 TJm
-(ting) 15.5024 Tj
--283 TJm
-(bad) 14.3866 Tj
--282 TJm
-(code) 18.8101 Tj
--282 TJm
-(for) 11.6169 Tj
-[1 0 0 1 472.141 698.082] cm
-0 g
-0 G
-[1 0 0 1 -472.141 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-472.141 698.082 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 502.029 698.082] cm
-0 g
-0 G
-[1 0 0 1 -502.029 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-502.029 698.082 Td
-/F128_0 9.963 Tf
-(,) 2.49075 Tj
--290 TJm
-(and) 14.3866 Tj
--282 TJm
-(I') 6.63536 Tj
-50 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-86.944 686.127 Td
-(run) 13.2807 Tj
--250 TJm
-(across) 24.8975 Tj
--250 TJm
-(tw) 9.963 Tj
-10 TJm
-(o) 4.9815 Tj
--250 TJm
-(such) 18.2622 Tj
--250 TJm
-(e) 4.42357 Tj
-15 TJm
-(xamples) 33.2067 Tj
--249 TJm
-(myself.) 29.61 Tj
-[1 0 0 1 237.767 686.127] cm
-0 g
-0 G
-[1 0 0 1 -165.767 -12.119] cm
-0 g
-0 G
-[1 0 0 1 -72 -674.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 664.209 Td
-/F128_0 9.963 Tf
-(2.7.X) 22.1378 Tj
--279 TJm
-(v) 4.9815 Tj
-15 TJm
-(ersions) 28.2252 Tj
--280 TJm
-(of) 8.29918 Tj
--279 TJm
-(GNU) 21.5799 Tj
--280 TJm
-(C) 6.64532 Tj
--279 TJm
-(are) 12.1648 Tj
--280 TJm
-(kno) 14.9445 Tj
-25 TJm
-(wn) 12.1748 Tj
--279 TJm
-(to) 7.75121 Tj
--280 TJm
-(generate) 33.7447 Tj
--279 TJm
-(bad) 14.3866 Tj
--280 TJm
-(code) 18.8101 Tj
--279 TJm
-(from) 19.3681 Tj
--280 TJm
-(time) 17.7142 Tj
--279 TJm
-(to) 7.75121 Tj
--280 TJm
-(time,) 20.205 Tj
--287 TJm
-(at) 7.19329 Tj
--279 TJm
-(high) 17.7142 Tj
--280 TJm
-(optimisation) 49.825 Tj
--279 TJm
-(le) 7.19329 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(els.) 13.5596 Tj
--797 TJm
-(If) 6.63536 Tj
--280 TJm
-(you) 14.9445 Tj
-86.944 652.254 Td
-(get) 12.1748 Tj
--295 TJm
-(problems,) 39.573 Tj
--307 TJm
-(try) 11.0689 Tj
--296 TJm
-(u) 4.9815 Tj
-1 TJm
-(sing) 16.6083 Tj
--296 TJm
-(the) 12.1748 Tj
--295 TJm
-(\003ags) 18.8201 Tj
-[1 0 0 1 220.116 652.254] cm
-0 g
-0 G
-[1 0 0 1 -220.116 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.116 652.254 Td
-/F130_0 9.963 Tf
-(-O2) 17.9334 Tj
-[1 0 0 1 238.049 652.254] cm
-0 g
-0 G
-[1 0 0 1 2.944 0] cm
-0 g
-0 G
-[1 0 0 1 -240.993 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-240.993 652.254 Td
-/F130_0 9.963 Tf
-(-fomit-frame-pointer) 119.556 Tj
-[1 0 0 1 360.544 652.254] cm
-0 g
-0 G
-[1 0 0 1 2.944 0] cm
-0 g
-0 G
-[1 0 0 1 -363.488 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.488 652.254 Td
-/F130_0 9.963 Tf
-(-fno-strength-reduce) 119.556 Tj
-[1 0 0 1 483.04 652.254] cm
-0 g
-0 G
-[1 0 0 1 -483.04 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-483.04 652.254 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--893 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--295 TJm
-(should) 26.5713 Tj
-86.944 640.299 Td
-(speci\002cally) 45.3815 Tj
-[1 0 0 1 134.814 640.299] cm
-0 g
-0 G
-[1 0 0 1 -134.814 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.814 640.299 Td
-/F631_0 9.963 Tf
-(not) 12.7327 Tj
-[1 0 0 1 147.546 640.299] cm
-0 g
-0 G
-[1 0 0 1 -147.546 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.037 640.299 Td
-/F128_0 9.963 Tf
-(use) 13.2807 Tj
-[1 0 0 1 165.807 640.299] cm
-0 g
-0 G
-[1 0 0 1 -165.807 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.807 640.299 Td
-/F130_0 9.963 Tf
-(-funroll-loops) 83.6892 Tj
-[1 0 0 1 249.493 640.299] cm
-0 g
-0 G
-[1 0 0 1 -249.493 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-249.493 640.299 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
-[1 0 0 1 72 638.142] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -628.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 618.381 Td
-/F128_0 9.963 Tf
-(Y) 7.19329 Tj
-110 TJm
-(ou) 9.963 Tj
--249 TJm
-(may) 17.1563 Tj
--248 TJm
-(notice) 24.3496 Tj
--249 TJm
-(that) 14.9445 Tj
--249 TJm
-(the) 12.1748 Tj
--249 TJm
-(M) 8.85711 Tj
-1 TJm
-(ak) 9.40507 Tj
-10 TJm
-(e\002le) 17.1563 Tj
--249 TJm
-(runs) 17.1563 Tj
--249 TJm
-(six) 11.6268 Tj
--249 TJm
-(test) 13.8386 Tj
-1 TJm
-(s) 3.87561 Tj
--249 TJm
-(as) 8.29918 Tj
--249 TJm
-(part) 15.4925 Tj
--249 TJm
-(of) 8.29918 Tj
--248 TJm
-(the) 12.1748 Tj
--249 TJm
-(b) 4.9815 Tj
-20 TJm
-(uild) 15.5024 Tj
--249 TJm
-(process.) 32.3698 Tj
--619 TJm
-(If) 6.63536 Tj
--249 TJm
-(the) 12.1748 Tj
--248 TJm
-(program) 33.7546 Tj
--249 TJm
-(passes) 25.4555 Tj
--249 TJm
-(all) 9.963 Tj
--248 TJm
-(of) 8.29918 Tj
--249 TJm
-(these,) 22.9647 Tj
--249 TJm
-(it') 8.85711 Tj
-55 TJm
-(s) 3.87561 Tj
-86.944 606.426 Td
-(a) 4.42357 Tj
--250 TJm
-(pretty) 23.2437 Tj
--250 TJm
-(good) 19.926 Tj
--250 TJm
-(\(b) 8.29918 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(not) 12.7327 Tj
--250 TJm
-(100%\)) 26.5614 Tj
--250 TJm
-(in) 7.75121 Tj
-1 TJm
-(dication) 32.1008 Tj
--250 TJm
-(that) 14.9445 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(compiler) 35.4185 Tj
--250 TJm
-(has) 13.2807 Tj
--250 TJm
-(done) 19.3681 Tj
--250 TJm
-(its) 9.41504 Tj
--250 TJm
-(job) 12.7327 Tj
--250 TJm
-(correctly) 35.4085 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 604.269] cm
-0 g
-0 G
-[1 0 0 1 0 -19.761] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 584.508 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 584.508] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 584.508 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
-[1 0 0 1 95.956 584.508] cm
-0 g
-0 G
-[1 0 0 1 -95.956 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.956 584.508 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 125.844 584.508] cm
-0 g
-0 G
-[1 0 0 1 -125.844 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.22 584.508 Td
-/F128_0 9.963 Tf
-(crashes) 29.3211 Tj
--238 TJm
-(randomly) 38.1882 Tj
-65 TJm
-(,) 2.49075 Tj
--241 TJm
-(and) 14.3866 Tj
--239 TJm
-(the) 12.1748 Tj
--238 TJm
-(crashes) 29.3211 Tj
--239 TJm
-(are) 12.1648 Tj
--238 TJm
-(not) 12.7327 Tj
--239 TJm
-(repea) 21.5699 Tj
-1 TJm
-(table,) 21.8588 Tj
--241 TJm
-(you) 14.9445 Tj
--239 TJm
-(may) 17.1563 Tj
--238 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--239 TJm
-(a) 4.42357 Tj
--238 TJm
-(\003ak) 14.9445 Tj
-15 TJm
-(y) 4.9815 Tj
--239 TJm
-(memory) 33.2067 Tj
--238 TJm
-(subsystem.) 44.0066 Tj
-[1 0 0 1 510.112 584.508] cm
-0 g
-0 G
-[1 0 0 1 -510.112 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 584.508 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 540 584.508] cm
-0 g
-0 G
-[1 0 0 1 -540 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 572.553 Td
-/F128_0 9.963 Tf
-(really) 22.6858 Tj
--253 TJm
-(hammers) 36.5244 Tj
--254 TJm
-(your) 18.2622 Tj
--253 TJm
-(memory) 33.2067 Tj
--254 TJm
-(hierarch) 32.6388 Tj
-5 TJm
-(y) 4.9815 Tj
-65 TJm
-(,) 2.49075 Tj
--254 TJm
-(and) 14.3866 Tj
--254 TJm
-(if) 6.08739 Tj
--253 TJm
-(it') 8.85711 Tj
-55 TJm
-(s) 3.87561 Tj
--254 TJm
-(a) 4.42357 Tj
--253 TJm
-(bit) 10.5209 Tj
--254 TJm
-(mar) 15.4925 Tj
-18 TJm
-(ginal,) 22.4168 Tj
--254 TJm
-(you) 14.9445 Tj
--254 TJm
-(may) 17.1563 Tj
--253 TJm
-(get) 12.1748 Tj
--254 TJm
-(these) 20.474 Tj
--253 TJm
-(problems.) 39.573 Tj
--642 TJm
-(D) 7.19329 Tj
-1 TJm
-(itto) 13.2906 Tj
--254 TJm
-(if) 6.08739 Tj
--254 TJm
-(you) 14.9445 Tj
-1 TJm
-(r) 3.31768 Tj
--254 TJm
-(disk) 16.6083 Tj
-86.944 560.598 Td
-(or) 8.29918 Tj
--250 TJm
-(I/O) 13.2807 Tj
--250 TJm
-(subsystem) 41.5158 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(slo) 11.6268 Tj
-25 TJm
-(wly) 14.9445 Tj
--249 TJm
-(f) 3.31768 Tj
-10 TJm
-(ailing.) 25.1865 Tj
--620 TJm
-(Y) 7.19329 Tj
-111 TJm
-(up,) 12.4538 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(really) 22.6858 Tj
--250 TJm
-(does) 18.2622 Tj
--250 TJm
-(happen.) 31.2639 Tj
-[1 0 0 1 345.143 560.598] cm
-0 g
-0 G
-[1 0 0 1 -273.143 -12.12] cm
-0 g
-0 G
-[1 0 0 1 -72 -548.478] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 538.68 Td
-/F128_0 9.963 Tf
-(T) 6.08739 Tj
-35 TJm
-(ry) 8.29918 Tj
--250 TJm
-(using) 21.5898 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(dif) 11.0689 Tj
-25 TJm
-(ferent) 23.2337 Tj
--250 TJm
-(machine) 33.7546 Tj
--249 TJm
-(of) 8.29918 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(same) 20.474 Tj
--250 TJm
-(type,) 19.647 Tj
--250 TJm
-(and) 14.3866 Tj
--250 TJm
-(see) 12.7228 Tj
--250 TJm
-(if) 6.08739 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(can) 13.8286 Tj
--250 TJm
-(repeat) 24.3396 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(problem.) 35.6974 Tj
-[1 0 0 1 72 536.523] cm
-0 g
-0 G
-[1 0 0 1 0 -19.761] cm
-0 g
-0 G
-[1 0 0 1 6.974 0] cm
-0 g
-0 G
-[1 0 0 1 -78.974 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.974 516.762 Td
-/F128_0 9.963 Tf
-(\225) 3.48705 Tj
-[1 0 0 1 82.461 516.762] cm
-0 g
-0 G
-[1 0 0 1 2.49 0] cm
-0 g
-0 G
-[1 0 0 1 1.993 0] cm
-0 g
-0 G
-[1 0 0 1 -86.944 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 516.762 Td
-/F128_0 9.963 Tf
-(This) 17.7142 Tj
--229 TJm
-(isn') 14.9445 Tj
-18 TJm
-(t) 2.76971 Tj
--230 TJm
-(real) 14.9345 Tj
-1 TJm
-(ly) 7.75121 Tj
--230 TJm
-(a) 4.42357 Tj
--229 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug,) 12.4538 Tj
--234 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--229 TJm
-(...) 7.47225 Tj
--303 TJm
-(If) 6.63536 Tj
-[1 0 0 1 212.232 516.762] cm
-0 g
-0 G
-[1 0 0 1 -212.232 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-212.232 516.762 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 242.12 516.762] cm
-0 g
-0 G
-[1 0 0 1 -242.12 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-244.405 516.762 Td
-/F128_0 9.963 Tf
-(tells) 16.6083 Tj
--229 TJm
-(you) 14.9445 Tj
--230 TJm
-(your) 18.2622 Tj
--229 TJm
-(\002le) 12.7327 Tj
--229 TJm
-(is) 6.64532 Tj
--229 TJm
-(corrupted) 38.1782 Tj
--230 TJm
-(on) 9.963 Tj
--229 TJm
-(decompression,) 62.2588 Tj
--233 TJm
-(and) 14.3866 Tj
--230 TJm
-(you) 14.9445 Tj
--229 TJm
-(obtained) 34.3126 Tj
--229 TJm
-(the) 12.1748 Tj
--229 TJm
-(\002le) 12.7327 Tj
-86.944 504.807 Td
-(via) 12.1748 Tj
--262 TJm
-(FTP) 17.1662 Tj
-111 TJm
-(,) 2.49075 Tj
--262 TJm
-(there) 19.916 Tj
--263 TJm
-(is) 6.64532 Tj
--262 TJm
-(a) 4.42357 Tj
--262 TJm
-(possibility) 41.5258 Tj
--262 TJm
-(that) 14.9445 Tj
--263 TJm
-(y) 4.9815 Tj
-1 TJm
-(ou) 9.963 Tj
--263 TJm
-(for) 11.6169 Tj
-18 TJm
-(got) 12.7327 Tj
--262 TJm
-(to) 7.75121 Tj
--262 TJm
-(tell) 12.7327 Tj
--262 TJm
-(FTP) 17.1662 Tj
--263 TJm
-(to) 7.75121 Tj
--262 TJm
-(do) 9.963 Tj
--262 TJm
-(a) 4.42357 Tj
--262 TJm
-(binary) 25.4555 Tj
--263 TJm
-(mode) 22.1378 Tj
--262 TJm
-(transfer) 30.427 Tj
-55 TJm
-(.) 2.49075 Tj
--694 TJm
-(Th) 11.0689 Tj
-1 TJm
-(at) 7.19329 Tj
--263 TJm
-(absolutely) 40.9579 Tj
--262 TJm
-(will) 15.5024 Tj
--262 TJm
-(cause) 22.1278 Tj
-86.944 492.852 Td
-(the) 12.1748 Tj
--250 TJm
-(\002le) 12.7327 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(be) 9.40507 Tj
--250 TJm
-(non-decompress) 65.2975 Tj
-1 TJm
-(ible.) 17.4353 Tj
--620 TJm
-(Y) 7.19329 Tj
-110 TJm
-(ou') 13.2807 Tj
-10 TJm
-(ll) 5.53943 Tj
--250 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(transfer) 30.427 Tj
--250 TJm
-(it) 5.53943 Tj
--250 TJm
-(ag) 9.40507 Tj
-5 TJm
-(ain.) 14.6655 Tj
-[1 0 0 1 351.34 492.852] cm
-0 g
-0 G
-[1 0 0 1 -279.34 -12.12] cm
-0 g
-0 G
-[1 0 0 1 -72 -480.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 470.934 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--235 TJm
-(you') 18.2622 Tj
-50 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--235 TJm
-(incorporated) 50.353 Tj
-[1 0 0 1 163.036 470.934] cm
-0 g
-0 G
-[1 0 0 1 -163.036 -470.934] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-163.036 470.934 Td
-/F130_0 9.963 Tf
-(libbzip2) 47.8224 Tj
-[1 0 0 1 210.856 470.934] cm
-0 g
-0 G
-[1 0 0 1 -210.856 -470.934] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.2 470.934 Td
-/F128_0 9.963 Tf
-(into) 15.5024 Tj
--235 TJm
-(your) 18.2622 Tj
--235 TJm
-(o) 4.9815 Tj
-25 TJm
-(wn) 12.1748 Tj
--236 TJm
-(prog) 18.2622 Tj
-1 TJm
-(ram) 15.4925 Tj
--236 TJm
-(and) 14.3866 Tj
--235 TJm
-(are) 12.1648 Tj
--235 TJm
-(getting) 27.6772 Tj
--235 TJm
-(problems,) 39.573 Tj
--238 TJm
-(please,) 27.3883 Tj
--238 TJm
-(please,) 27.3883 Tj
--238 TJm
-(please,) 27.3883 Tj
--238 TJm
-(check) 23.2337 Tj
--236 TJm
-(t) 2.76971 Tj
-1 TJm
-(hat) 12.1748 Tj
-72 458.979 Td
-(the) 12.1748 Tj
--242 TJm
-(parameters) 43.7077 Tj
--242 TJm
-(you) 14.9445 Tj
--243 TJm
-(are) 12.1648 Tj
--242 TJm
-(passing) 29.889 Tj
--242 TJm
-(in) 7.75121 Tj
--243 TJm
-(calls) 18.2622 Tj
--242 TJm
-(to) 7.75121 Tj
--242 TJm
-(the) 12.1748 Tj
--242 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--244 TJm
-(are) 12.1648 Tj
--243 TJm
-(co) 9.40507 Tj
-1 TJm
-(rrect,) 20.743 Tj
--244 TJm
-(and) 14.3866 Tj
--243 TJm
-(in) 7.75121 Tj
--242 TJm
-(accordance) 44.8036 Tj
--242 TJm
-(with) 17.7142 Tj
--242 TJm
-(what) 19.3681 Tj
--243 TJm
-(the) 12.1748 Tj
--242 TJm
-(documentation) 59.2201 Tj
--242 TJm
-(says) 17.1563 Tj
-72 447.024 Td
-(is) 6.64532 Tj
--250 TJm
-(allo) 14.9445 Tj
-25 TJm
-(w) 7.19329 Tj
-10 TJm
-(able.) 19.0891 Tj
--310 TJm
-(I) 3.31768 Tj
--250 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(tried) 18.2622 Tj
--250 TJm
-(to) 7.75121 Tj
--250 TJm
-(m) 7.75121 Tj
-1 TJm
-(ak) 9.40507 Tj
-10 TJm
-(e) 4.42357 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(library) 26.5614 Tj
--250 TJm
-(rob) 13.2807 Tj
-20 TJm
-(ust) 11.6268 Tj
--250 TJm
-(ag) 9.40507 Tj
-5 TJm
-(ainst) 18.8201 Tj
--250 TJm
-(such) 18.2622 Tj
--250 TJm
-(problems,) 39.573 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--250 TJm
-(I'm) 14.3866 Tj
--250 TJm
-(sur) 12.1748 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(I) 3.31768 Tj
--250 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(en') 12.7228 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(succeeded.) 43.4287 Tj
-[1 0 0 1 72 444.867] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -434.904] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 425.106 Td
-/F128_0 9.963 Tf
-(Finally) 28.2351 Tj
-65 TJm
-(,) 2.49075 Tj
--324 TJm
-(if) 6.08739 Tj
--309 TJm
-(the) 12.1748 Tj
--310 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--309 TJm
-(comments) 40.9579 Tj
--309 TJm
-(don') 18.2622 Tj
-18 TJm
-(t) 2.76971 Tj
--309 TJm
-(help,) 19.647 Tj
--325 TJm
-(you') 18.2622 Tj
-11 TJm
-(ll) 5.53943 Tj
--310 TJm
-(ha) 9.40507 Tj
-20 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--309 TJm
-(to) 7.75121 Tj
--309 TJm
-(send) 18.2622 Tj
--310 TJm
-(me) 12.1748 Tj
--309 TJm
-(a) 4.42357 Tj
--309 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--310 TJm
-(report.) 26.2824 Tj
--976 TJm
-(No) 12.1748 Tj
-25 TJm
-(w) 7.19329 Tj
-65 TJm
-(,) 2.49075 Tj
--324 TJm
-(it') 8.85711 Tj
-55 TJm
-(s) 3.87561 Tj
--309 TJm
-(just) 14.3965 Tj
--309 TJm
-(amazing) 33.7546 Tj
--310 TJm
-(ho) 9.963 Tj
-25 TJm
-(w) 7.19329 Tj
--309 TJm
-(man) 17.1563 Tj
-15 TJm
-(y) 4.9815 Tj
-72 413.151 Td
-(people) 26.5614 Tj
--250 TJm
-(will) 15.5024 Tj
--250 TJm
-(send) 18.2622 Tj
--250 TJm
-(me) 12.1748 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(b) 4.9815 Tj
-20 TJm
-(ug) 9.963 Tj
--250 TJm
-(rep) 12.7228 Tj
-1 TJm
-(ort) 11.0689 Tj
--250 TJm
-(saying) 26.0134 Tj
--250 TJm
-(something) 41.5158 Tj
--250 TJm
-(lik) 10.5209 Tj
-10 TJm
-(e:) 7.19329 Tj
-[1 0 0 1 72 410.994] cm
-0 g
-0 G
-[1 0 0 1 0 -24.907] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 23.91 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 20.324] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -401.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 401.629 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
--426 TJm
-(crashed) 41.8446 Tj
--426 TJm
-(with) 23.9112 Tj
--426 TJm
-(segmen) 35.8668 Tj
-1 TJm
-(tation) 35.8668 Tj
--426 TJm
-(fault) 29.889 Tj
--426 TJm
-(on) 11.9556 Tj
--426 TJm
-(my) 11.9556 Tj
--426 TJm
-(machine) 41.8446 Tj
-[1 0 0 1 72 386.087] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -376.125] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 364.169 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
--241 TJm
-(absolutely) 40.9579 Tj
--240 TJm
-(nothing) 30.4469 Tj
--241 TJm
-(else.) 17.9832 Tj
--614 TJm
-(Needless) 35.9664 Tj
--241 TJm
-(to) 7.75121 Tj
--240 TJm
-(say) 13.2807 Tj
-65 TJm
-(,) 2.49075 Tj
--243 TJm
-(a) 4.42357 Tj
--241 TJm
-(such) 18.2622 Tj
--241 TJm
-(a) 4.42357 Tj
--240 TJm
-(report) 23.7916 Tj
--241 TJm
-(is) 6.64532 Tj
-[1 0 0 1 324.681 364.169] cm
-0 g
-0 G
-[1 0 0 1 -324.681 -364.169] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-324.681 364.169 Td
-/F631_0 9.963 Tf
-(totally) 25.4654 Tj
-55 TJm
-(,) 2.49075 Tj
--243 TJm
-(u) 4.9815 Tj
-1 TJm
-(tterly) 21.0319 Tj
-55 TJm
-(,) 2.49075 Tj
--243 TJm
-(completely) 43.1597 Tj
--241 TJm
-(and) 14.9445 Tj
--240 TJm
-(compr) 25.4555 Tj
-37 TJm
-(ehensively) 41.4959 Tj
--241 TJm
-(100%) 23.2437 Tj
-72 352.214 Td
-(useless;) 31.5429 Tj
--257 TJm
-(a) 4.9815 Tj
--255 TJm
-(waste) 22.6957 Tj
--255 TJm
-(of) 7.75121 Tj
--255 TJm
-(your) 18.2622 Tj
--255 TJm
-(time) 17.1563 Tj
-10 TJm
-(,) 2.49075 Tj
--256 TJm
-(my) 11.6169 Tj
--255 TJm
-(t) 2.76971 Tj
-1 TJm
-(ime) 14.3866 Tj
-10 TJm
-(,) 2.49075 Tj
--257 TJm
-(and) 14.9445 Tj
--254 TJm
-(net) 12.1748 Tj
--255 TJm
-(bandwidth) 42.0737 Tj
-[1 0 0 1 302.574 352.214] cm
-0 g
-0 G
-[1 0 0 1 -302.574 -352.214] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.574 352.214 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--649 TJm
-(W) 9.40507 Tj
-40 TJm
-(ith) 10.5209 Tj
--255 TJm
-(no) 9.963 Tj
--255 TJm
-(details) 26.0134 Tj
--255 TJm
-(at) 7.19329 Tj
--255 TJm
-(all,) 12.4538 Tj
--256 TJm
-(there') 23.2337 Tj
-55 TJm
-(s) 3.87561 Tj
--255 TJm
-(no) 9.963 Tj
--255 TJm
-(w) 7.19329 Tj
-10 TJm
-(ay) 9.40507 Tj
--254 TJm
-(I) 3.31768 Tj
--255 TJm
-(can) 13.8286 Tj
--255 TJm
-(possibly) 33.2166 Tj
--255 TJm
-(be) 9.40507 Tj
-15 TJm
-(gin) 12.7327 Tj
-72 340.259 Td
-(to) 7.75121 Tj
--250 TJm
-(\002gure) 23.2437 Tj
--250 TJm
-(out) 12.7327 Tj
--250 TJm
-(what) 19.3681 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(problem) 33.2067 Tj
--249 TJm
-(is.) 9.13607 Tj
-[1 0 0 1 72 338.102] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -328.14] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 318.341 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--309 TJm
-(rules) 19.3681 Tj
--309 TJm
-(of) 8.29918 Tj
--309 TJm
-(the) 12.1748 Tj
--309 TJm
-(g) 4.9815 Tj
-5 TJm
-(ame) 16.5984 Tj
--309 TJm
-(are:) 14.9345 Tj
--429 TJm
-(f) 3.31768 Tj
-10 TJm
-(ac) 8.84714 Tj
-1 TJm
-(ts,) 9.13607 Tj
--324 TJm
-(f) 3.31768 Tj
-10 TJm
-(acts,) 17.9832 Tj
--324 TJm
-(f) 3.31768 Tj
-10 TJm
-(acts.) 17.9832 Tj
--975 TJm
-(Don') 20.474 Tj
-18 TJm
-(t) 2.76971 Tj
--309 TJm
-(omit) 18.2721 Tj
--309 TJm
-(them) 19.926 Tj
--309 TJm
-(because) 31.5329 Tj
--309 TJm
-("oh,) 16.5187 Tj
--324 TJm
-(the) 12.1748 Tj
-15 TJm
-(y) 4.9815 Tj
--309 TJm
-(w) 7.19329 Tj
-10 TJm
-(on') 13.2807 Tj
-18 TJm
-(t) 2.76971 Tj
--309 TJm
-(be) 9.40507 Tj
--309 TJm
-(rele) 14.9345 Tj
-25 TJm
-(v) 4.9815 Tj
-25 TJm
-(ant".) 18.7304 Tj
--975 TJm
-(At) 9.963 Tj
--309 TJm
-(the) 12.1748 Tj
--309 TJm
-(bare) 17.1463 Tj
-72 306.386 Td
-(minimum:) 41.5258 Tj
-[1 0 0 1 72 306.287] cm
-0 g
-0 G
-[1 0 0 1 0 -60.772] cm
-0.949 0.949 0.97646 rg
-0.949 0.949 0.97646 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 59.776 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 56.189] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -296.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 296.922 Td
-/F130_0 9.963 Tf
-(Machine) 41.8446 Tj
--426 TJm
-(type.) 29.889 Tj
--852 TJm
-(Operating) 53.8002 Tj
--425 TJm
-(system) 35.8668 Tj
--426 TJm
-(version.) 47.8224 Tj
-90 284.967 Td
-(Exact) 29.889 Tj
--426 TJm
-(version) 41.8446 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(bzip2) 29.889 Tj
--426 TJm
-(\() 5.9778 Tj
-1 TJm
-(do) 11.9556 Tj
--426 TJm
-(bzip2) 29.889 Tj
--426 TJm
-(-V\).) 23.9112 Tj
-90 273.011 Td
-(Exact) 29.889 Tj
--426 TJm
-(version) 41.8446 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(com) 17.9334 Tj
-1 TJm
-(piler) 29.889 Tj
--426 TJm
-(used.) 29.889 Tj
-90 261.056 Td
-(Flags) 29.889 Tj
--426 TJm
-(passed) 35.8668 Tj
--426 TJm
-(to) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(comp) 23.9112 Tj
-1 TJm
-(iler.) 29.889 Tj
-[1 0 0 1 72 245.514] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -235.552] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 223.597 Td
-/F128_0 9.963 Tf
-(Ho) 12.1748 Tj
-25 TJm
-(we) 11.6169 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(er) 7.74125 Tj
-40 TJm
-(,) 2.49075 Tj
--253 TJm
-(the) 12.1748 Tj
--253 TJm
-(most) 19.378 Tj
--253 TJm
-(important) 38.7461 Tj
--252 TJm
-(single) 23.8016 Tj
--253 TJm
-(thing) 20.4839 Tj
--253 TJm
-(that) 14.9445 Tj
--253 TJm
-(will) 15.5024 Tj
--252 TJm
-(help) 17.1563 Tj
--253 TJm
-(me) 12.1748 Tj
--253 TJm
-(is) 6.64532 Tj
--253 TJm
-(the) 12.1748 Tj
--252 TJm
-(\002le) 12.7327 Tj
--253 TJm
-(that) 14.9445 Tj
--253 TJm
-(you) 14.9445 Tj
--253 TJm
-(we) 11.6169 Tj
-1 TJm
-(re) 7.74125 Tj
--253 TJm
-(trying) 23.8016 Tj
--253 TJm
-(to) 7.75121 Tj
--253 TJm
-(compress) 37.6303 Tj
--252 TJm
-(or) 8.29918 Tj
--253 TJm
-(decompress) 47.0353 Tj
-72 211.642 Td
-(at) 7.19329 Tj
--304 TJm
-(the) 12.1748 Tj
--305 TJm
-(time) 17.7142 Tj
--304 TJm
-(the) 12.1748 Tj
--304 TJm
-(problem) 33.2067 Tj
--304 TJm
-(happened.) 40.669 Tj
--946 TJm
-(W) 9.40507 Tj
-40 TJm
-(ithout) 23.2536 Tj
--305 TJm
-(that,) 17.4353 Tj
--317 TJm
-(my) 12.7327 Tj
--305 TJm
-(ability) 25.4654 Tj
--304 TJm
-(to) 7.75121 Tj
--304 TJm
-(do) 9.963 Tj
--305 TJm
-(an) 9.40507 Tj
-15 TJm
-(ythin) 20.4839 Tj
-1 TJm
-(g) 4.9815 Tj
--305 TJm
-(more) 20.474 Tj
--304 TJm
-(than) 17.1563 Tj
--304 TJm
-(speculate) 37.0723 Tj
--305 TJm
-(abou) 19.3681 Tj
-1 TJm
-(t) 2.76971 Tj
--305 TJm
-(the) 12.1748 Tj
--304 TJm
-(cause,) 24.6186 Tj
--318 TJm
-(is) 6.64532 Tj
-72 199.686 Td
-(limited.) 30.7259 Tj
-[1 0 0 1 72 199.587] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -189.624] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 164.933 Td
-/F121_0 20.659 Tf
-(4.4.) 34.4592 Tj
--278 TJm
-(Did) 33.2816 Tj
--278 TJm
-(y) 11.4864 Tj
-25 TJm
-(ou) 25.2453 Tj
--278 TJm
-(g) 12.6226 Tj
--10 TJm
-(et) 18.3659 Tj
--278 TJm
-(the) 30.9885 Tj
--278 TJm
-(right) 45.9043 Tj
--278 TJm
-(pac) 35.5955 Tj
-20 TJm
-(ka) 22.9728 Tj
-11 TJm
-(g) 12.6226 Tj
--10 TJm
-(e?) 24.1091 Tj
-[1 0 0 1 72 160.337] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -150.374] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 143.016 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 143.016] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -143.016] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.603 143.016 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--272 TJm
-(a) 4.42357 Tj
--273 TJm
-(resource) 33.7447 Tj
--272 TJm
-(hog.) 17.4353 Tj
--378 TJm
-(It) 6.08739 Tj
--272 TJm
-(soaks) 22.1378 Tj
--272 TJm
-(up) 9.963 Tj
--273 TJm
-(lar) 10.511 Tj
-18 TJm
-(ge) 9.40507 Tj
--272 TJm
-(amounts) 33.7646 Tj
--273 TJm
-(of) 8.29918 Tj
--272 TJm
-(CPU) 19.378 Tj
--272 TJm
-(c) 4.42357 Tj
-15 TJm
-(ycles) 20.474 Tj
--273 TJm
-(and) 14.3866 Tj
--272 TJm
-(memory) 33.2067 Tj
-65 TJm
-(.) 2.49075 Tj
--755 TJm
-(Also,) 21.3109 Tj
--278 TJm
-(it) 5.53943 Tj
--272 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--273 TJm
-(v) 4.9815 Tj
-15 TJm
-(ery) 12.7228 Tj
--272 TJm
-(lar) 10.511 Tj
-18 TJm
-(ge) 9.40507 Tj
--273 TJm
-(latencies.) 37.3513 Tj
-72 131.061 Td
-(In) 8.29918 Tj
--251 TJm
-(the) 12.1748 Tj
--251 TJm
-(w) 7.19329 Tj
-10 TJm
-(orst) 14.9445 Tj
--251 TJm
-(case,) 19.6371 Tj
--251 TJm
-(you) 14.9445 Tj
--251 TJm
-(can) 13.8286 Tj
--251 TJm
-(feed) 17.1463 Tj
--251 TJm
-(man) 17.1563 Tj
-15 TJm
-(y) 4.9815 Tj
--251 TJm
-(me) 12.1748 Tj
-15 TJm
-(g) 4.9815 Tj
-5 TJm
-(abytes) 25.4555 Tj
--251 TJm
-(of) 8.29918 Tj
--251 TJm
-(uncompressed) 56.9983 Tj
--251 TJm
-(dat) 12.1748 Tj
-1 TJm
-(a) 4.42357 Tj
--251 TJm
-(into) 15.5024 Tj
--251 TJm
-(the) 12.1748 Tj
--251 TJm
-(library) 26.5614 Tj
--251 TJm
-(before) 25.4455 Tj
--251 TJm
-(getting) 27.6772 Tj
--251 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--251 TJm
-(compressed) 47.0353 Tj
-72 119.105 Td
-(output,) 27.9562 Tj
--250 TJm
-(so) 8.85711 Tj
--250 TJm
-(this) 14.3965 Tj
--250 TJm
-(probably) 35.4185 Tj
--250 TJm
-(rules) 19.3681 Tj
--249 TJm
-(out) 12.7327 Tj
--250 TJm
-(applications) 48.1512 Tj
--250 TJm
-(requiring) 36.5244 Tj
--250 TJm
-(interacti) 32.6488 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
--250 TJm
-(beha) 18.8101 Tj
-20 TJm
-(viour) 21.0319 Tj
-55 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 116.949] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 -72 -106.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 97.188 Td
-/F128_0 9.963 Tf
-(These) 23.7916 Tj
--304 TJm
-(aren') 20.464 Tj
-18 TJm
-(t) 2.76971 Tj
--304 TJm
-(f) 3.31768 Tj
-10 TJm
-(aults) 18.8201 Tj
--304 TJm
-(of) 8.29918 Tj
--304 TJm
-(my) 12.7327 Tj
--304 TJm
-(im) 10.5209 Tj
-1 TJm
-(plementation,) 54.5175 Tj
--318 TJm
-(I) 3.31768 Tj
--304 TJm
-(hope,) 21.8588 Tj
--317 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--304 TJm
-(more) 20.474 Tj
--304 TJm
-(an) 9.40507 Tj
--304 TJm
-(intrinsic) 32.6587 Tj
--304 TJm
-(property) 33.7546 Tj
--304 TJm
-(of) 8.29918 Tj
--303 TJm
-(the) 12.1748 Tj
--304 TJm
-(Burro) 23.2437 Tj
-25 TJm
-(ws-Wheeler) 48.1313 Tj
--304 TJm
-(transform) 38.7361 Tj
-72 85.232 Td
-(\(unfortunately\).) 62.8068 Tj
--620 TJm
-(Maybe) 27.6673 Tj
--250 TJm
-(this) 14.3965 Tj
--249 TJm
-(isn') 14.9445 Tj
-18 TJm
-(t) 2.76971 Tj
--250 TJm
-(what) 19.3681 Tj
--250 TJm
-(you) 14.9445 Tj
--250 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant.) 14.6655 Tj
-[1 0 0 1 72 83.076] cm
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-[1 0 0 1 0 -22.261] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(33) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 37 37
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -6.854] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 116.329 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F128_0 9.963 Tf
-(Miscellanea) 48.1412 Tj
-[1 0 0 1 266.071 749.146] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -7.094] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(If) 6.63536 Tj
--275 TJm
-(you) 14.9445 Tj
--274 TJm
-(w) 7.19329 Tj
-10 TJm
-(ant) 12.1748 Tj
--275 TJm
-(a) 4.42357 Tj
--274 TJm
-(compressor) 45.9294 Tj
--275 TJm
-(and/or) 25.4555 Tj
--274 TJm
-(library) 26.5614 Tj
--275 TJm
-(which) 24.3496 Tj
--274 TJm
-(is) 6.64532 Tj
--275 TJm
-(f) 3.31768 Tj
-10 TJm
-(aster) 18.8101 Tj
-40 TJm
-(,) 2.49075 Tj
--280 TJm
-(uses) 17.1563 Tj
--275 TJm
-(less) 14.9445 Tj
--274 TJm
-(memory) 33.2067 Tj
--275 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--274 TJm
-(gets) 16.0504 Tj
--275 TJm
-(pretty) 23.2437 Tj
--274 TJm
-(good) 19.926 Tj
--275 TJm
-(compression,) 52.8537 Tj
--280 TJm
-(and) 14.3866 Tj
--275 TJm
-(has) 13.2807 Tj
-72 698.082 Td
-(minimal) 33.2166 Tj
--288 TJm
-(latenc) 23.7916 Tj
-15 TJm
-(y) 4.9815 Tj
-65 TJm
-(,) 2.49075 Tj
--297 TJm
-(consider) 33.7546 Tj
--288 TJm
-(Jean-lou) 33.7546 Tj
-1 TJm
-(p) 4.9815 Tj
--288 TJm
-(Gailly') 28.2252 Tj
-55 TJm
-(s) 3.87561 Tj
--288 TJm
-(and) 14.3866 Tj
--288 TJm
-(Mark) 21.5799 Tj
--288 TJm
-(Adler') 26.0034 Tj
-55 TJm
-(s) 3.87561 Tj
--287 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork,) 15.7714 Tj
-[1 0 0 1 353.879 698.082] cm
-0 g
-0 G
-[1 0 0 1 -353.879 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.879 698.082 Td
-/F130_0 9.963 Tf
-(zlib-1.2.1) 59.778 Tj
-[1 0 0 1 413.655 698.082] cm
-0 g
-0 G
-[1 0 0 1 -413.655 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-416.523 698.082 Td
-/F128_0 9.963 Tf
-(and) 14.3866 Tj
-[1 0 0 1 433.777 698.082] cm
-0 g
-0 G
-[1 0 0 1 -433.777 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-433.777 698.082 Td
-/F130_0 9.963 Tf
-(gzip-1.2.4) 59.778 Tj
-[1 0 0 1 493.553 698.082] cm
-0 g
-0 G
-[1 0 0 1 -493.553 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.553 698.082 Td
-/F128_0 9.963 Tf
-(.) 2.49075 Tj
--847 TJm
-(Look) 21.0319 Tj
--288 TJm
-(for) 11.6169 Tj
-72 686.127 Td
-(them) 19.926 Tj
--250 TJm
-(at) 7.19329 Tj
--250 TJm
-(http://www) 45.3914 Tj
-65 TJm
-(.zlib) 17.4353 Tj
-40 TJm
-(.or) 10.7899 Tj
-18 TJm
-(g) 4.9815 Tj
--250 TJm
-(a) 4.42357 Tj
-1 TJm
-(nd) 9.963 Tj
--250 TJm
-(http://www) 45.3914 Tj
-65 TJm
-(.gzip.or) 30.437 Tj
-18 TJm
-(g) 4.9815 Tj
--250 TJm
-(respecti) 30.9849 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(ely) 12.1748 Tj
-65 TJm
-(.) 2.49075 Tj
-[1 0 0 1 72 683.97] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -674.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 664.209 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(or) 8.29918 Tj
--582 TJm
-(something) 41.5158 Tj
--582 TJm
-(f) 3.31768 Tj
-10 TJm
-(aster) 18.8101 Tj
--583 TJm
-(and) 14.3866 Tj
--582 TJm
-(lighter) 26.0134 Tj
--582 TJm
-(still,) 17.4452 Tj
--665 TJm
-(you) 14.9445 Tj
--583 TJm
-(m) 7.75121 Tj
-1 TJm
-(ight) 15.5024 Tj
--583 TJm
-(try) 11.0689 Tj
--582 TJm
-(Markus) 30.437 Tj
--582 TJm
-(F) 5.53943 Tj
--582 TJm
-(X) 7.19329 Tj
--582 TJm
-(J) 3.87561 Tj
--582 TJm
-(Oberhumer') 48.6892 Tj
-55 TJm
-(s) 3.87561 Tj
-[1 0 0 1 437.433 664.209] cm
-0 g
-0 G
-[1 0 0 1 -437.433 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-437.433 664.209 Td
-/F130_0 9.963 Tf
-(LZO) 17.9334 Tj
-[1 0 0 1 455.365 664.209] cm
-0 g
-0 G
-[1 0 0 1 -455.365 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-461.164 664.209 Td
-/F128_0 9.963 Tf
-(real-time) 35.9664 Tj
--582 TJm
-(compres-) 37.0723 Tj
-72 652.254 Td
-(sion/decompression) 79.1461 Tj
--250 TJm
-(library) 26.5614 Tj
-65 TJm
-(,) 2.49075 Tj
--250 TJm
-(a) 4.42357 Tj
-1 TJm
-(t) 2.76971 Tj
--250 TJm
-(http://www) 45.3914 Tj
-65 TJm
-(.oberhumer) 45.6505 Tj
-55 TJm
-(.com/opensource.) 70.279 Tj
-[1 0 0 1 72 650.097] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -640.135] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 617.501 Td
-/F121_0 20.659 Tf
-(4.5.) 34.4592 Tj
--278 TJm
-(Fur) 33.2816 Tj
--20 TJm
-(ther) 39.0249 Tj
--278 TJm
-(Reading) 81.4998 Tj
-[1 0 0 1 72 612.905] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 0 -9.963] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -72 -602.942] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 595.583 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 101.888 595.583] cm
-0 g
-0 G
-[1 0 0 1 -101.888 -595.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.923 595.583 Td
-/F128_0 9.963 Tf
-(is) 6.64532 Tj
--305 TJm
-(n) 4.9815 Tj
-1 TJm
-(ot) 7.75121 Tj
--305 TJm
-(research) 33.1868 Tj
--304 TJm
-(w) 7.19329 Tj
-10 TJm
-(ork,) 15.7714 Tj
--319 TJm
-(in) 7.75121 Tj
--304 TJm
-(the) 12.1748 Tj
--305 TJm
-(sense) 21.5799 Tj
--304 TJm
-(that) 14.9445 Tj
--305 TJm
-(it) 5.53943 Tj
--304 TJm
-(doesn') 26.5614 Tj
-18 TJm
-(t) 2.76971 Tj
--305 TJm
-(present) 28.7731 Tj
--304 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--305 TJm
-(ne) 9.40507 Tj
-25 TJm
-(w) 7.19329 Tj
--304 TJm
-(ideas.) 22.9647 Tj
--474 TJm
-(Rather) 26.5614 Tj
-40 TJm
-(,) 2.49075 Tj
--318 TJm
-(it') 8.85711 Tj
-55 TJm
-(s) 3.87561 Tj
--305 TJm
-(an) 9.40507 Tj
--304 TJm
-(engineering) 47.0353 Tj
--305 TJm
-(e) 4.42357 Tj
-15 TJm
-(x) 4.9815 Tj
-15 TJm
-(e) 4.42357 Tj
-1 TJm
-(rcise) 18.8101 Tj
-72 583.628 Td
-(based) 22.6858 Tj
--250 TJm
-(on) 9.963 Tj
--250 TJm
-(e) 4.42357 Tj
-15 TJm
-(xisting) 27.1292 Tj
--250 TJm
-(ideas.) 22.9647 Tj
-[1 0 0 1 72 581.471] cm
-0 g
-0 G
-[1 0 0 1 0 -9.962] cm
-0 g
-0 G
-[1 0 0 1 -72 -571.509] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 561.71 Td
-/F128_0 9.963 Tf
-(F) 5.53943 Tj
-15 TJm
-(our) 13.2807 Tj
--250 TJm
-(documents) 43.1697 Tj
--250 TJm
-(describe) 33.1967 Tj
--250 TJm
-(esse) 16.5984 Tj
-1 TJm
-(ntially) 25.4654 Tj
--250 TJm
-(all) 9.963 Tj
--250 TJm
-(the) 12.1748 Tj
--250 TJm
-(ideas) 20.474 Tj
--250 TJm
-(behind) 27.1193 Tj
-[1 0 0 1 298.747 561.71] cm
-0 g
-0 G
-[1 0 0 1 -298.747 -561.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-298.747 561.71 Td
-/F130_0 9.963 Tf
-(bzip2) 29.889 Tj
-[1 0 0 1 328.635 561.71] cm
-0 g
-0 G
-[1 0 0 1 -328.635 -561.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-328.635 561.71 Td
-/F128_0 9.963 Tf
-(:) 2.76971 Tj
-[1 0 0 1 72 559.554] cm
-0 g
-0 G
-[1 0 0 1 0 -299.876] cm
-0.9294 0.96861 0.95685 rg
-0.9294 0.96861 0.95685 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 298.879 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 295.292] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -550.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 550.189 Td
-/F130_0 9.963 Tf
-(Michael) 41.8446 Tj
--426 TJm
-(Burrows) 41.8446 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(D.) 11.9556 Tj
--426 TJm
-(J) 5.9778 Tj
-1 TJm
-(.) 5.9778 Tj
--426 TJm
-(Wheeler:) 47.8224 Tj
-98.488 538.234 Td
-("A) 11.9556 Tj
--426 TJm
-(block-sorting) 77.7114 Tj
--426 TJm
-(lossless) 47.8224 Tj
--425 TJm
-(data) 23.9112 Tj
--426 TJm
-(compression) 65.7558 Tj
--426 TJm
-(algorithm") 59.778 Tj
-102.732 526.278 Td
-(10th) 23.9112 Tj
--426 TJm
-(May) 17.9334 Tj
--426 TJm
-(1994.) 29.889 Tj
-102.732 514.323 Td
-(Digital) 41.8446 Tj
--426 TJm
-(SRC) 17.9334 Tj
--426 TJm
-(Research) 47.8224 Tj
--426 TJm
-(Rep) 17.9334 Tj
-1 TJm
-(ort) 17.9334 Tj
--426 TJm
-(124.) 23.9112 Tj
-102.732 502.368 Td
-(ftp://ftp.digital.com/pub) 149.445 Tj
-1 TJm
-(/DEC/SRC/research-reports/SRC-124.ps.gz) 233.134 Tj
-102.732 490.413 Td
-(If) 11.9556 Tj
--426 TJm
-(you) 17.9334 Tj
--426 TJm
-(have) 23.9112 Tj
--426 TJm
-(trouble) 41.8446 Tj
--426 TJm
-(find) 23.9112 Tj
-1 TJm
-(ing) 17.9334 Tj
--426 TJm
-(it,) 17.9334 Tj
--426 TJm
-(try) 17.9334 Tj
--426 TJm
-(searching) 53.8002 Tj
--426 TJm
-(at) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
-102.732 478.458 Td
-(New) 17.9334 Tj
--426 TJm
-(Zealand) 41.8446 Tj
--426 TJm
-(Digital) 41.8446 Tj
--426 TJm
-(Libr) 23.9112 Tj
-1 TJm
-(ary,) 23.9112 Tj
--426 TJm
-(http://www.nzdl.org.) 119.556 Tj
-90 454.547 Td
-(Daniel) 35.8668 Tj
--426 TJm
-(S.) 11.9556 Tj
--426 TJm
-(Hirschberg) 59.778 Tj
--426 TJm
-(and) 17.9334 Tj
--425 TJm
-(Debra) 29.889 Tj
--426 TJm
-(A.) 11.9556 Tj
--426 TJm
-(LeLewer) 41.8446 Tj
-98.488 442.592 Td
-("Efficient) 59.778 Tj
--426 TJm
-(Decoding) 47.8224 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(Pr) 11.9556 Tj
-1 TJm
-(efix) 23.9112 Tj
--426 TJm
-(Codes") 35.8668 Tj
-102.732 430.637 Td
-(Communications) 83.6892 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(ACM) 17.9334 Tj
-1 TJm
-(,) 5.9778 Tj
--426 TJm
-(April) 29.889 Tj
--426 TJm
-(1990,) 29.889 Tj
--426 TJm
-(Vol) 17.9334 Tj
--426 TJm
-(33,) 17.9334 Tj
--426 TJm
-(Number) 35.8668 Tj
--426 TJm
-(4.) 11.9556 Tj
-102.732 418.682 Td
-(You) 17.9334 Tj
--426 TJm
-(might) 29.889 Tj
--426 TJm
-(be) 11.9556 Tj
--426 TJm
-(able) 23.9112 Tj
--426 TJm
-(to) 11.9556 Tj
--426 TJm
-(get) 17.9334 Tj
--425 TJm
-(an) 11.9556 Tj
--426 TJm
-(electronic) 59.778 Tj
--426 TJm
-(copy) 23.9112 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(this) 23.9112 Tj
-102.732 406.727 Td
-(from) 23.9112 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(ACM) 17.9334 Tj
--426 TJm
-(Digital) 41.8446 Tj
--426 TJm
-(Lib) 17.9334 Tj
-1 TJm
-(rary.) 29.889 Tj
-90 382.816 Td
-(David) 29.889 Tj
--426 TJm
-(J.) 11.9556 Tj
--426 TJm
-(Wheeler) 41.8446 Tj
-102.732 370.861 Td
-(Program) 41.8446 Tj
--426 TJm
-(bred3.c) 41.8446 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(accom) 29.889 Tj
-1 TJm
-(panying) 41.8446 Tj
--426 TJm
-(document) 47.8224 Tj
--426 TJm
-(bred3.ps.) 53.8002 Tj
-102.732 358.906 Td
-(This) 23.9112 Tj
--426 TJm
-(contains) 47.8224 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(idea) 23.9112 Tj
--426 TJm
-(b) 5.9778 Tj
-1 TJm
-(ehind) 29.889 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(multi-table) 65.7558 Tj
--426 TJm
-(Huffman) 41.8446 Tj
--426 TJm
-(coding) 35.8668 Tj
--426 TJm
-(scheme.) 41.8446 Tj
-102.732 346.951 Td
-(ftp://ftp.cl.cam.ac.uk/us) 149.445 Tj
-1 TJm
-(ers/djw3/) 53.8002 Tj
-90 323.04 Td
-(Jon) 17.9334 Tj
--426 TJm
-(L.) 11.9556 Tj
--426 TJm
-(Bentley) 41.8446 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(Robert) 35.8668 Tj
--425 TJm
-(Sedgewick) 53.8002 Tj
-98.488 311.085 Td
-("Fast) 29.889 Tj
--426 TJm
-(Algorithms) 59.778 Tj
--426 TJm
-(for) 17.9334 Tj
--426 TJm
-(Sort) 23.9112 Tj
-1 TJm
-(ing) 17.9334 Tj
--426 TJm
-(and) 17.9334 Tj
--426 TJm
-(Searching) 53.8002 Tj
--426 TJm
-(Strings") 47.8224 Tj
-102.732 299.13 Td
-(Available) 53.8002 Tj
--426 TJm
-(from) 23.9112 Tj
--426 TJm
-(Sedgewick') 59.778 Tj
-1 TJm
-(s) 5.9778 Tj
--426 TJm
-(web) 17.9334 Tj
--426 TJm
-(page,) 29.889 Tj
-102.732 287.175 Td
-(www.cs.princeton.edu/~rs) 143.467 Tj
-[1 0 0 1 72 259.678] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -249.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 237.76 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--239 TJm
-(follo) 18.8201 Tj
-26 TJm
-(wing) 19.926 Tj
--239 TJm
-(paper) 22.1278 Tj
--239 TJm
-(gi) 7.75121 Tj
-25 TJm
-(v) 4.9815 Tj
-15 TJm
-(es) 8.29918 Tj
--238 TJm
-(v) 4.9815 Tj
-25 TJm
-(aluable) 28.7731 Tj
--239 TJm
-(additiona) 37.0823 Tj
-1 TJm
-(l) 2.76971 Tj
--239 TJm
-(insights) 31.0049 Tj
--239 TJm
-(into) 15.5024 Tj
--238 TJm
-(the) 12.1748 Tj
--239 TJm
-(algorithm,) 41.2369 Tj
--240 TJm
-(b) 4.9815 Tj
-20 TJm
-(ut) 7.75121 Tj
--239 TJm
-(is) 6.64532 Tj
--239 TJm
-(not) 12.7327 Tj
--238 TJm
-(immediately) 49.815 Tj
--239 TJm
-(the) 12.1748 Tj
--238 TJm
-(basis) 19.926 Tj
--239 TJm
-(of) 8.29918 Tj
--238 TJm
-(an) 9.40507 Tj
-15 TJm
-(y) 4.9815 Tj
--239 TJm
-(code) 18.8101 Tj
-72 225.805 Td
-(used) 18.2622 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(bzip2.) 24.6285 Tj
-[1 0 0 1 72 223.648] cm
-0 g
-0 G
-[1 0 0 1 0 -72.727] cm
-0.9294 0.96861 0.95685 rg
-0.9294 0.96861 0.95685 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 71.731 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.587] cm
-0 g
-0 G
-[1 0 0 1 0 68.144] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -214.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 214.283 Td
-/F130_0 9.963 Tf
-(Peter) 29.889 Tj
--426 TJm
-(Fenwick:) 47.8224 Tj
-102.732 202.328 Td
-(Block) 29.889 Tj
--426 TJm
-(Sorting) 41.8446 Tj
--426 TJm
-(Text) 23.9112 Tj
--426 TJm
-(Compr) 29.889 Tj
-1 TJm
-(ession) 35.8668 Tj
-102.732 190.373 Td
-(Proceedings) 65.7558 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(19th) 23.9112 Tj
--425 TJm
-(Australasian) 71.7336 Tj
--426 TJm
-(Computer) 47.8224 Tj
--426 TJm
-(Science) 41.8446 Tj
--426 TJm
-(Conference,) 65.7558 Tj
-111.22 178.418 Td
-(Melbourne,) 59.778 Tj
--426 TJm
-(Australia.) 59.778 Tj
--852 TJm
-(J) 5.9778 Tj
-1 TJm
-(an) 11.9556 Tj
--426 TJm
-(31) 11.9556 Tj
--426 TJm
-(-) 5.9778 Tj
--426 TJm
-(Feb) 17.9334 Tj
--426 TJm
-(2,) 11.9556 Tj
--426 TJm
-(1996.) 29.889 Tj
-102.732 166.463 Td
-(ftp://ftp.cs.auckland.ac.) 149.445 Tj
-1 TJm
-(nz/pub/peter-f/ACSC96paper.ps) 173.356 Tj
-[1 0 0 1 72 150.921] cm
-0 g
-0 G
-[1 0 0 1 468 3.587] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.55] cm
-0 g
-0 G
-[1 0 0 1 -72 -140.958] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 129.003 Td
-/F128_0 9.963 Tf
-(K) 7.19329 Tj
-15 TJm
-(unihik) 25.4654 Tj
-10 TJm
-(o) 4.9815 Tj
--250 TJm
-(Sadakane') 41.4959 Tj
-55 TJm
-(s) 3.87561 Tj
--250 TJm
-(sorting) 27.6772 Tj
--250 TJm
-(al) 7.19329 Tj
-1 TJm
-(gorithm,) 34.0436 Tj
--250 TJm
-(mentioned) 42.0638 Tj
--250 TJm
-(abo) 14.3866 Tj
-15 TJm
-(v) 4.9815 Tj
-15 TJm
-(e,) 6.91432 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailable) 26.5614 Tj
--250 TJm
-(from:) 22.1378 Tj
-[1 0 0 1 72 126.846] cm
-0 g
-0 G
-[1 0 0 1 0 -36.861] cm
-0.9294 0.96861 0.95685 rg
-0.9294 0.96861 0.95685 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -117.481] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 117.481 Td
-/F130_0 9.963 Tf
-(http://naomi.is.s.u-tokyo.) 155.423 Tj
-1 TJm
-(ac.jp/~sada/papers/Sada98b.ps.gz) 191.29 Tj
-[1 0 0 1 72 89.985] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 0 -29.17] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(34) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 38 38
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-0 g
-0 G
-q
-[1 0 0 1 72 741.554] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 14.446] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 187.197 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.49 -6.854] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 116.329 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F128_0 9.963 Tf
-(Miscellanea) 48.1412 Tj
-[1 0 0 1 266.071 749.146] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 280.796 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -472.974 -7.094] cm
-0 g
-0 G
-[1 0 0 1 0 -0.498] cm
-q
-[] 0 d
-0 J
-0.498 w
-0 0.249 m
-475.465 0.249 l
-S
-Q
-0 g
-0 G
-[1 0 0 1 479.251 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F128_0 9.963 Tf
-(The) 15.4925 Tj
--250 TJm
-(Manber) 30.9849 Tj
-20 TJm
-(-Myers) 28.7731 Tj
--250 TJm
-(suf) 12.1748 Tj
-25 TJm
-(\002x) 10.5209 Tj
--250 TJm
-(arra) 15.4825 Tj
-1 TJm
-(y) 4.9815 Tj
--250 TJm
-(construction) 49.2571 Tj
--250 TJm
-(algorithm) 38.7461 Tj
--250 TJm
-(is) 6.64532 Tj
--250 TJm
-(described) 38.1782 Tj
--250 TJm
-(in) 7.75121 Tj
--250 TJm
-(a) 4.42357 Tj
--250 TJm
-(paper) 22.1278 Tj
--250 TJm
-(a) 4.42357 Tj
-20 TJm
-(v) 4.9815 Tj
-25 TJm
-(ailabl) 22.1378 Tj
-1 TJm
-(e) 4.42357 Tj
--250 TJm
-(from:) 22.1378 Tj
-[1 0 0 1 72 707.881] cm
-0 g
-0 G
-[1 0 0 1 0 -36.862] cm
-0.9294 0.96861 0.95685 rg
-0.9294 0.96861 0.95685 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 35.866 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 32.279] cm
-0 g
-0 G
-[1 0 0 1 18 -8.368] cm
-0 g
-0 G
-[1 0 0 1 -90 -698.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 698.516 Td
-/F130_0 9.963 Tf
-(http://www.cs.arizona.edu/) 155.423 Tj
-1 TJm
-(people/gene/PAPERS/suffix.ps) 167.378 Tj
-[1 0 0 1 72 671.019] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -13.549] cm
-0 g
-0 G
-[1 0 0 1 -72 -661.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 649.101 Td
-/F128_0 9.963 Tf
-(Finally) 28.2351 Tj
-65 TJm
-(,) 2.49075 Tj
--227 TJm
-(the) 12.1748 Tj
--221 TJm
-(follo) 18.8201 Tj
-25 TJm
-(wing) 19.926 Tj
--221 TJm
-(papers) 26.0034 Tj
--222 TJm
-(docume) 31.5429 Tj
-1 TJm
-(nt) 7.75121 Tj
--222 TJm
-(some) 21.0319 Tj
--221 TJm
-(in) 7.75121 Tj
-40 TJm
-(v) 4.9815 Tj
-15 TJm
-(estig) 18.8201 Tj
-5 TJm
-(ations) 23.8016 Tj
--221 TJm
-(I) 3.31768 Tj
--221 TJm
-(made) 21.5799 Tj
--222 TJm
-(into) 15.5024 Tj
--221 TJm
-(the) 12.1748 Tj
--221 TJm
-(performance) 50.343 Tj
--221 TJm
-(of) 8.29918 Tj
--222 TJm
-(sorting) 27.6772 Tj
--221 TJm
-(and) 14.3866 Tj
--221 TJm
-(decompression) 59.768 Tj
-72 637.146 Td
-(algorithms:) 45.3914 Tj
-[1 0 0 1 72 634.989] cm
-0 g
-0 G
-[1 0 0 1 0 -132.503] cm
-0.9294 0.96861 0.95685 rg
-0.9294 0.96861 0.95685 RG
-q
-[] 0 d
-0 J
-0 j
-0 w
-0 0 468 131.507 re
-f
-Q
-0 g
-0 G
-[1 0 0 1 0 3.586] cm
-0 g
-0 G
-[1 0 0 1 0 127.921] cm
-0 g
-0 G
-[1 0 0 1 18 -8.369] cm
-0 g
-0 G
-[1 0 0 1 -90 -625.624] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 625.624 Td
-/F130_0 9.963 Tf
-(Julian) 35.8668 Tj
--426 TJm
-(Seward) 35.8668 Tj
-102.732 613.669 Td
-(On) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(Performance) 65.7558 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(BW) 11.9556 Tj
-1 TJm
-(T) 5.9778 Tj
--426 TJm
-(Sorting) 41.8446 Tj
--426 TJm
-(Algorithms) 59.778 Tj
-102.732 601.714 Td
-(Proceedings) 65.7558 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(IEEE) 23.9112 Tj
--425 TJm
-(Data) 23.9112 Tj
--426 TJm
-(Compression) 65.7558 Tj
--426 TJm
-(Conference) 59.778 Tj
--426 TJm
-(2000) 23.9112 Tj
-111.22 589.759 Td
-(Snowbird,) 53.8002 Tj
--426 TJm
-(Utah.) 29.889 Tj
--852 TJm
-(28-30) 29.889 Tj
--426 TJm
-(M) 5.9778 Tj
-1 TJm
-(arch) 23.9112 Tj
--426 TJm
-(2000.) 29.889 Tj
-90 565.848 Td
-(Julian) 35.8668 Tj
--426 TJm
-(Seward) 35.8668 Tj
-102.732 553.893 Td
-(Space-time) 59.778 Tj
--426 TJm
-(Tradeoffs) 53.8002 Tj
--426 TJm
-(in) 11.9556 Tj
--425 TJm
-(the) 17.9334 Tj
--426 TJm
-(Inverse) 41.8446 Tj
--426 TJm
-(B-W) 17.9334 Tj
--426 TJm
-(Transform) 53.8002 Tj
-102.732 541.938 Td
-(Proceedings) 65.7558 Tj
--426 TJm
-(of) 11.9556 Tj
--426 TJm
-(the) 17.9334 Tj
--426 TJm
-(IEEE) 23.9112 Tj
--425 TJm
-(Data) 23.9112 Tj
--426 TJm
-(Compression) 65.7558 Tj
--426 TJm
-(Conference) 59.778 Tj
--426 TJm
-(2001) 23.9112 Tj
-111.22 529.983 Td
-(Snowbird,) 53.8002 Tj
--426 TJm
-(Utah.) 29.889 Tj
--852 TJm
-(27-29) 29.889 Tj
--426 TJm
-(M) 5.9778 Tj
-1 TJm
-(arch) 23.9112 Tj
--426 TJm
-(2001.) 29.889 Tj
-[1 0 0 1 72 502.486] cm
-0 g
-0 G
-[1 0 0 1 468 3.586] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 -468 -3.586] cm
-0 g
-0 G
-[1 0 0 1 0 -451.634] cm
-0 g
-0 G
-[1 0 0 1 1.893 0] cm
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 374.394 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 2.491 0] cm
-0 g
-0 G
-[1 0 0 1 0 6.854] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 40.572 -6.755] cm
-0 g
-0 G
-[1 0 0 1 -493.841 -50.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.951 Td
-/F128_0 9.963 Tf
-(35) 9.963 Tj
-[1 0 0 1 453.269 50.852] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 93.598 0] cm
-0 g
-0 G
-0 g
-0 G
-[1 0 0 1 6.277 0] cm
-0 g
-0 G
-[1 0 0 1 -13.144 0] cm
-0 g
-0 G
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Trailer
-end
-%%DocumentSuppliedResources:
-%%+ font CJBHNS+CMMI10
-%%+ font RBGKEI+CMSY10
-%%EOF
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.xml b/contrib/vmap_extractor_v2/stormlib/bzip2/manual.xml
deleted file mode 100644
index 1ab5bd71d9e..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/manual.xml
+++ /dev/null
@@ -1,2966 +0,0 @@
-<?xml version="1.0"?> <!-- -*- sgml -*- -->
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"[
-
-<!-- various strings, dates etc. common to all docs -->
-<!ENTITY % common-ents SYSTEM "entities.xml"> %common-ents;
-]>
-
-<book lang="en" id="userman" xreflabel="bzip2 Manual">
-
- <bookinfo>
- <title>bzip2 and libbzip2, version 1.0.3</title>
- <subtitle>A program and library for data compression</subtitle>
- <copyright>
- <year>&bz-lifespan;</year>
- <holder>Julian Seward</holder>
- </copyright>
- <releaseinfo>Version &bz-version; of &bz-date;</releaseinfo>
-
- <authorgroup>
- <author>
- <firstname>Julian</firstname>
- <surname>Seward</surname>
- <affiliation>
- <orgname>&bz-url;</orgname>
- </affiliation>
- </author>
- </authorgroup>
-
- <legalnotice>
-
- <para>This program, <computeroutput>bzip2</computeroutput>, the
- associated library <computeroutput>libbzip2</computeroutput>, and
- all documentation, are copyright &copy; &bz-lifespan; Julian Seward.
- All rights reserved.</para>
-
- <para>Redistribution and use in source and binary forms, with
- or without modification, are permitted provided that the
- following conditions are met:</para>
-
- <itemizedlist mark='bullet'>
-
- <listitem><para>Redistributions of source code must retain the
- above copyright notice, this list of conditions and the
- following disclaimer.</para></listitem>
-
- <listitem><para>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.</para></listitem>
-
- <listitem><para>Altered source versions must be plainly marked
- as such, and must not be misrepresented as being the original
- software.</para></listitem>
-
- <listitem><para>The name of the author may not be used to
- endorse or promote products derived from this software without
- specific prior written permission.</para></listitem>
-
- </itemizedlist>
-
- <para>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 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.</para>
-
- <para>PATENTS: To the best of my knowledge,
- <computeroutput>bzip2</computeroutput> and
- <computeroutput>libbzip2</computeroutput> do not use any patented
- algorithms. However, I do not have the resources to carry
- out a patent search. Therefore I cannot give any guarantee of
- the above statement.
- </para>
-
-</legalnotice>
-
-</bookinfo>
-
-
-
-<chapter id="intro" xreflabel="Introduction">
-<title>Introduction</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses files
-using the Burrows-Wheeler block-sorting text compression
-algorithm, and Huffman coding. Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</para>
-
-<para><computeroutput>bzip2</computeroutput> is built on top of
-<computeroutput>libbzip2</computeroutput>, a flexible library for
-handling compressed data in the
-<computeroutput>bzip2</computeroutput> format. This manual
-describes both how to use the program and how to work with the
-library interface. Most of the manual is devoted to this
-library, not the program, which is good news if your interest is
-only in the program.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><xref linkend="using"/> describes how to use
- <computeroutput>bzip2</computeroutput>; this is the only part
- you need to read if you just want to know how to operate the
- program.</para></listitem>
-
- <listitem><para><xref linkend="libprog"/> describes the
- programming interfaces in detail, and</para></listitem>
-
- <listitem><para><xref linkend="misc"/> records some
- miscellaneous notes which I thought ought to be recorded
- somewhere.</para></listitem>
-
-</itemizedlist>
-
-</chapter>
-
-
-<chapter id="using" xreflabel="How to use bzip2">
-<title>How to use bzip2</title>
-
-<para>This chapter contains a copy of the
-<computeroutput>bzip2</computeroutput> man page, and nothing
-else.</para>
-
-<sect1 id="name" xreflabel="NAME">
-<title>NAME</title>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><computeroutput>bzip2</computeroutput>,
- <computeroutput>bunzip2</computeroutput> - a block-sorting file
- compressor, v1.0.3</para></listitem>
-
- <listitem><para><computeroutput>bzcat</computeroutput> -
- decompresses files to stdout</para></listitem>
-
- <listitem><para><computeroutput>bzip2recover</computeroutput> -
- recovers data from damaged bzip2 files</para></listitem>
-
-</itemizedlist>
-
-</sect1>
-
-
-<sect1 id="synopsis" xreflabel="SYNOPSIS">
-<title>SYNOPSIS</title>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><computeroutput>bzip2</computeroutput> [
- -cdfkqstvzVL123456789 ] [ filenames ... ]</para></listitem>
-
- <listitem><para><computeroutput>bunzip2</computeroutput> [
- -fkvsVL ] [ filenames ... ]</para></listitem>
-
- <listitem><para><computeroutput>bzcat</computeroutput> [ -s ] [
- filenames ... ]</para></listitem>
-
- <listitem><para><computeroutput>bzip2recover</computeroutput>
- filename</para></listitem>
-
-</itemizedlist>
-
-</sect1>
-
-
-<sect1 id="description" xreflabel="DESCRIPTION">
-<title>DESCRIPTION</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses files
-using the Burrows-Wheeler block sorting text compression
-algorithm, and Huffman coding. Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</para>
-
-<para>The command-line options are deliberately very similar to
-those of GNU <computeroutput>gzip</computeroutput>, but they are
-not identical.</para>
-
-<para><computeroutput>bzip2</computeroutput> expects a list of
-file names to accompany the command-line flags. Each file is
-replaced by a compressed version of itself, with the name
-<computeroutput>original_name.bz2</computeroutput>. Each
-compressed file has the same modification date, permissions, and,
-when possible, ownership as the corresponding original, so that
-these properties can be correctly restored at decompression time.
-File name handling is naive in the sense that there is no
-mechanism for preserving original file names, permissions,
-ownerships or dates in filesystems which lack these concepts, or
-have serious file name length restrictions, such as
-MS-DOS.</para>
-
-<para><computeroutput>bzip2</computeroutput> and
-<computeroutput>bunzip2</computeroutput> will by default not
-overwrite existing files. If you want this to happen, specify
-the <computeroutput>-f</computeroutput> flag.</para>
-
-<para>If no file names are specified,
-<computeroutput>bzip2</computeroutput> compresses from standard
-input to standard output. In this case,
-<computeroutput>bzip2</computeroutput> will decline to write
-compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.</para>
-
-<para><computeroutput>bunzip2</computeroutput> (or
-<computeroutput>bzip2 -d</computeroutput>) decompresses all
-specified files. Files which were not created by
-<computeroutput>bzip2</computeroutput> will be detected and
-ignored, and a warning issued.
-<computeroutput>bzip2</computeroutput> attempts to guess the
-filename for the decompressed file from that of the compressed
-file as follows:</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><computeroutput>filename.bz2 </computeroutput>
- becomes
- <computeroutput>filename</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>filename.bz </computeroutput>
- becomes
- <computeroutput>filename</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>filename.tbz2</computeroutput>
- becomes
- <computeroutput>filename.tar</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>filename.tbz </computeroutput>
- becomes
- <computeroutput>filename.tar</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>anyothername </computeroutput>
- becomes
- <computeroutput>anyothername.out</computeroutput></para></listitem>
-
-</itemizedlist>
-
-<para>If the file does not end in one of the recognised endings,
-<computeroutput>.bz2</computeroutput>,
-<computeroutput>.bz</computeroutput>,
-<computeroutput>.tbz2</computeroutput> or
-<computeroutput>.tbz</computeroutput>,
-<computeroutput>bzip2</computeroutput> complains that it cannot
-guess the name of the original file, and uses the original name
-with <computeroutput>.out</computeroutput> appended.</para>
-
-<para>As with compression, supplying no filenames causes
-decompression from standard input to standard output.</para>
-
-<para><computeroutput>bunzip2</computeroutput> will correctly
-decompress a file which is the concatenation of two or more
-compressed files. The result is the concatenation of the
-corresponding uncompressed files. Integrity testing
-(<computeroutput>-t</computeroutput>) of concatenated compressed
-files is also supported.</para>
-
-<para>You can also compress or decompress files to the standard
-output by giving the <computeroutput>-c</computeroutput> flag.
-Multiple files may be compressed and decompressed like this. The
-resulting outputs are fed sequentially to stdout. Compression of
-multiple files in this manner generates a stream containing
-multiple compressed file representations. Such a stream can be
-decompressed correctly only by
-<computeroutput>bzip2</computeroutput> version 0.9.0 or later.
-Earlier versions of <computeroutput>bzip2</computeroutput> will
-stop after decompressing the first file in the stream.</para>
-
-<para><computeroutput>bzcat</computeroutput> (or
-<computeroutput>bzip2 -dc</computeroutput>) decompresses all
-specified files to the standard output.</para>
-
-<para><computeroutput>bzip2</computeroutput> will read arguments
-from the environment variables
-<computeroutput>BZIP2</computeroutput> and
-<computeroutput>BZIP</computeroutput>, in that order, and will
-process them before any arguments read from the command line.
-This gives a convenient way to supply default arguments.</para>
-
-<para>Compression is always performed, even if the compressed
-file is slightly larger than the original. Files of less than
-about one hundred bytes tend to get larger, since the compression
-mechanism has a constant overhead in the region of 50 bytes.
-Random data (including the output of most file compressors) is
-coded at about 8.05 bits per byte, giving an expansion of around
-0.5%.</para>
-
-<para>As a self-check for your protection,
-<computeroutput>bzip2</computeroutput> uses 32-bit CRCs to make
-sure that the decompressed version of a file is identical to the
-original. This guards against corruption of the compressed data,
-and against undetected bugs in
-<computeroutput>bzip2</computeroutput> (hopefully very unlikely).
-The chances of data corruption going undetected is microscopic,
-about one chance in four billion for each file processed. Be
-aware, though, that the check occurs upon decompression, so it
-can only tell you that something is wrong. It can't help you
-recover the original uncompressed data. You can use
-<computeroutput>bzip2recover</computeroutput> to try to recover
-data from damaged files.</para>
-
-<para>Return values: 0 for a normal exit, 1 for environmental
-problems (file not found, invalid flags, I/O errors, etc.), 2
-to indicate a corrupt compressed file, 3 for an internal
-consistency error (eg, bug) which caused
-<computeroutput>bzip2</computeroutput> to panic.</para>
-
-</sect1>
-
-
-<sect1 id="options" xreflabel="OPTIONS">
-<title>OPTIONS</title>
-
-<variablelist>
-
- <varlistentry>
- <term><computeroutput>-c --stdout</computeroutput></term>
- <listitem><para>Compress or decompress to standard
- output.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-d --decompress</computeroutput></term>
- <listitem><para>Force decompression.
- <computeroutput>bzip2</computeroutput>,
- <computeroutput>bunzip2</computeroutput> and
- <computeroutput>bzcat</computeroutput> are really the same
- program, and the decision about what actions to take is done on
- the basis of which name is used. This flag overrides that
- mechanism, and forces bzip2 to decompress.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-z --compress</computeroutput></term>
- <listitem><para>The complement to
- <computeroutput>-d</computeroutput>: forces compression,
- regardless of the invokation name.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-t --test</computeroutput></term>
- <listitem><para>Check integrity of the specified file(s), but
- don't decompress them. This really performs a trial
- decompression and throws away the result.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-f --force</computeroutput></term>
- <listitem><para>Force overwrite of output files. Normally,
- <computeroutput>bzip2</computeroutput> will not overwrite
- existing output files. Also forces
- <computeroutput>bzip2</computeroutput> to break hard links to
- files, which it otherwise wouldn't do.</para>
- <para><computeroutput>bzip2</computeroutput> normally declines
- to decompress files which don't have the correct magic header
- bytes. If forced (<computeroutput>-f</computeroutput>),
- however, it will pass such files through unmodified. This is
- how GNU <computeroutput>gzip</computeroutput> behaves.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-k --keep</computeroutput></term>
- <listitem><para>Keep (don't delete) input files during
- compression or decompression.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-s --small</computeroutput></term>
- <listitem><para>Reduce memory usage, for compression,
- decompression and testing. Files are decompressed and tested
- using a modified algorithm which only requires 2.5 bytes per
- block byte. This means any file can be decompressed in 2300k
- of memory, albeit at about half the normal speed.</para>
- <para>During compression, <computeroutput>-s</computeroutput>
- selects a block size of 200k, which limits memory use to around
- the same figure, at the expense of your compression ratio. In
- short, if your machine is low on memory (8 megabytes or less),
- use <computeroutput>-s</computeroutput> for everything. See
- <xref linkend="memory-management"/> below.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-q --quiet</computeroutput></term>
- <listitem><para>Suppress non-essential warning messages.
- Messages pertaining to I/O errors and other critical events
- will not be suppressed.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-v --verbose</computeroutput></term>
- <listitem><para>Verbose mode -- show the compression ratio for
- each file processed. Further
- <computeroutput>-v</computeroutput>'s increase the verbosity
- level, spewing out lots of information which is primarily of
- interest for diagnostic purposes.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-L --license -V --version</computeroutput></term>
- <listitem><para>Display the software version, license terms and
- conditions.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-1</computeroutput> (or
- <computeroutput>--fast</computeroutput>) to
- <computeroutput>-9</computeroutput> (or
- <computeroutput>-best</computeroutput>)</term>
- <listitem><para>Set the block size to 100 k, 200 k ... 900 k
- when compressing. Has no effect when decompressing. See <xref
- linkend="memory-management" /> below. The
- <computeroutput>--fast</computeroutput> and
- <computeroutput>--best</computeroutput> aliases are primarily
- for GNU <computeroutput>gzip</computeroutput> compatibility.
- In particular, <computeroutput>--fast</computeroutput> doesn't
- make things significantly faster. And
- <computeroutput>--best</computeroutput> merely selects the
- default behaviour.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>--</computeroutput></term>
- <listitem><para>Treats all subsequent arguments as file names,
- even if they start with a dash. This is so you can handle
- files with names beginning with a dash, for example:
- <computeroutput>bzip2 --
- -myfilename</computeroutput>.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>--repetitive-fast</computeroutput></term>
- <term><computeroutput>--repetitive-best</computeroutput></term>
- <listitem><para>These flags are redundant in versions 0.9.5 and
- above. They provided some coarse control over the behaviour of
- the sorting algorithm in earlier versions, which was sometimes
- useful. 0.9.5 and above have an improved algorithm which
- renders these flags irrelevant.</para></listitem>
- </varlistentry>
-
-</variablelist>
-
-</sect1>
-
-
-<sect1 id="memory-management" xreflabel="MEMORY MANAGEMENT">
-<title>MEMORY MANAGEMENT</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses large
-files in blocks. The block size affects both the compression
-ratio achieved, and the amount of memory needed for compression
-and decompression. The flags <computeroutput>-1</computeroutput>
-through <computeroutput>-9</computeroutput> specify the block
-size to be 100,000 bytes through 900,000 bytes (the default)
-respectively. At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-<computeroutput>bunzip2</computeroutput> then allocates itself
-just enough memory to decompress the file. Since block sizes are
-stored in compressed files, it follows that the flags
-<computeroutput>-1</computeroutput> to
-<computeroutput>-9</computeroutput> are irrelevant to and so
-ignored during decompression.</para>
-
-<para>Compression and decompression requirements, in bytes, can be
-estimated as:</para>
-<programlisting>
-Compression: 400k + ( 8 x block size )
-
-Decompression: 100k + ( 4 x block size ), or
- 100k + ( 2.5 x block size )
-</programlisting>
-
-<para>Larger block sizes give rapidly diminishing marginal
-returns. Most of the compression comes from the first two or
-three hundred k of block size, a fact worth bearing in mind when
-using <computeroutput>bzip2</computeroutput> on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block
-size.</para>
-
-<para>For files compressed with the default 900k block size,
-<computeroutput>bunzip2</computeroutput> will require about 3700
-kbytes to decompress. To support decompression of any file on a
-4 megabyte machine, <computeroutput>bunzip2</computeroutput> has
-an option to decompress using approximately half this amount of
-memory, about 2300 kbytes. Decompression speed is also halved,
-so you should use this option only where necessary. The relevant
-flag is <computeroutput>-s</computeroutput>.</para>
-
-<para>In general, try and use the largest block size memory
-constraints allow, since that maximises the compression achieved.
-Compression and decompression speed are virtually unaffected by
-block size.</para>
-
-<para>Another significant point applies to files which fit in a
-single block -- that means most files you'd encounter using a
-large block size. The amount of real memory touched is
-proportional to the size of the file, since the file is smaller
-than a block. For example, compressing a file 20,000 bytes long
-with the flag <computeroutput>-9</computeroutput> will cause the
-compressor to allocate around 7600k of memory, but only touch
-400k + 20000 * 8 = 560 kbytes of it. Similarly, the decompressor
-will allocate 3700k but only touch 100k + 20000 * 4 = 180
-kbytes.</para>
-
-<para>Here is a table which summarises the maximum memory usage
-for different block sizes. Also recorded is the total compressed
-size for 14 files of the Calgary Text Compression Corpus
-totalling 3,141,622 bytes. This column gives some feel for how
-compression varies with block size. These figures tend to
-understate the advantage of larger block sizes for larger files,
-since the Corpus is dominated by smaller files.</para>
-
-<programlisting>
- Compress Decompress Decompress Corpus
-Flag usage usage -s usage Size
-
- -1 1200k 500k 350k 914704
- -2 2000k 900k 600k 877703
- -3 2800k 1300k 850k 860338
- -4 3600k 1700k 1100k 846899
- -5 4400k 2100k 1350k 845160
- -6 5200k 2500k 1600k 838626
- -7 6100k 2900k 1850k 834096
- -8 6800k 3300k 2100k 828642
- -9 7600k 3700k 2350k 828642
-</programlisting>
-
-</sect1>
-
-
-<sect1 id="recovering" xreflabel="RECOVERING DATA FROM DAMAGED FILES">
-<title>RECOVERING DATA FROM DAMAGED FILES</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses files in
-blocks, usually 900kbytes long. Each block is handled
-independently. If a media or transmission error causes a
-multi-block <computeroutput>.bz2</computeroutput> file to become
-damaged, it may be possible to recover data from the undamaged
-blocks in the file.</para>
-
-<para>The compressed representation of each block is delimited by
-a 48-bit pattern, which makes it possible to find the block
-boundaries with reasonable certainty. Each block also carries
-its own 32-bit CRC, so damaged blocks can be distinguished from
-undamaged ones.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> is a simple
-program whose purpose is to search for blocks in
-<computeroutput>.bz2</computeroutput> files, and write each block
-out into its own <computeroutput>.bz2</computeroutput> file. You
-can then use <computeroutput>bzip2 -t</computeroutput> to test
-the integrity of the resulting files, and decompress those which
-are undamaged.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> takes a
-single argument, the name of the damaged file, and writes a
-number of files <computeroutput>rec0001file.bz2</computeroutput>,
-<computeroutput>rec0002file.bz2</computeroutput>, etc, containing
-the extracted blocks. The output filenames are designed so that
-the use of wildcards in subsequent processing -- for example,
-<computeroutput>bzip2 -dc rec*file.bz2 &#62;
-recovered_data</computeroutput> -- lists the files in the correct
-order.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> should be of
-most use dealing with large <computeroutput>.bz2</computeroutput>
-files, as these will contain many blocks. It is clearly futile
-to use it on damaged single-block files, since a damaged block
-cannot be recovered. If you wish to minimise any potential data
-loss through media or transmission errors, you might consider
-compressing with a smaller block size.</para>
-
-</sect1>
-
-
-<sect1 id="performance" xreflabel="PERFORMANCE NOTES">
-<title>PERFORMANCE NOTES</title>
-
-<para>The sorting phase of compression gathers together similar
-strings in the file. Because of this, files containing very long
-runs of repeated symbols, like "aabaabaabaab ..." (repeated
-several hundred times) may compress more slowly than normal.
-Versions 0.9.5 and above fare much better than previous versions
-in this respect. The ratio between worst-case and average-case
-compression time is in the region of 10:1. For previous
-versions, this figure was more like 100:1. You can use the
-<computeroutput>-vvvv</computeroutput> option to monitor progress
-in great detail, if you want.</para>
-
-<para>Decompression speed is unaffected by these
-phenomena.</para>
-
-<para><computeroutput>bzip2</computeroutput> usually allocates
-several megabytes of memory to operate in, and then charges all
-over it in a fairly random fashion. This means that performance,
-both for compressing and decompressing, is largely determined by
-the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss
-rate have been observed to give disproportionately large
-performance improvements. I imagine
-<computeroutput>bzip2</computeroutput> will perform best on
-machines with very large caches.</para>
-
-</sect1>
-
-
-
-<sect1 id="caveats" xreflabel="CAVEATS">
-<title>CAVEATS</title>
-
-<para>I/O error messages are not as helpful as they could be.
-<computeroutput>bzip2</computeroutput> tries hard to detect I/O
-errors and exit cleanly, but the details of what the problem is
-sometimes seem rather misleading.</para>
-
-<para>This manual page pertains to version &bz-version; of
-<computeroutput>bzip2</computeroutput>. Compressed data created
-by this version is entirely forwards and backwards compatible
-with the previous public releases, versions 0.1pl2, 0.9.0 and
-0.9.5, 1.0.0, 1.0.1 and 1.0.2, but with the following exception: 0.9.0
-and above can correctly decompress multiple concatenated
-compressed files. 0.1pl2 cannot do this; it will stop after
-decompressing just the first file in the stream.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> versions
-prior to 1.0.2 used 32-bit integers to represent bit positions in
-compressed files, so it could not handle compressed files more
-than 512 megabytes long. Versions 1.0.2 and above use 64-bit ints
-on some platforms which support them (GNU supported targets, and
-Windows). To establish whether or not
-<computeroutput>bzip2recover</computeroutput> was built with such
-a limitation, run it without arguments. In any event you can
-build yourself an unlimited version if you can recompile it with
-<computeroutput>MaybeUInt64</computeroutput> set to be an
-unsigned 64-bit integer.</para>
-
-</sect1>
-
-
-
-<sect1 id="author" xreflabel="AUTHOR">
-<title>AUTHOR</title>
-
-<para>Julian Seward,
-<computeroutput>&bz-email;</computeroutput></para>
-
-<para>The ideas embodied in
-<computeroutput>bzip2</computeroutput> are due to (at least) the
-following people: Michael Burrows and David Wheeler (for the
-block sorting transformation), David Wheeler (again, for the
-Huffman coder), Peter Fenwick (for the structured coding model in
-the original <computeroutput>bzip</computeroutput>, and many
-refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-<computeroutput>bzip</computeroutput>). I am much indebted for
-their help, support and advice. See the manual in the source
-distribution for pointers to sources of documentation. Christian
-von Roques encouraged me to look for faster sorting algorithms,
-so as to speed up compression. Bela Lubkin encouraged me to
-improve the worst-case compression performance.
-Donna Robinson XMLised the documentation.
-Many people sent
-patches, helped with portability problems, lent machines, gave
-advice and were generally helpful.</para>
-
-</sect1>
-
-</chapter>
-
-
-
-<chapter id="libprog" xreflabel="Programming with libbzip2">
-<title>
-Programming with <computeroutput>libbzip2</computeroutput>
-</title>
-
-<para>This chapter describes the programming interface to
-<computeroutput>libbzip2</computeroutput>.</para>
-
-<para>For general background information, particularly about
-memory use and performance aspects, you'd be well advised to read
-<xref linkend="using"/> as well.</para>
-
-
-<sect1 id="top-level" xreflabel="Top-level structure">
-<title>Top-level structure</title>
-
-<para><computeroutput>libbzip2</computeroutput> is a flexible
-library for compressing and decompressing data in the
-<computeroutput>bzip2</computeroutput> data format. Although
-packaged as a single entity, it helps to regard the library as
-three separate parts: the low level interface, and the high level
-interface, and some utility functions.</para>
-
-<para>The structure of
-<computeroutput>libbzip2</computeroutput>'s interfaces is similar
-to that of Jean-loup Gailly's and Mark Adler's excellent
-<computeroutput>zlib</computeroutput> library.</para>
-
-<para>All externally visible symbols have names beginning
-<computeroutput>BZ2_</computeroutput>. This is new in version
-1.0. The intention is to minimise pollution of the namespaces of
-library clients.</para>
-
-<para>To use any part of the library, you need to
-<computeroutput>#include &lt;bzlib.h&gt;</computeroutput>
-into your sources.</para>
-
-
-
-<sect2 id="ll-summary" xreflabel="Low-level summary">
-<title>Low-level summary</title>
-
-<para>This interface provides services for compressing and
-decompressing data in memory. There's no provision for dealing
-with files, streams or any other I/O mechanisms, just straight
-memory-to-memory work. In fact, this part of the library can be
-compiled without inclusion of
-<computeroutput>stdio.h</computeroutput>, which may be helpful
-for embedded applications.</para>
-
-<para>The low-level part of the library has no global variables
-and is therefore thread-safe.</para>
-
-<para>Six routines make up the low level interface:
-<computeroutput>BZ2_bzCompressInit</computeroutput>,
-<computeroutput>BZ2_bzCompress</computeroutput>, and
-<computeroutput>BZ2_bzCompressEnd</computeroutput> for
-compression, and a corresponding trio
-<computeroutput>BZ2_bzDecompressInit</computeroutput>,
-<computeroutput>BZ2_bzDecompress</computeroutput> and
-<computeroutput>BZ2_bzDecompressEnd</computeroutput> for
-decompression. The <computeroutput>*Init</computeroutput>
-functions allocate memory for compression/decompression and do
-other initialisations, whilst the
-<computeroutput>*End</computeroutput> functions close down
-operations and release memory.</para>
-
-<para>The real work is done by
-<computeroutput>BZ2_bzCompress</computeroutput> and
-<computeroutput>BZ2_bzDecompress</computeroutput>. These
-compress and decompress data from a user-supplied input buffer to
-a user-supplied output buffer. These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions. This is a flexible mechanism allowing a
-consumer-pull style of activity, or producer-push, or a mixture
-of both.</para>
-
-</sect2>
-
-
-<sect2 id="hl-summary" xreflabel="High-level summary">
-<title>High-level summary</title>
-
-<para>This interface provides some handy wrappers around the
-low-level interface to facilitate reading and writing
-<computeroutput>bzip2</computeroutput> format files
-(<computeroutput>.bz2</computeroutput> files). The routines
-provide hooks to facilitate reading files in which the
-<computeroutput>bzip2</computeroutput> data stream is embedded
-within some larger-scale file structure, or where there are
-multiple <computeroutput>bzip2</computeroutput> data streams
-concatenated end-to-end.</para>
-
-<para>For reading files,
-<computeroutput>BZ2_bzReadOpen</computeroutput>,
-<computeroutput>BZ2_bzRead</computeroutput>,
-<computeroutput>BZ2_bzReadClose</computeroutput> and
-<computeroutput>BZ2_bzReadGetUnused</computeroutput> are
-supplied. For writing files,
-<computeroutput>BZ2_bzWriteOpen</computeroutput>,
-<computeroutput>BZ2_bzWrite</computeroutput> and
-<computeroutput>BZ2_bzWriteFinish</computeroutput> are
-available.</para>
-
-<para>As with the low-level library, no global variables are used
-so the library is per se thread-safe. However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult <computeroutput>errno</computeroutput> to
-determine the cause of the error. In that case, you'd need a C
-library which correctly supports
-<computeroutput>errno</computeroutput> in a multithreaded
-environment.</para>
-
-<para>To make the library a little simpler and more portable,
-<computeroutput>BZ2_bzReadOpen</computeroutput> and
-<computeroutput>BZ2_bzWriteOpen</computeroutput> require you to
-pass them file handles (<computeroutput>FILE*</computeroutput>s)
-which have previously been opened for reading or writing
-respectively. That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.</para>
-
-</sect2>
-
-
-<sect2 id="util-fns-summary" xreflabel="Utility functions summary">
-<title>Utility functions summary</title>
-
-<para>For very simple needs,
-<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
-<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> are
-provided. These compress data in memory from one buffer to
-another buffer in a single function call. You should assess
-whether these functions fulfill your memory-to-memory
-compression/decompression requirements before investing effort in
-understanding the more general but more complex low-level
-interface.</para>
-
-<para>Yoshioka Tsuneo
-(<computeroutput>QWF00133@niftyserve.or.jp</computeroutput> /
-<computeroutput>tsuneo-y@is.aist-nara.ac.jp</computeroutput>) has
-contributed some functions to give better
-<computeroutput>zlib</computeroutput> compatibility. These
-functions are <computeroutput>BZ2_bzopen</computeroutput>,
-<computeroutput>BZ2_bzread</computeroutput>,
-<computeroutput>BZ2_bzwrite</computeroutput>,
-<computeroutput>BZ2_bzflush</computeroutput>,
-<computeroutput>BZ2_bzclose</computeroutput>,
-<computeroutput>BZ2_bzerror</computeroutput> and
-<computeroutput>BZ2_bzlibVersion</computeroutput>. You may find
-these functions more convenient for simple file reading and
-writing, than those in the high-level interface. These functions
-are not (yet) officially part of the library, and are minimally
-documented here. If they break, you get to keep all the pieces.
-I hope to document them properly when time permits.</para>
-
-<para>Yoshioka also contributed modifications to allow the
-library to be built as a Windows DLL.</para>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="err-handling" xreflabel="Error handling">
-<title>Error handling</title>
-
-<para>The library is designed to recover cleanly in all
-situations, including the worst-case situation of decompressing
-random data. I'm not 100% sure that it can always do this, so
-you might want to add a signal handler to catch segmentation
-violations during decompression if you are feeling especially
-paranoid. I would be interested in hearing more about the
-robustness of the library to corrupted compressed data.</para>
-
-<para>Version 1.0.3 more robust in this respect than any
-previous version. Investigations with Valgrind (a tool for detecting
-problems with memory management) indicate
-that, at least for the few files I tested, all single-bit errors
-in the decompressed data are caught properly, with no
-segmentation faults, no uses of uninitialised data, no out of
-range reads or writes, and no infinite looping in the decompressor.
-So it's certainly pretty robust, although
-I wouldn't claim it to be totally bombproof.</para>
-
-<para>The file <computeroutput>bzlib.h</computeroutput> contains
-all definitions needed to use the library. In particular, you
-should definitely not include
-<computeroutput>bzlib_private.h</computeroutput>.</para>
-
-<para>In <computeroutput>bzlib.h</computeroutput>, the various
-return values are defined. The following list is not intended as
-an exhaustive description of the circumstances in which a given
-value may be returned -- those descriptions are given later.
-Rather, it is intended to convey the rough meaning of each return
-value. The first five actions are normal and not intended to
-denote an error situation.</para>
-
-<variablelist>
-
- <varlistentry>
- <term><computeroutput>BZ_OK</computeroutput></term>
- <listitem><para>The requested action was completed
- successfully.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_RUN_OK, BZ_FLUSH_OK,
- BZ_FINISH_OK</computeroutput></term>
- <listitem><para>In
- <computeroutput>BZ2_bzCompress</computeroutput>, the requested
- flush/finish/nothing-special action was completed
- successfully.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_STREAM_END</computeroutput></term>
- <listitem><para>Compression of data was completed, or the
- logical stream end was detected during
- decompression.</para></listitem>
- </varlistentry>
-
-</variablelist>
-
-<para>The following return values indicate an error of some
-kind.</para>
-
-<variablelist>
-
- <varlistentry>
- <term><computeroutput>BZ_CONFIG_ERROR</computeroutput></term>
- <listitem><para>Indicates that the library has been improperly
- compiled on your platform -- a major configuration error.
- Specifically, it means that
- <computeroutput>sizeof(char)</computeroutput>,
- <computeroutput>sizeof(short)</computeroutput> and
- <computeroutput>sizeof(int)</computeroutput> are not 1, 2 and
- 4 respectively, as they should be. Note that the library
- should still work properly on 64-bit platforms which follow
- the LP64 programming model -- that is, where
- <computeroutput>sizeof(long)</computeroutput> and
- <computeroutput>sizeof(void*)</computeroutput> are 8. Under
- LP64, <computeroutput>sizeof(int)</computeroutput> is still 4,
- so <computeroutput>libbzip2</computeroutput>, which doesn't
- use the <computeroutput>long</computeroutput> type, is
- OK.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_SEQUENCE_ERROR</computeroutput></term>
- <listitem><para>When using the library, it is important to call
- the functions in the correct sequence and with data structures
- (buffers etc) in the correct states.
- <computeroutput>libbzip2</computeroutput> checks as much as it
- can to ensure this is happening, and returns
- <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> if not.
- Code which complies precisely with the function semantics, as
- detailed below, should never receive this value; such an event
- denotes buggy code which you should
- investigate.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_PARAM_ERROR</computeroutput></term>
- <listitem><para>Returned when a parameter to a function call is
- out of range or otherwise manifestly incorrect. As with
- <computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, this
- denotes a bug in the client code. The distinction between
- <computeroutput>BZ_PARAM_ERROR</computeroutput> and
- <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> is a bit
- hazy, but still worth making.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_MEM_ERROR</computeroutput></term>
- <listitem><para>Returned when a request to allocate memory
- failed. Note that the quantity of memory needed to decompress
- a stream cannot be determined until the stream's header has
- been read. So
- <computeroutput>BZ2_bzDecompress</computeroutput> and
- <computeroutput>BZ2_bzRead</computeroutput> may return
- <computeroutput>BZ_MEM_ERROR</computeroutput> even though some
- of the compressed data has been read. The same is not true
- for compression; once
- <computeroutput>BZ2_bzCompressInit</computeroutput> or
- <computeroutput>BZ2_bzWriteOpen</computeroutput> have
- successfully completed,
- <computeroutput>BZ_MEM_ERROR</computeroutput> cannot
- occur.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_DATA_ERROR</computeroutput></term>
- <listitem><para>Returned when a data integrity error is
- detected during decompression. Most importantly, this means
- when stored and computed CRCs for the data do not match. This
- value is also returned upon detection of any other anomaly in
- the compressed data.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_DATA_ERROR_MAGIC</computeroutput></term>
- <listitem><para>As a special case of
- <computeroutput>BZ_DATA_ERROR</computeroutput>, it is
- sometimes useful to know when the compressed stream does not
- start with the correct magic bytes (<computeroutput>'B' 'Z'
- 'h'</computeroutput>).</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_IO_ERROR</computeroutput></term>
- <listitem><para>Returned by
- <computeroutput>BZ2_bzRead</computeroutput> and
- <computeroutput>BZ2_bzWrite</computeroutput> when there is an
- error reading or writing in the compressed file, and by
- <computeroutput>BZ2_bzReadOpen</computeroutput> and
- <computeroutput>BZ2_bzWriteOpen</computeroutput> for attempts
- to use a file for which the error indicator (viz,
- <computeroutput>ferror(f)</computeroutput>) is set. On
- receipt of <computeroutput>BZ_IO_ERROR</computeroutput>, the
- caller should consult <computeroutput>errno</computeroutput>
- and/or <computeroutput>perror</computeroutput> to acquire
- operating-system specific information about the
- problem.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_UNEXPECTED_EOF</computeroutput></term>
- <listitem><para>Returned by
- <computeroutput>BZ2_bzRead</computeroutput> when the
- compressed file finishes before the logical end of stream is
- detected.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>BZ_OUTBUFF_FULL</computeroutput></term>
- <listitem><para>Returned by
- <computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
- <computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> to
- indicate that the output data will not fit into the output
- buffer provided.</para></listitem>
- </varlistentry>
-
-</variablelist>
-
-</sect1>
-
-
-
-<sect1 id="low-level" xreflabel=">Low-level interface">
-<title>Low-level interface</title>
-
-
-<sect2 id="bzcompress-init" xreflabel="BZ2_bzCompressInit">
-<title><computeroutput>BZ2_bzCompressInit</computeroutput></title>
-
-<programlisting>
-typedef struct {
- char *next_in;
- unsigned int avail_in;
- unsigned int total_in_lo32;
- unsigned int total_in_hi32;
-
- char *next_out;
- unsigned int avail_out;
- unsigned int total_out_lo32;
- unsigned int total_out_hi32;
-
- void *state;
-
- void *(*bzalloc)(void *,int,int);
- void (*bzfree)(void *,void *);
- void *opaque;
-} bz_stream;
-
-int BZ2_bzCompressInit ( bz_stream *strm,
- int blockSize100k,
- int verbosity,
- int workFactor );
-</programlisting>
-
-<para>Prepares for compression. The
-<computeroutput>bz_stream</computeroutput> structure holds all
-data pertaining to the compression activity. A
-<computeroutput>bz_stream</computeroutput> structure should be
-allocated and initialised prior to the call. The fields of
-<computeroutput>bz_stream</computeroutput> comprise the entirety
-of the user-visible data. <computeroutput>state</computeroutput>
-is a pointer to the private data structures required for
-compression.</para>
-
-<para>Custom memory allocators are supported, via fields
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput>, and
-<computeroutput>opaque</computeroutput>. The value
-<computeroutput>opaque</computeroutput> is passed to as the first
-argument to all calls to <computeroutput>bzalloc</computeroutput>
-and <computeroutput>bzfree</computeroutput>, but is otherwise
-ignored by the library. The call <computeroutput>bzalloc (
-opaque, n, m )</computeroutput> is expected to return a pointer
-<computeroutput>p</computeroutput> to <computeroutput>n *
-m</computeroutput> bytes of memory, and <computeroutput>bzfree (
-opaque, p )</computeroutput> should free that memory.</para>
-
-<para>If you don't want to use a custom memory allocator, set
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput> and
-<computeroutput>opaque</computeroutput> to
-<computeroutput>NULL</computeroutput>, and the library will then
-use the standard <computeroutput>malloc</computeroutput> /
-<computeroutput>free</computeroutput> routines.</para>
-
-<para>Before calling
-<computeroutput>BZ2_bzCompressInit</computeroutput>, fields
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput> and
-<computeroutput>opaque</computeroutput> should be filled
-appropriately, as just described. Upon return, the internal
-state will have been allocated and initialised, and
-<computeroutput>total_in_lo32</computeroutput>,
-<computeroutput>total_in_hi32</computeroutput>,
-<computeroutput>total_out_lo32</computeroutput> and
-<computeroutput>total_out_hi32</computeroutput> will have been
-set to zero. These four fields are used by the library to inform
-the caller of the total amount of data passed into and out of the
-library, respectively. You should not try to change them. As of
-version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the <computeroutput>_hi32</computeroutput>
-fields to store the upper 32 bits of the count. So, for example,
-the total amount of data in is <computeroutput>(total_in_hi32
-&#60;&#60; 32) + total_in_lo32</computeroutput>.</para>
-
-<para>Parameter <computeroutput>blockSize100k</computeroutput>
-specifies the block size to be used for compression. It should
-be a value between 1 and 9 inclusive, and the actual block size
-used is 100000 x this figure. 9 gives the best compression but
-takes most memory.</para>
-
-<para>Parameter <computeroutput>verbosity</computeroutput> should
-be set to a number between 0 and 4 inclusive. 0 is silent, and
-greater numbers give increasingly verbose monitoring/debugging
-output. If the library has been compiled with
-<computeroutput>-DBZ_NO_STDIO</computeroutput>, no such output
-will appear for any verbosity setting.</para>
-
-<para>Parameter <computeroutput>workFactor</computeroutput>
-controls how the compression phase behaves when presented with
-worst case, highly repetitive, input data. If compression runs
-into difficulties caused by repetitive data, the library switches
-from the standard sorting algorithm to a fallback algorithm. The
-fallback is slower than the standard algorithm by perhaps a
-factor of three, but always behaves reasonably, no matter how bad
-the input.</para>
-
-<para>Lower values of <computeroutput>workFactor</computeroutput>
-reduce the amount of effort the standard algorithm will expend
-before resorting to the fallback. You should set this parameter
-carefully; too low, and many inputs will be handled by the
-fallback algorithm and so compress rather slowly, too high, and
-your average-to-worst case compression times can become very
-large. The default value of 30 gives reasonable behaviour over a
-wide range of circumstances.</para>
-
-<para>Allowable values range from 0 to 250 inclusive. 0 is a
-special case, equivalent to using the default value of 30.</para>
-
-<para>Note that the compressed output generated is the same
-regardless of whether or not the fallback algorithm is
-used.</para>
-
-<para>Be aware also that this parameter may disappear entirely in
-future versions of the library. In principle it should be
-possible to devise a good way to automatically choose which
-algorithm to use. Such a mechanism would render the parameter
-obsolete.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if strm is NULL
- or blockSize < 1 or blockSize > 9
- or verbosity < 0 or verbosity > 4
- or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR
- if not enough memory is available
-BZ_OK
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzCompress
- if BZ_OK is returned
- no specific action needed in case of error
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzCompress" xreflabel="BZ2_bzCompress">
-<title><computeroutput>BZ2_bzCompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzCompress ( bz_stream *strm, int action );
-</programlisting>
-
-<para>Provides more input and/or output buffer space for the
-library. The caller maintains input and output buffers, and
-calls <computeroutput>BZ2_bzCompress</computeroutput> to transfer
-data between them.</para>
-
-<para>Before each call to
-<computeroutput>BZ2_bzCompress</computeroutput>,
-<computeroutput>next_in</computeroutput> should point at the data
-to be compressed, and <computeroutput>avail_in</computeroutput>
-should indicate how many bytes the library may read.
-<computeroutput>BZ2_bzCompress</computeroutput> updates
-<computeroutput>next_in</computeroutput>,
-<computeroutput>avail_in</computeroutput> and
-<computeroutput>total_in</computeroutput> to reflect the number
-of bytes it has read.</para>
-
-<para>Similarly, <computeroutput>next_out</computeroutput> should
-point to a buffer in which the compressed data is to be placed,
-with <computeroutput>avail_out</computeroutput> indicating how
-much output space is available.
-<computeroutput>BZ2_bzCompress</computeroutput> updates
-<computeroutput>next_out</computeroutput>,
-<computeroutput>avail_out</computeroutput> and
-<computeroutput>total_out</computeroutput> to reflect the number
-of bytes output.</para>
-
-<para>You may provide and remove as little or as much data as you
-like on each call of
-<computeroutput>BZ2_bzCompress</computeroutput>. In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient. You should always
-ensure that at least one byte of output space is available at
-each call.</para>
-
-<para>A second purpose of
-<computeroutput>BZ2_bzCompress</computeroutput> is to request a
-change of mode of the compressed stream.</para>
-
-<para>Conceptually, a compressed stream can be in one of four
-states: IDLE, RUNNING, FLUSHING and FINISHING. Before
-initialisation
-(<computeroutput>BZ2_bzCompressInit</computeroutput>) and after
-termination (<computeroutput>BZ2_bzCompressEnd</computeroutput>),
-a stream is regarded as IDLE.</para>
-
-<para>Upon initialisation
-(<computeroutput>BZ2_bzCompressInit</computeroutput>), the stream
-is placed in the RUNNING state. Subsequent calls to
-<computeroutput>BZ2_bzCompress</computeroutput> should pass
-<computeroutput>BZ_RUN</computeroutput> as the requested action;
-other actions are illegal and will result in
-<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>.</para>
-
-<para>At some point, the calling program will have provided all
-the input data it wants to. It will then want to finish up -- in
-effect, asking the library to process any data it might have
-buffered internally. In this state,
-<computeroutput>BZ2_bzCompress</computeroutput> will no longer
-attempt to read data from
-<computeroutput>next_in</computeroutput>, but it will want to
-write data to <computeroutput>next_out</computeroutput>. Because
-the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a
-single call of
-<computeroutput>BZ2_bzCompress</computeroutput>.</para>
-
-<para>Instead, the calling program passes
-<computeroutput>BZ_FINISH</computeroutput> as an action to
-<computeroutput>BZ2_bzCompress</computeroutput>. This changes
-the stream's state to FINISHING. Any remaining input (ie,
-<computeroutput>next_in[0 .. avail_in-1]</computeroutput>) is
-compressed and transferred to the output buffer. To do this,
-<computeroutput>BZ2_bzCompress</computeroutput> must be called
-repeatedly until all the output has been consumed. At that
-point, <computeroutput>BZ2_bzCompress</computeroutput> returns
-<computeroutput>BZ_STREAM_END</computeroutput>, and the stream's
-state is set back to IDLE.
-<computeroutput>BZ2_bzCompressEnd</computeroutput> should then be
-called.</para>
-
-<para>Just to make sure the calling program does not cheat, the
-library makes a note of <computeroutput>avail_in</computeroutput>
-at the time of the first call to
-<computeroutput>BZ2_bzCompress</computeroutput> which has
-<computeroutput>BZ_FINISH</computeroutput> as an action (ie, at
-the time the program has announced its intention to not supply
-any more input). By comparing this value with that of
-<computeroutput>avail_in</computeroutput> over subsequent calls
-to <computeroutput>BZ2_bzCompress</computeroutput>, the library
-can detect any attempts to slip in more data to compress. Any
-calls for which this is detected will return
-<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>. This
-indicates a programming mistake which should be corrected.</para>
-
-<para>Instead of asking to finish, the calling program may ask
-<computeroutput>BZ2_bzCompress</computeroutput> to take all the
-remaining input, compress it and terminate the current
-(Burrows-Wheeler) compression block. This could be useful for
-error control purposes. The mechanism is analogous to that for
-finishing: call <computeroutput>BZ2_bzCompress</computeroutput>
-with an action of <computeroutput>BZ_FLUSH</computeroutput>,
-remove output data, and persist with the
-<computeroutput>BZ_FLUSH</computeroutput> action until the value
-<computeroutput>BZ_RUN</computeroutput> is returned. As with
-finishing, <computeroutput>BZ2_bzCompress</computeroutput>
-detects any attempt to provide more input data once the flush has
-begun.</para>
-
-<para>Once the flush is complete, the stream returns to the
-normal RUNNING state.</para>
-
-<para>This all sounds pretty complex, but isn't really. Here's a
-table which shows which actions are allowable in each state, what
-action will be taken, what the next state is, and what the
-non-error return values are. Note that you can't explicitly ask
-what state the stream is in, but nor do you need to -- it can be
-inferred from the values returned by
-<computeroutput>BZ2_bzCompress</computeroutput>.</para>
-
-<programlisting>
-IDLE/any
- Illegal. IDLE state only exists after BZ2_bzCompressEnd or
- before BZ2_bzCompressInit.
- Return value = BZ_SEQUENCE_ERROR
-
-RUNNING/BZ_RUN
- Compress from next_in to next_out as much as possible.
- Next state = RUNNING
- Return value = BZ_RUN_OK
-
-RUNNING/BZ_FLUSH
- Remember current value of next_in. Compress from next_in
- to next_out as much as possible, but do not accept any more input.
- Next state = FLUSHING
- Return value = BZ_FLUSH_OK
-
-RUNNING/BZ_FINISH
- Remember current value of next_in. Compress from next_in
- to next_out as much as possible, but do not accept any more input.
- Next state = FINISHING
- Return value = BZ_FINISH_OK
-
-FLUSHING/BZ_FLUSH
- Compress from next_in to next_out as much as possible,
- but do not accept any more input.
- If all the existing input has been used up and all compressed
- output has been removed
- Next state = RUNNING; Return value = BZ_RUN_OK
- else
- Next state = FLUSHING; Return value = BZ_FLUSH_OK
-
-FLUSHING/other
- Illegal.
- Return value = BZ_SEQUENCE_ERROR
-
-FINISHING/BZ_FINISH
- Compress from next_in to next_out as much as possible,
- but to not accept any more input.
- If all the existing input has been used up and all compressed
- output has been removed
- Next state = IDLE; Return value = BZ_STREAM_END
- else
- Next state = FINISHING; Return value = BZ_FINISHING
-
-FINISHING/other
- Illegal.
- Return value = BZ_SEQUENCE_ERROR
-</programlisting>
-
-
-<para>That still looks complicated? Well, fair enough. The
-usual sequence of calls for compressing a load of data is:</para>
-
-<orderedlist>
-
- <listitem><para>Get started with
- <computeroutput>BZ2_bzCompressInit</computeroutput>.</para></listitem>
-
- <listitem><para>Shovel data in and shlurp out its compressed form
- using zero or more calls of
- <computeroutput>BZ2_bzCompress</computeroutput> with action =
- <computeroutput>BZ_RUN</computeroutput>.</para></listitem>
-
- <listitem><para>Finish up. Repeatedly call
- <computeroutput>BZ2_bzCompress</computeroutput> with action =
- <computeroutput>BZ_FINISH</computeroutput>, copying out the
- compressed output, until
- <computeroutput>BZ_STREAM_END</computeroutput> is
- returned.</para></listitem> <listitem><para>Close up and go home. Call
- <computeroutput>BZ2_bzCompressEnd</computeroutput>.</para></listitem>
-
-</orderedlist>
-
-<para>If the data you want to compress fits into your input
-buffer all at once, you can skip the calls of
-<computeroutput>BZ2_bzCompress ( ..., BZ_RUN )</computeroutput>
-and just do the <computeroutput>BZ2_bzCompress ( ..., BZ_FINISH
-)</computeroutput> calls.</para>
-
-<para>All required memory is allocated by
-<computeroutput>BZ2_bzCompressInit</computeroutput>. The
-compression library can accept any data at all (obviously). So
-you shouldn't get any error return values from the
-<computeroutput>BZ2_bzCompress</computeroutput> calls. If you
-do, they will be
-<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, and indicate
-a bug in your programming.</para>
-
-<para>Trivial other possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
- if strm is NULL, or strm->s is NULL
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzCompress-end" xreflabel="BZ2_bzCompressEnd">
-<title><computeroutput>BZ2_bzCompressEnd</computeroutput></title>
-
-<programlisting>
-int BZ2_bzCompressEnd ( bz_stream *strm );
-</programlisting>
-
-<para>Releases all memory associated with a compression
-stream.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR if strm is NULL or strm->s is NULL
-BZ_OK otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzDecompress-init" xreflabel="BZ2_bzDecompressInit">
-<title><computeroutput>BZ2_bzDecompressInit</computeroutput></title>
-
-<programlisting>
-int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
-</programlisting>
-
-<para>Prepares for decompression. As with
-<computeroutput>BZ2_bzCompressInit</computeroutput>, a
-<computeroutput>bz_stream</computeroutput> record should be
-allocated and initialised before the call. Fields
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput> and
-<computeroutput>opaque</computeroutput> should be set if a custom
-memory allocator is required, or made
-<computeroutput>NULL</computeroutput> for the normal
-<computeroutput>malloc</computeroutput> /
-<computeroutput>free</computeroutput> routines. Upon return, the
-internal state will have been initialised, and
-<computeroutput>total_in</computeroutput> and
-<computeroutput>total_out</computeroutput> will be zero.</para>
-
-<para>For the meaning of parameter
-<computeroutput>verbosity</computeroutput>, see
-<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
-
-<para>If <computeroutput>small</computeroutput> is nonzero, the
-library will use an alternative decompression algorithm which
-uses less memory but at the cost of decompressing more slowly
-(roughly speaking, half the speed, but the maximum memory
-requirement drops to around 2300k). See <xref linkend="using"/>
-for more information on memory management.</para>
-
-<para>Note that the amount of memory needed to decompress a
-stream cannot be determined until the stream's header has been
-read, so even if
-<computeroutput>BZ2_bzDecompressInit</computeroutput> succeeds, a
-subsequent <computeroutput>BZ2_bzDecompress</computeroutput>
-could fail with
-<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if ( small != 0 && small != 1 )
- or (verbosity <; 0 || verbosity > 4)
-BZ_MEM_ERROR
- if insufficient memory is available
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzDecompress
- if BZ_OK was returned
- no specific action required in case of error
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzDecompress" xreflabel="BZ2_bzDecompress">
-<title><computeroutput>BZ2_bzDecompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzDecompress ( bz_stream *strm );
-</programlisting>
-
-<para>Provides more input and/out output buffer space for the
-library. The caller maintains input and output buffers, and uses
-<computeroutput>BZ2_bzDecompress</computeroutput> to transfer
-data between them.</para>
-
-<para>Before each call to
-<computeroutput>BZ2_bzDecompress</computeroutput>,
-<computeroutput>next_in</computeroutput> should point at the
-compressed data, and <computeroutput>avail_in</computeroutput>
-should indicate how many bytes the library may read.
-<computeroutput>BZ2_bzDecompress</computeroutput> updates
-<computeroutput>next_in</computeroutput>,
-<computeroutput>avail_in</computeroutput> and
-<computeroutput>total_in</computeroutput> to reflect the number
-of bytes it has read.</para>
-
-<para>Similarly, <computeroutput>next_out</computeroutput> should
-point to a buffer in which the uncompressed output is to be
-placed, with <computeroutput>avail_out</computeroutput>
-indicating how much output space is available.
-<computeroutput>BZ2_bzCompress</computeroutput> updates
-<computeroutput>next_out</computeroutput>,
-<computeroutput>avail_out</computeroutput> and
-<computeroutput>total_out</computeroutput> to reflect the number
-of bytes output.</para>
-
-<para>You may provide and remove as little or as much data as you
-like on each call of
-<computeroutput>BZ2_bzDecompress</computeroutput>. In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient. You should always
-ensure that at least one byte of output space is available at
-each call.</para>
-
-<para>Use of <computeroutput>BZ2_bzDecompress</computeroutput> is
-simpler than
-<computeroutput>BZ2_bzCompress</computeroutput>.</para>
-
-<para>You should provide input and remove output as described
-above, and repeatedly call
-<computeroutput>BZ2_bzDecompress</computeroutput> until
-<computeroutput>BZ_STREAM_END</computeroutput> is returned.
-Appearance of <computeroutput>BZ_STREAM_END</computeroutput>
-denotes that <computeroutput>BZ2_bzDecompress</computeroutput>
-has detected the logical end of the compressed stream.
-<computeroutput>BZ2_bzDecompress</computeroutput> will not
-produce <computeroutput>BZ_STREAM_END</computeroutput> until all
-output data has been placed into the output buffer, so once
-<computeroutput>BZ_STREAM_END</computeroutput> appears, you are
-guaranteed to have available all the decompressed output, and
-<computeroutput>BZ2_bzDecompressEnd</computeroutput> can safely
-be called.</para>
-
-<para>If case of an error return value, you should call
-<computeroutput>BZ2_bzDecompressEnd</computeroutput> to clean up
-and release memory.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
- if strm is NULL or strm->s is NULL
- or strm->avail_out < 1
-BZ_DATA_ERROR
- if a data integrity error is detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
- if the compressed stream doesn't begin with the right magic bytes
-BZ_MEM_ERROR
- if there wasn't enough memory available
-BZ_STREAM_END
- if the logical end of the data stream was detected and all
- output in has been consumed, eg s-->avail_out > 0
-BZ_OK
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzDecompress
- if BZ_OK was returned
-BZ2_bzDecompressEnd
- otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzDecompress-end" xreflabel="BZ2_bzDecompressEnd">
-<title><computeroutput>BZ2_bzDecompressEnd</computeroutput></title>
-
-<programlisting>
-int BZ2_bzDecompressEnd ( bz_stream *strm );
-</programlisting>
-
-<para>Releases all memory associated with a decompression
-stream.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
- if strm is NULL or strm->s is NULL
-BZ_OK
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
- None.
-</programlisting>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="hl-interface" xreflabel="High-level interface">
-<title>High-level interface</title>
-
-<para>This interface provides functions for reading and writing
-<computeroutput>bzip2</computeroutput> format files. First, some
-general points.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>All of the functions take an
- <computeroutput>int*</computeroutput> first argument,
- <computeroutput>bzerror</computeroutput>. After each call,
- <computeroutput>bzerror</computeroutput> should be consulted
- first to determine the outcome of the call. If
- <computeroutput>bzerror</computeroutput> is
- <computeroutput>BZ_OK</computeroutput>, the call completed
- successfully, and only then should the return value of the
- function (if any) be consulted. If
- <computeroutput>bzerror</computeroutput> is
- <computeroutput>BZ_IO_ERROR</computeroutput>, there was an
- error reading/writing the underlying compressed file, and you
- should then consult <computeroutput>errno</computeroutput> /
- <computeroutput>perror</computeroutput> to determine the cause
- of the difficulty. <computeroutput>bzerror</computeroutput>
- may also be set to various other values; precise details are
- given on a per-function basis below.</para></listitem>
-
- <listitem><para>If <computeroutput>bzerror</computeroutput> indicates
- an error (ie, anything except
- <computeroutput>BZ_OK</computeroutput> and
- <computeroutput>BZ_STREAM_END</computeroutput>), you should
- immediately call
- <computeroutput>BZ2_bzReadClose</computeroutput> (or
- <computeroutput>BZ2_bzWriteClose</computeroutput>, depending on
- whether you are attempting to read or to write) to free up all
- resources associated with the stream. Once an error has been
- indicated, behaviour of all calls except
- <computeroutput>BZ2_bzReadClose</computeroutput>
- (<computeroutput>BZ2_bzWriteClose</computeroutput>) is
- undefined. The implication is that (1)
- <computeroutput>bzerror</computeroutput> should be checked
- after each call, and (2) if
- <computeroutput>bzerror</computeroutput> indicates an error,
- <computeroutput>BZ2_bzReadClose</computeroutput>
- (<computeroutput>BZ2_bzWriteClose</computeroutput>) should then
- be called to clean up.</para></listitem>
-
- <listitem><para>The <computeroutput>FILE*</computeroutput> arguments
- passed to <computeroutput>BZ2_bzReadOpen</computeroutput> /
- <computeroutput>BZ2_bzWriteOpen</computeroutput> should be set
- to binary mode. Most Unix systems will do this by default, but
- other platforms, including Windows and Mac, will not. If you
- omit this, you may encounter problems when moving code to new
- platforms.</para></listitem>
-
- <listitem><para>Memory allocation requests are handled by
- <computeroutput>malloc</computeroutput> /
- <computeroutput>free</computeroutput>. At present there is no
- facility for user-defined memory allocators in the file I/O
- functions (could easily be added, though).</para></listitem>
-
-</itemizedlist>
-
-
-
-<sect2 id="bzreadopen" xreflabel="BZ2_bzReadOpen">
-<title><computeroutput>BZ2_bzReadOpen</computeroutput></title>
-
-<programlisting>
-typedef void BZFILE;
-
-BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f,
- int verbosity, int small,
- void *unused, int nUnused );
-</programlisting>
-
-<para>Prepare to read compressed data from file handle
-<computeroutput>f</computeroutput>.
-<computeroutput>f</computeroutput> should refer to a file which
-has been opened for reading, and for which the error indicator
-(<computeroutput>ferror(f)</computeroutput>)is not set. If
-<computeroutput>small</computeroutput> is 1, the library will try
-to decompress using less memory, at the expense of speed.</para>
-
-<para>For reasons explained below,
-<computeroutput>BZ2_bzRead</computeroutput> will decompress the
-<computeroutput>nUnused</computeroutput> bytes starting at
-<computeroutput>unused</computeroutput>, before starting to read
-from the file <computeroutput>f</computeroutput>. At most
-<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes may be
-supplied like this. If this facility is not required, you should
-pass <computeroutput>NULL</computeroutput> and
-<computeroutput>0</computeroutput> for
-<computeroutput>unused</computeroutput> and
-n<computeroutput>Unused</computeroutput> respectively.</para>
-
-<para>For the meaning of parameters
-<computeroutput>small</computeroutput> and
-<computeroutput>verbosity</computeroutput>, see
-<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
-
-<para>The amount of memory needed to decompress a file cannot be
-determined until the file's header has been read. So it is
-possible that <computeroutput>BZ2_bzReadOpen</computeroutput>
-returns <computeroutput>BZ_OK</computeroutput> but a subsequent
-call of <computeroutput>BZ2_bzRead</computeroutput> will return
-<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if f is NULL
- or small is neither 0 nor 1
- or ( unused == NULL && nUnused != 0 )
- or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
-BZ_IO_ERROR
- if ferror(f) is nonzero
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OK
- otherwise.
-</programlisting>
-
-<para>Possible return values:</para>
-
-<programlisting>
-Pointer to an abstract BZFILE
- if bzerror is BZ_OK
-NULL
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzRead
- if bzerror is BZ_OK
-BZ2_bzClose
- otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzread" xreflabel="BZ2_bzRead">
-<title><computeroutput>BZ2_bzRead</computeroutput></title>
-
-<programlisting>
-int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
-</programlisting>
-
-<para>Reads up to <computeroutput>len</computeroutput>
-(uncompressed) bytes from the compressed file
-<computeroutput>b</computeroutput> into the buffer
-<computeroutput>buf</computeroutput>. If the read was
-successful, <computeroutput>bzerror</computeroutput> is set to
-<computeroutput>BZ_OK</computeroutput> and the number of bytes
-read is returned. If the logical end-of-stream was detected,
-<computeroutput>bzerror</computeroutput> will be set to
-<computeroutput>BZ_STREAM_END</computeroutput>, and the number of
-bytes read is returned. All other
-<computeroutput>bzerror</computeroutput> values denote an
-error.</para>
-
-<para><computeroutput>BZ2_bzRead</computeroutput> will supply
-<computeroutput>len</computeroutput> bytes, unless the logical
-stream end is detected or an error occurs. Because of this, it
-is possible to detect the stream end by observing when the number
-of bytes returned is less than the number requested.
-Nevertheless, this is regarded as inadvisable; you should instead
-check <computeroutput>bzerror</computeroutput> after every call
-and watch out for
-<computeroutput>BZ_STREAM_END</computeroutput>.</para>
-
-<para>Internally, <computeroutput>BZ2_bzRead</computeroutput>
-copies data from the compressed file in chunks of size
-<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes before
-decompressing it. If the file contains more bytes than strictly
-needed to reach the logical end-of-stream,
-<computeroutput>BZ2_bzRead</computeroutput> will almost certainly
-read some of the trailing data before signalling
-<computeroutput>BZ_SEQUENCE_END</computeroutput>. To collect the
-read but unused data once
-<computeroutput>BZ_SEQUENCE_END</computeroutput> has appeared,
-call <computeroutput>BZ2_bzReadGetUnused</computeroutput>
-immediately before
-<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
- if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzWriteOpen
-BZ_IO_ERROR
- if there is an error reading from the compressed file
-BZ_UNEXPECTED_EOF
- if the compressed file ended before
- the logical end-of-stream was detected
-BZ_DATA_ERROR
- if a data integrity error was detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
- if the stream does not begin with the requisite header bytes
- (ie, is not a bzip2 data file). This is really
- a special case of BZ_DATA_ERROR.
-BZ_MEM_ERROR
- if insufficient memory was available
-BZ_STREAM_END
- if the logical end of stream was detected.
-BZ_OK
- otherwise.
-</programlisting>
-
-<para>Possible return values:</para>
-
-<programlisting>
-number of bytes read
- if bzerror is BZ_OK or BZ_STREAM_END
-undefined
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
- if bzerror is BZ_OK
-collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
- if bzerror is BZ_SEQUENCE_END
-BZ2_bzReadClose
- otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzreadgetunused" xreflabel="BZ2_bzReadGetUnused">
-<title><computeroutput>BZ2_bzReadGetUnused</computeroutput></title>
-
-<programlisting>
-void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b,
- void** unused, int* nUnused );
-</programlisting>
-
-<para>Returns data which was read from the compressed file but
-was not needed to get to the logical end-of-stream.
-<computeroutput>*unused</computeroutput> is set to the address of
-the data, and <computeroutput>*nUnused</computeroutput> to the
-number of bytes. <computeroutput>*nUnused</computeroutput> will
-be set to a value between <computeroutput>0</computeroutput> and
-<computeroutput>BZ_MAX_UNUSED</computeroutput> inclusive.</para>
-
-<para>This function may only be called once
-<computeroutput>BZ2_bzRead</computeroutput> has signalled
-<computeroutput>BZ_STREAM_END</computeroutput> but before
-<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
- if b is NULL
- or unused is NULL or nUnused is NULL
-BZ_SEQUENCE_ERROR
- if BZ_STREAM_END has not been signalled
- or if b was opened with BZ2_bzWriteOpen
-BZ_OK
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzReadClose
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzreadclose" xreflabel="BZ2_bzReadClose">
-<title><computeroutput>BZ2_bzReadClose</computeroutput></title>
-
-<programlisting>
-void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
-</programlisting>
-
-<para>Releases all memory pertaining to the compressed file
-<computeroutput>b</computeroutput>.
-<computeroutput>BZ2_bzReadClose</computeroutput> does not call
-<computeroutput>fclose</computeroutput> on the underlying file
-handle, so you should do that yourself if appropriate.
-<computeroutput>BZ2_bzReadClose</computeroutput> should be called
-to clean up after all error situations.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzOpenWrite
-BZ_OK
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-none
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzwriteopen" xreflabel="BZ2_bzWriteOpen">
-<title><computeroutput>BZ2_bzWriteOpen</computeroutput></title>
-
-<programlisting>
-BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f,
- int blockSize100k, int verbosity,
- int workFactor );
-</programlisting>
-
-<para>Prepare to write compressed data to file handle
-<computeroutput>f</computeroutput>.
-<computeroutput>f</computeroutput> should refer to a file which
-has been opened for writing, and for which the error indicator
-(<computeroutput>ferror(f)</computeroutput>)is not set.</para>
-
-<para>For the meaning of parameters
-<computeroutput>blockSize100k</computeroutput>,
-<computeroutput>verbosity</computeroutput> and
-<computeroutput>workFactor</computeroutput>, see
-<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
-
-<para>All required memory is allocated at this stage, so if the
-call completes successfully,
-<computeroutput>BZ_MEM_ERROR</computeroutput> cannot be signalled
-by a subsequent call to
-<computeroutput>BZ2_bzWrite</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if f is NULL
- or blockSize100k < 1 or blockSize100k > 9
-BZ_IO_ERROR
- if ferror(f) is nonzero
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OK
- otherwise
-</programlisting>
-
-<para>Possible return values:</para>
-
-<programlisting>
-Pointer to an abstract BZFILE
- if bzerror is BZ_OK
-NULL
- otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzWrite
- if bzerror is BZ_OK
- (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
-BZ2_bzWriteClose
- otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzwrite" xreflabel="BZ2_bzWrite">
-<title><computeroutput>BZ2_bzWrite</computeroutput></title>
-
-<programlisting>
-void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
-</programlisting>
-
-<para>Absorbs <computeroutput>len</computeroutput> bytes from the
-buffer <computeroutput>buf</computeroutput>, eventually to be
-compressed and written to the file.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
- if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
- if there is an error writing the compressed file.
-BZ_OK
- otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzwriteclose" xreflabel="BZ2_bzWriteClose">
-<title><computeroutput>BZ2_bzWriteClose</computeroutput></title>
-
-<programlisting>
-void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out );
-
-void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32 );
-</programlisting>
-
-<para>Compresses and flushes to the compressed file all data so
-far supplied by <computeroutput>BZ2_bzWrite</computeroutput>.
-The logical end-of-stream markers are also written, so subsequent
-calls to <computeroutput>BZ2_bzWrite</computeroutput> are
-illegal. All memory associated with the compressed file
-<computeroutput>b</computeroutput> is released.
-<computeroutput>fflush</computeroutput> is called on the
-compressed file, but it is not
-<computeroutput>fclose</computeroutput>'d.</para>
-
-<para>If <computeroutput>BZ2_bzWriteClose</computeroutput> is
-called to clean up after an error, the only action is to release
-the memory. The library records the error codes issued by
-previous calls, so this situation will be detected automatically.
-There is no attempt to complete the compression operation, nor to
-<computeroutput>fflush</computeroutput> the compressed file. You
-can force this behaviour to happen even in the case of no error,
-by passing a nonzero value to
-<computeroutput>abandon</computeroutput>.</para>
-
-<para>If <computeroutput>nbytes_in</computeroutput> is non-null,
-<computeroutput>*nbytes_in</computeroutput> will be set to be the
-total volume of uncompressed data handled. Similarly,
-<computeroutput>nbytes_out</computeroutput> will be set to the
-total volume of compressed data written. For compatibility with
-older versions of the library,
-<computeroutput>BZ2_bzWriteClose</computeroutput> only yields the
-lower 32 bits of these counts. Use
-<computeroutput>BZ2_bzWriteClose64</computeroutput> if you want
-the full 64 bit counts. These two functions are otherwise
-absolutely identical.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_SEQUENCE_ERROR
- if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
- if there is an error writing the compressed file
-BZ_OK
- otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="embed" xreflabel="Handling embedded compressed data streams">
-<title>Handling embedded compressed data streams</title>
-
-<para>The high-level library facilitates use of
-<computeroutput>bzip2</computeroutput> data streams which form
-some part of a surrounding, larger data stream.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>For writing, the library takes an open file handle,
- writes compressed data to it,
- <computeroutput>fflush</computeroutput>es it but does not
- <computeroutput>fclose</computeroutput> it. The calling
- application can write its own data before and after the
- compressed data stream, using that same file handle.</para></listitem>
-
- <listitem><para>Reading is more complex, and the facilities are not as
- general as they could be since generality is hard to reconcile
- with efficiency. <computeroutput>BZ2_bzRead</computeroutput>
- reads from the compressed file in blocks of size
- <computeroutput>BZ_MAX_UNUSED</computeroutput> bytes, and in
- doing so probably will overshoot the logical end of compressed
- stream. To recover this data once decompression has ended,
- call <computeroutput>BZ2_bzReadGetUnused</computeroutput> after
- the last call of <computeroutput>BZ2_bzRead</computeroutput>
- (the one returning
- <computeroutput>BZ_STREAM_END</computeroutput>) but before
- calling
- <computeroutput>BZ2_bzReadClose</computeroutput>.</para></listitem>
-
-</itemizedlist>
-
-<para>This mechanism makes it easy to decompress multiple
-<computeroutput>bzip2</computeroutput> streams placed end-to-end.
-As the end of one stream, when
-<computeroutput>BZ2_bzRead</computeroutput> returns
-<computeroutput>BZ_STREAM_END</computeroutput>, call
-<computeroutput>BZ2_bzReadGetUnused</computeroutput> to collect
-the unused data (copy it into your own buffer somewhere). That
-data forms the start of the next compressed stream. To start
-uncompressing that next stream, call
-<computeroutput>BZ2_bzReadOpen</computeroutput> again, feeding in
-the unused data via the <computeroutput>unused</computeroutput> /
-<computeroutput>nUnused</computeroutput> parameters. Keep doing
-this until <computeroutput>BZ_STREAM_END</computeroutput> return
-coincides with the physical end of file
-(<computeroutput>feof(f)</computeroutput>). In this situation
-<computeroutput>BZ2_bzReadGetUnused</computeroutput> will of
-course return no data.</para>
-
-<para>This should give some feel for how the high-level interface
-can be used. If you require extra flexibility, you'll have to
-bite the bullet and get to grips with the low-level
-interface.</para>
-
-</sect2>
-
-
-<sect2 id="std-rdwr" xreflabel="Standard file-reading/writing code">
-<title>Standard file-reading/writing code</title>
-
-<para>Here's how you'd write data to a compressed file:</para>
-
-<programlisting>
-FILE* f;
-BZFILE* b;
-int nBuf;
-char buf[ /* whatever size you like */ ];
-int bzerror;
-int nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzWriteOpen( &bzerror, f, 9 );
-if (bzerror != BZ_OK) {
- BZ2_bzWriteClose ( b );
- /* handle error */
-}
-
-while ( /* condition */ ) {
- /* get data to write into buf, and set nBuf appropriately */
- nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
- if (bzerror == BZ_IO_ERROR) {
- BZ2_bzWriteClose ( &bzerror, b );
- /* handle error */
- }
-}
-
-BZ2_bzWriteClose( &bzerror, b );
-if (bzerror == BZ_IO_ERROR) {
- /* handle error */
-}
-</programlisting>
-
-<para>And to read from a compressed file:</para>
-
-<programlisting>
-FILE* f;
-BZFILE* b;
-int nBuf;
-char buf[ /* whatever size you like */ ];
-int bzerror;
-int nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
-if ( bzerror != BZ_OK ) {
- BZ2_bzReadClose ( &bzerror, b );
- /* handle error */
-}
-
-bzerror = BZ_OK;
-while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
- nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
- if ( bzerror == BZ_OK ) {
- /* do something with buf[0 .. nBuf-1] */
- }
-}
-if ( bzerror != BZ_STREAM_END ) {
- BZ2_bzReadClose ( &bzerror, b );
- /* handle error */
-} else {
- BZ2_bzReadClose ( &bzerror );
-}
-</programlisting>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="util-fns" xreflabel="Utility functions">
-<title>Utility functions</title>
-
-
-<sect2 id="bzbufftobuffcompress" xreflabel="BZ2_bzBuffToBuffCompress">
-<title><computeroutput>BZ2_bzBuffToBuffCompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzBuffToBuffCompress( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor );
-</programlisting>
-
-<para>Attempts to compress the data in <computeroutput>source[0
-.. sourceLen-1]</computeroutput> into the destination buffer,
-<computeroutput>dest[0 .. *destLen-1]</computeroutput>. If the
-destination buffer is big enough,
-<computeroutput>*destLen</computeroutput> is set to the size of
-the compressed data, and <computeroutput>BZ_OK</computeroutput>
-is returned. If the compressed data won't fit,
-<computeroutput>*destLen</computeroutput> is unchanged, and
-<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
-returned.</para>
-
-<para>Compression in this manner is a one-shot event, done with a
-single call to this function. The resulting compressed data is a
-complete <computeroutput>bzip2</computeroutput> format data
-stream. There is no mechanism for making additional calls to
-provide extra input data. If you want that kind of mechanism,
-use the low-level interface.</para>
-
-<para>For the meaning of parameters
-<computeroutput>blockSize100k</computeroutput>,
-<computeroutput>verbosity</computeroutput> and
-<computeroutput>workFactor</computeroutput>, see
-<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
-
-<para>To guarantee that the compressed data will fit in its
-buffer, allocate an output buffer of size 1% larger than the
-uncompressed data, plus six hundred extra bytes.</para>
-
-<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
-will not write data at or beyond
-<computeroutput>dest[*destLen]</computeroutput>, even in case of
-buffer overflow.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if dest is NULL or destLen is NULL
- or blockSize100k < 1 or blockSize100k > 9
- or verbosity < 0 or verbosity > 4
- or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OUTBUFF_FULL
- if the size of the compressed data exceeds *destLen
-BZ_OK
- otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzbufftobuffdecompress" xreflabel="BZ2_bzBuffToBuffDecompress">
-<title><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzBuffToBuffDecompress( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity );
-</programlisting>
-
-<para>Attempts to decompress the data in <computeroutput>source[0
-.. sourceLen-1]</computeroutput> into the destination buffer,
-<computeroutput>dest[0 .. *destLen-1]</computeroutput>. If the
-destination buffer is big enough,
-<computeroutput>*destLen</computeroutput> is set to the size of
-the uncompressed data, and <computeroutput>BZ_OK</computeroutput>
-is returned. If the compressed data won't fit,
-<computeroutput>*destLen</computeroutput> is unchanged, and
-<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
-returned.</para>
-
-<para><computeroutput>source</computeroutput> is assumed to hold
-a complete <computeroutput>bzip2</computeroutput> format data
-stream.
-<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> tries
-to decompress the entirety of the stream into the output
-buffer.</para>
-
-<para>For the meaning of parameters
-<computeroutput>small</computeroutput> and
-<computeroutput>verbosity</computeroutput>, see
-<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
-
-<para>Because the compression ratio of the compressed data cannot
-be known in advance, there is no easy way to guarantee that the
-output buffer will be big enough. You may of course make
-arrangements in your code to record the size of the uncompressed
-data, but such a mechanism is beyond the scope of this
-library.</para>
-
-<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
-will not write data at or beyond
-<computeroutput>dest[*destLen]</computeroutput>, even in case of
-buffer overflow.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
- if the library has been mis-compiled
-BZ_PARAM_ERROR
- if dest is NULL or destLen is NULL
- or small != 0 && small != 1
- or verbosity < 0 or verbosity > 4
-BZ_MEM_ERROR
- if insufficient memory is available
-BZ_OUTBUFF_FULL
- if the size of the compressed data exceeds *destLen
-BZ_DATA_ERROR
- if a data integrity error was detected in the compressed data
-BZ_DATA_ERROR_MAGIC
- if the compressed data doesn't begin with the right magic bytes
-BZ_UNEXPECTED_EOF
- if the compressed data ends unexpectedly
-BZ_OK
- otherwise
-</programlisting>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="zlib-compat" xreflabel="zlib compatibility functions">
-<title><computeroutput>zlib</computeroutput> compatibility functions</title>
-
-<para>Yoshioka Tsuneo has contributed some functions to give
-better <computeroutput>zlib</computeroutput> compatibility.
-These functions are <computeroutput>BZ2_bzopen</computeroutput>,
-<computeroutput>BZ2_bzread</computeroutput>,
-<computeroutput>BZ2_bzwrite</computeroutput>,
-<computeroutput>BZ2_bzflush</computeroutput>,
-<computeroutput>BZ2_bzclose</computeroutput>,
-<computeroutput>BZ2_bzerror</computeroutput> and
-<computeroutput>BZ2_bzlibVersion</computeroutput>. These
-functions are not (yet) officially part of the library. If they
-break, you get to keep all the pieces. Nevertheless, I think
-they work ok.</para>
-
-<programlisting>
-typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );
-</programlisting>
-
-<para>Returns a string indicating the library version.</para>
-
-<programlisting>
-BZFILE * BZ2_bzopen ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int fd, const char *mode );
-</programlisting>
-
-<para>Opens a <computeroutput>.bz2</computeroutput> file for
-reading or writing, using either its name or a pre-existing file
-descriptor. Analogous to <computeroutput>fopen</computeroutput>
-and <computeroutput>fdopen</computeroutput>.</para>
-
-<programlisting>
-int BZ2_bzread ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
-</programlisting>
-
-<para>Reads/writes data from/to a previously opened
-<computeroutput>BZFILE</computeroutput>. Analogous to
-<computeroutput>fread</computeroutput> and
-<computeroutput>fwrite</computeroutput>.</para>
-
-<programlisting>
-int BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );
-</programlisting>
-
-<para>Flushes/closes a <computeroutput>BZFILE</computeroutput>.
-<computeroutput>BZ2_bzflush</computeroutput> doesn't actually do
-anything. Analogous to <computeroutput>fflush</computeroutput>
-and <computeroutput>fclose</computeroutput>.</para>
-
-<programlisting>
-const char * BZ2_bzerror ( BZFILE *b, int *errnum )
-</programlisting>
-
-<para>Returns a string describing the more recent error status of
-<computeroutput>b</computeroutput>, and also sets
-<computeroutput>*errnum</computeroutput> to its numerical
-value.</para>
-
-</sect1>
-
-
-<sect1 id="stdio-free"
- xreflabel="Using the library in a stdio-free environment">
-<title>Using the library in a <computeroutput>stdio</computeroutput>-free environment</title>
-
-
-<sect2 id="stdio-bye" xreflabel="Getting rid of stdio">
-<title>Getting rid of <computeroutput>stdio</computeroutput></title>
-
-<para>In a deeply embedded application, you might want to use
-just the memory-to-memory functions. You can do this
-conveniently by compiling the library with preprocessor symbol
-<computeroutput>BZ_NO_STDIO</computeroutput> defined. Doing this
-gives you a library containing only the following eight
-functions:</para>
-
-<para><computeroutput>BZ2_bzCompressInit</computeroutput>,
-<computeroutput>BZ2_bzCompress</computeroutput>,
-<computeroutput>BZ2_bzCompressEnd</computeroutput>
-<computeroutput>BZ2_bzDecompressInit</computeroutput>,
-<computeroutput>BZ2_bzDecompress</computeroutput>,
-<computeroutput>BZ2_bzDecompressEnd</computeroutput>
-<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput>,
-<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput></para>
-
-<para>When compiled like this, all functions will ignore
-<computeroutput>verbosity</computeroutput> settings.</para>
-
-</sect2>
-
-
-<sect2 id="critical-error" xreflabel="Critical error handling">
-<title>Critical error handling</title>
-
-<para><computeroutput>libbzip2</computeroutput> contains a number
-of internal assertion checks which should, needless to say, never
-be activated. Nevertheless, if an assertion should fail,
-behaviour depends on whether or not the library was compiled with
-<computeroutput>BZ_NO_STDIO</computeroutput> set.</para>
-
-<para>For a normal compile, an assertion failure yields the
-message:</para>
-
-<blockquote>
-<para>bzip2/libbzip2: internal error number N.</para>
-<para>This is a bug in bzip2/libbzip2, &bz-version; of &bz-date;.
-Please report it to me at: &bz-email;. If this happened
-when you were using some program which uses libbzip2 as a
-component, you should also report this bug to the author(s)
-of that program. Please make an effort to report this bug;
-timely and accurate bug reports eventually lead to higher
-quality software. Thanks. Julian Seward, &bz-date;.
-</para></blockquote>
-
-<para>where <computeroutput>N</computeroutput> is some error code
-number. If <computeroutput>N == 1007</computeroutput>, it also
-prints some extra text advising the reader that unreliable memory
-is often associated with internal error 1007. (This is a
-frequently-observed-phenomenon with versions 1.0.0/1.0.1).</para>
-
-<para><computeroutput>exit(3)</computeroutput> is then
-called.</para>
-
-<para>For a <computeroutput>stdio</computeroutput>-free library,
-assertion failures result in a call to a function declared
-as:</para>
-
-<programlisting>
-extern void bz_internal_error ( int errcode );
-</programlisting>
-
-<para>The relevant code is passed as a parameter. You should
-supply such a function.</para>
-
-<para>In either case, once an assertion failure has occurred, any
-<computeroutput>bz_stream</computeroutput> records involved can
-be regarded as invalid. You should not attempt to resume normal
-operation with them.</para>
-
-<para>You may, of course, change critical error handling to suit
-your needs. As I said above, critical errors indicate bugs in
-the library and should not occur. All "normal" error situations
-are indicated via error return codes from functions, and can be
-recovered from.</para>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="win-dll" xreflabel="Making a Windows DLL">
-<title>Making a Windows DLL</title>
-
-<para>Everything related to Windows has been contributed by
-Yoshioka Tsuneo
-(<computeroutput>QWF00133@niftyserve.or.jp</computeroutput> /
-<computeroutput>tsuneo-y@is.aist-nara.ac.jp</computeroutput>), so
-you should send your queries to him (but perhaps Cc: me,
-<computeroutput>&bz-email;</computeroutput>).</para>
-
-<para>My vague understanding of what to do is: using Visual C++
-5.0, open the project file
-<computeroutput>libbz2.dsp</computeroutput>, and build. That's
-all.</para>
-
-<para>If you can't open the project file for some reason, make a
-new one, naming these files:
-<computeroutput>blocksort.c</computeroutput>,
-<computeroutput>bzlib.c</computeroutput>,
-<computeroutput>compress.c</computeroutput>,
-<computeroutput>crctable.c</computeroutput>,
-<computeroutput>decompress.c</computeroutput>,
-<computeroutput>huffman.c</computeroutput>,
-<computeroutput>randtable.c</computeroutput> and
-<computeroutput>libbz2.def</computeroutput>. You will also need
-to name the header files <computeroutput>bzlib.h</computeroutput>
-and <computeroutput>bzlib_private.h</computeroutput>.</para>
-
-<para>If you don't use VC++, you may need to define the
-proprocessor symbol
-<computeroutput>_WIN32</computeroutput>.</para>
-
-<para>Finally, <computeroutput>dlltest.c</computeroutput> is a
-sample program using the DLL. It has a project file,
-<computeroutput>dlltest.dsp</computeroutput>.</para>
-
-<para>If you just want a makefile for Visual C, have a look at
-<computeroutput>makefile.msc</computeroutput>.</para>
-
-<para>Be aware that if you compile
-<computeroutput>bzip2</computeroutput> itself on Win32, you must
-set <computeroutput>BZ_UNIX</computeroutput> to 0 and
-<computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the file
-<computeroutput>bzip2.c</computeroutput>, before compiling.
-Otherwise the resulting binary won't work correctly.</para>
-
-<para>I haven't tried any of this stuff myself, but it all looks
-plausible.</para>
-
-</sect1>
-
-</chapter>
-
-
-
-<chapter id="misc" xreflabel="Miscellanea">
-<title>Miscellanea</title>
-
-<para>These are just some random thoughts of mine. Your mileage
-may vary.</para>
-
-
-<sect1 id="limits" xreflabel="Limitations of the compressed file format">
-<title>Limitations of the compressed file format</title>
-
-<para><computeroutput>bzip2-1.0.X</computeroutput>,
-<computeroutput>0.9.5</computeroutput> and
-<computeroutput>0.9.0</computeroutput> use exactly the same file
-format as the original version,
-<computeroutput>bzip2-0.1</computeroutput>. This decision was
-made in the interests of stability. Creating yet another
-incompatible compressed file format would create further
-confusion and disruption for users.</para>
-
-<para>Nevertheless, this is not a painless decision. Development
-work since the release of
-<computeroutput>bzip2-0.1</computeroutput> in August 1997 has
-shown complexities in the file format which slow down
-decompression and, in retrospect, are unnecessary. These
-are:</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>The run-length encoder, which is the first of the
- compression transformations, is entirely irrelevant. The
- original purpose was to protect the sorting algorithm from the
- very worst case input: a string of repeated symbols. But
- algorithm steps Q6a and Q6b in the original Burrows-Wheeler
- technical report (SRC-124) show how repeats can be handled
- without difficulty in block sorting.</para></listitem>
-
- <listitem><para>The randomisation mechanism doesn't really need to be
- there. Udi Manber and Gene Myers published a suffix array
- construction algorithm a few years back, which can be employed
- to sort any block, no matter how repetitive, in O(N log N)
- time. Subsequent work by Kunihiko Sadakane has produced a
- derivative O(N (log N)^2) algorithm which usually outperforms
- the Manber-Myers algorithm.</para>
-
- <para>I could have changed to Sadakane's algorithm, but I find
- it to be slower than <computeroutput>bzip2</computeroutput>'s
- existing algorithm for most inputs, and the randomisation
- mechanism protects adequately against bad cases. I didn't
- think it was a good tradeoff to make. Partly this is due to
- the fact that I was not flooded with email complaints about
- <computeroutput>bzip2-0.1</computeroutput>'s performance on
- repetitive data, so perhaps it isn't a problem for real
- inputs.</para>
-
- <para>Probably the best long-term solution, and the one I have
- incorporated into 0.9.5 and above, is to use the existing
- sorting algorithm initially, and fall back to a O(N (log N)^2)
- algorithm if the standard algorithm gets into
- difficulties.</para></listitem>
-
- <listitem><para>The compressed file format was never designed to be
- handled by a library, and I have had to jump though some hoops
- to produce an efficient implementation of decompression. It's
- a bit hairy. Try passing
- <computeroutput>decompress.c</computeroutput> through the C
- preprocessor and you'll see what I mean. Much of this
- complexity could have been avoided if the compressed size of
- each block of data was recorded in the data stream.</para></listitem>
-
- <listitem><para>An Adler-32 checksum, rather than a CRC32 checksum,
- would be faster to compute.</para></listitem>
-
-</itemizedlist>
-
-<para>It would be fair to say that the
-<computeroutput>bzip2</computeroutput> format was frozen before I
-properly and fully understood the performance consequences of
-doing so.</para>
-
-<para>Improvements which I was able to incorporate into 0.9.0,
-despite using the same file format, are:</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>Single array implementation of the inverse BWT. This
- significantly speeds up decompression, presumably because it
- reduces the number of cache misses.</para></listitem>
-
- <listitem><para>Faster inverse MTF transform for large MTF values.
- The new implementation is based on the notion of sliding blocks
- of values.</para></listitem>
-
- <listitem><para><computeroutput>bzip2-0.9.0</computeroutput> now reads
- and writes files with <computeroutput>fread</computeroutput>
- and <computeroutput>fwrite</computeroutput>; version 0.1 used
- <computeroutput>putc</computeroutput> and
- <computeroutput>getc</computeroutput>. Duh! Well, you live
- and learn.</para></listitem>
-
-</itemizedlist>
-
-<para>Further ahead, it would be nice to be able to do random
-access into files. This will require some careful design of
-compressed file formats.</para>
-
-</sect1>
-
-
-<sect1 id="port-issues" xreflabel="Portability issues">
-<title>Portability issues</title>
-
-<para>After some consideration, I have decided not to use GNU
-<computeroutput>autoconf</computeroutput> to configure 0.9.5 or
-1.0.</para>
-
-<para><computeroutput>autoconf</computeroutput>, admirable and
-wonderful though it is, mainly assists with portability problems
-between Unix-like platforms. But
-<computeroutput>bzip2</computeroutput> doesn't have much in the
-way of portability problems on Unix; most of the difficulties
-appear when porting to the Mac, or to Microsoft's operating
-systems. <computeroutput>autoconf</computeroutput> doesn't help
-in those cases, and brings in a whole load of new
-complexity.</para>
-
-<para>Most people should be able to compile the library and
-program under Unix straight out-of-the-box, so to speak,
-especially if you have a version of GNU C available.</para>
-
-<para>There are a couple of
-<computeroutput>__inline__</computeroutput> directives in the
-code. GNU C (<computeroutput>gcc</computeroutput>) should be
-able to handle them. If you're not using GNU C, your C compiler
-shouldn't see them at all. If your compiler does, for some
-reason, see them and doesn't like them, just
-<computeroutput>#define</computeroutput>
-<computeroutput>__inline__</computeroutput> to be
-<computeroutput>/* */</computeroutput>. One easy way to do this
-is to compile with the flag
-<computeroutput>-D__inline__=</computeroutput>, which should be
-understood by most Unix compilers.</para>
-
-<para>If you still have difficulties, try compiling with the
-macro <computeroutput>BZ_STRICT_ANSI</computeroutput> defined.
-This should enable you to build the library in a strictly ANSI
-compliant environment. Building the program itself like this is
-dangerous and not supported, since you remove
-<computeroutput>bzip2</computeroutput>'s checks against
-compressing directories, symbolic links, devices, and other
-not-really-a-file entities. This could cause filesystem
-corruption!</para>
-
-<para>One other thing: if you create a
-<computeroutput>bzip2</computeroutput> binary for public distribution,
-please consider linking it statically (<computeroutput>gcc
--static</computeroutput>). This avoids all sorts of library-version
-issues that others may encounter later on.</para>
-
-<para>If you build <computeroutput>bzip2</computeroutput> on
-Win32, you must set <computeroutput>BZ_UNIX</computeroutput> to 0
-and <computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the
-file <computeroutput>bzip2.c</computeroutput>, before compiling.
-Otherwise the resulting binary won't work correctly.</para>
-
-</sect1>
-
-
-<sect1 id="bugs" xreflabel="Reporting bugs">
-<title>Reporting bugs</title>
-
-<para>I tried pretty hard to make sure
-<computeroutput>bzip2</computeroutput> is bug free, both by
-design and by testing. Hopefully you'll never need to read this
-section for real.</para>
-
-<para>Nevertheless, if <computeroutput>bzip2</computeroutput> dies
-with a segmentation fault, a bus error or an internal assertion
-failure, it will ask you to email me a bug report. Experience from
-years of feedback of bzip2 users indicates that almost all these
-problems can be traced to either compiler bugs or hardware
-problems.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>Recompile the program with no optimisation, and
- see if it works. And/or try a different compiler. I heard all
- sorts of stories about various flavours of GNU C (and other
- compilers) generating bad code for
- <computeroutput>bzip2</computeroutput>, and I've run across two
- such examples myself.</para>
-
- <para>2.7.X versions of GNU C are known to generate bad code
- from time to time, at high optimisation levels. If you get
- problems, try using the flags
- <computeroutput>-O2</computeroutput>
- <computeroutput>-fomit-frame-pointer</computeroutput>
- <computeroutput>-fno-strength-reduce</computeroutput>. You
- should specifically <emphasis>not</emphasis> use
- <computeroutput>-funroll-loops</computeroutput>.</para>
-
- <para>You may notice that the Makefile runs six tests as part
- of the build process. If the program passes all of these, it's
- a pretty good (but not 100%) indication that the compiler has
- done its job correctly.</para></listitem>
-
- <listitem><para>If <computeroutput>bzip2</computeroutput>
- crashes randomly, and the crashes are not repeatable, you may
- have a flaky memory subsystem.
- <computeroutput>bzip2</computeroutput> really hammers your
- memory hierarchy, and if it's a bit marginal, you may get these
- problems. Ditto if your disk or I/O subsystem is slowly
- failing. Yup, this really does happen.</para>
-
- <para>Try using a different machine of the same type, and see
- if you can repeat the problem.</para></listitem>
-
- <listitem><para>This isn't really a bug, but ... If
- <computeroutput>bzip2</computeroutput> tells you your file is
- corrupted on decompression, and you obtained the file via FTP,
- there is a possibility that you forgot to tell FTP to do a
- binary mode transfer. That absolutely will cause the file to
- be non-decompressible. You'll have to transfer it
- again.</para></listitem>
-
-</itemizedlist>
-
-<para>If you've incorporated
-<computeroutput>libbzip2</computeroutput> into your own program
-and are getting problems, please, please, please, check that the
-parameters you are passing in calls to the library, are correct,
-and in accordance with what the documentation says is allowable.
-I have tried to make the library robust against such problems,
-but I'm sure I haven't succeeded.</para>
-
-<para>Finally, if the above comments don't help, you'll have to
-send me a bug report. Now, it's just amazing how many people
-will send me a bug report saying something like:</para>
-
-<programlisting>
-bzip2 crashed with segmentation fault on my machine
-</programlisting>
-
-<para>and absolutely nothing else. Needless to say, a such a
-report is <emphasis>totally, utterly, completely and
-comprehensively 100% useless; a waste of your time, my time, and
-net bandwidth</emphasis>. With no details at all, there's no way
-I can possibly begin to figure out what the problem is.</para>
-
-<para>The rules of the game are: facts, facts, facts. Don't omit
-them because "oh, they won't be relevant". At the bare
-minimum:</para>
-
-<programlisting>
-Machine type. Operating system version.
-Exact version of bzip2 (do bzip2 -V).
-Exact version of the compiler used.
-Flags passed to the compiler.
-</programlisting>
-
-<para>However, the most important single thing that will help me
-is the file that you were trying to compress or decompress at the
-time the problem happened. Without that, my ability to do
-anything more than speculate about the cause, is limited.</para>
-
-</sect1>
-
-
-<sect1 id="package" xreflabel="Did you get the right package?">
-<title>Did you get the right package?</title>
-
-<para><computeroutput>bzip2</computeroutput> is a resource hog.
-It soaks up large amounts of CPU cycles and memory. Also, it
-gives very large latencies. In the worst case, you can feed many
-megabytes of uncompressed data into the library before getting
-any compressed output, so this probably rules out applications
-requiring interactive behaviour.</para>
-
-<para>These aren't faults of my implementation, I hope, but more
-an intrinsic property of the Burrows-Wheeler transform
-(unfortunately). Maybe this isn't what you want.</para>
-
-<para>If you want a compressor and/or library which is faster,
-uses less memory but gets pretty good compression, and has
-minimal latency, consider Jean-loup Gailly's and Mark Adler's
-work, <computeroutput>zlib-1.2.1</computeroutput> and
-<computeroutput>gzip-1.2.4</computeroutput>. Look for them at
-<ulink url="http://www.zlib.org">http://www.zlib.org</ulink> and
-<ulink url="http://www.gzip.org">http://www.gzip.org</ulink>
-respectively.</para>
-
-<para>For something faster and lighter still, you might try Markus F
-X J Oberhumer's <computeroutput>LZO</computeroutput> real-time
-compression/decompression library, at
-<ulink url="http://www.oberhumer.com/opensource">http://www.oberhumer.com/opensource</ulink>.</para>
-
-</sect1>
-
-
-
-<sect1 id="reading" xreflabel="Further Reading">
-<title>Further Reading</title>
-
-<para><computeroutput>bzip2</computeroutput> is not research
-work, in the sense that it doesn't present any new ideas.
-Rather, it's an engineering exercise based on existing
-ideas.</para>
-
-<para>Four documents describe essentially all the ideas behind
-<computeroutput>bzip2</computeroutput>:</para>
-
-<literallayout>Michael Burrows and D. J. Wheeler:
- "A block-sorting lossless data compression algorithm"
- 10th May 1994.
- Digital SRC Research Report 124.
- ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz
- If you have trouble finding it, try searching at the
- New Zealand Digital Library, http://www.nzdl.org.
-
-Daniel S. Hirschberg and Debra A. LeLewer
- "Efficient Decoding of Prefix Codes"
- Communications of the ACM, April 1990, Vol 33, Number 4.
- You might be able to get an electronic copy of this
- from the ACM Digital Library.
-
-David J. Wheeler
- Program bred3.c and accompanying document bred3.ps.
- This contains the idea behind the multi-table Huffman coding scheme.
- ftp://ftp.cl.cam.ac.uk/users/djw3/
-
-Jon L. Bentley and Robert Sedgewick
- "Fast Algorithms for Sorting and Searching Strings"
- Available from Sedgewick's web page,
- www.cs.princeton.edu/~rs
-</literallayout>
-
-<para>The following paper gives valuable additional insights into
-the algorithm, but is not immediately the basis of any code used
-in bzip2.</para>
-
-<literallayout>Peter Fenwick:
- Block Sorting Text Compression
- Proceedings of the 19th Australasian Computer Science Conference,
- Melbourne, Australia. Jan 31 - Feb 2, 1996.
- ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</literallayout>
-
-<para>Kunihiko Sadakane's sorting algorithm, mentioned above, is
-available from:</para>
-
-<literallayout>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz
-</literallayout>
-
-<para>The Manber-Myers suffix array construction algorithm is
-described in a paper available from:</para>
-
-<literallayout>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
-</literallayout>
-
-<para>Finally, the following papers document some
-investigations I made into the performance of sorting
-and decompression algorithms:</para>
-
-<literallayout>Julian Seward
- On the Performance of BWT Sorting Algorithms
- Proceedings of the IEEE Data Compression Conference 2000
- Snowbird, Utah. 28-30 March 2000.
-
-Julian Seward
- Space-time Tradeoffs in the Inverse B-W Transform
- Proceedings of the IEEE Data Compression Conference 2001
- Snowbird, Utah. 27-29 March 2001.
-</literallayout>
-
-</sect1>
-
-</chapter>
-
-</book>
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/mk251.c b/contrib/vmap_extractor_v2/stormlib/bzip2/mk251.c
deleted file mode 100644
index 205778a84e6..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/mk251.c
+++ /dev/null
@@ -1,16 +0,0 @@
-
-/* Spew out a long sequence of the byte 251. When fed to bzip2
- versions 1.0.0 or 1.0.1, causes it to die with internal error
- 1007 in blocksort.c. This assertion misses an extremely rare
- case, which is fixed in this version (1.0.2) and above.
-*/
-
-#include <stdio.h>
-
-int main ()
-{
- int i;
- for (i = 0; i < 48500000 ; i++)
- putchar(251);
- return 0;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.bz2 b/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.bz2
deleted file mode 100644
index 18dea60043b..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.bz2
+++ /dev/null
Binary files differ
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.ref b/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.ref
deleted file mode 100644
index a56e52b77f9..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/sample1.ref
+++ /dev/null
Binary files differ
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.bz2 b/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.bz2
deleted file mode 100644
index d5a6160ba20..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.bz2
+++ /dev/null
Binary files differ
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.ref b/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.ref
deleted file mode 100644
index 34af95839a0..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/sample2.ref
+++ /dev/null
Binary files differ
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.bz2 b/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.bz2
deleted file mode 100644
index d90cff9208f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.bz2
+++ /dev/null
Binary files differ
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.ref b/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.ref
deleted file mode 100644
index 775a2f68e21..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/sample3.ref
+++ /dev/null
@@ -1,30007 +0,0 @@
-This file is exceedingly boring. If you find yourself
-reading it, please (1) take it from me that you can safely
-guess what the rest of the file says, and (2) seek professional
-help.
-
-ps. there are no further sarcastic remarks in this file.
-
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/spewG.c b/contrib/vmap_extractor_v2/stormlib/bzip2/spewG.c
deleted file mode 100644
index 7934e765818..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/spewG.c
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/* spew out a thoroughly gigantic file designed so that bzip2
- can compress it reasonably rapidly. This is to help test
- support for large files (> 2GB) in a reasonable amount of time.
- I suggest you use the undocumented --exponential option to
- bzip2 when compressing the resulting file; this saves a bit of
- time. Note: *don't* bother with --exponential when compressing
- Real Files; it'll just waste a lot of CPU time :-)
- (but is otherwise harmless).
-*/
-
-#define _FILE_OFFSET_BITS 64
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/* The number of megabytes of junk to spew out (roughly) */
-#define MEGABYTES 5000
-
-#define N_BUF 1000000
-char buf[N_BUF];
-
-int main ( int argc, char** argv )
-{
- int ii, kk, p;
- srandom(1);
- setbuffer ( stdout, buf, N_BUF );
- for (kk = 0; kk < MEGABYTES * 515; kk+=3) {
- p = 25+random()%50;
- for (ii = 0; ii < p; ii++)
- printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
- for (ii = 0; ii < p-1; ii++)
- printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" );
- for (ii = 0; ii < p+1; ii++)
- printf ( "ccccccccccccccccccccccccccccccccccccc" );
- }
- fflush(stdout);
- return 0;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/unzcrash.c b/contrib/vmap_extractor_v2/stormlib/bzip2/unzcrash.c
deleted file mode 100644
index f0f17fcca53..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/unzcrash.c
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/* A test program written to test robustness to decompression of
- corrupted data. Usage is
- unzcrash filename
- and the program will read the specified file, compress it (in memory),
- and then repeatedly decompress it, each time with a different bit of
- the compressed data inverted, so as to test all possible one-bit errors.
- This should not cause any invalid memory accesses. If it does,
- I want to know about it!
-
- p.s. As you can see from the above description, the process is
- incredibly slow. A file of size eg 5KB will cause it to run for
- many hours.
-*/
-
-#include <stdio.h>
-#include <assert.h>
-#include "bzlib.h"
-
-#define M_BLOCK 1000000
-
-typedef unsigned char uchar;
-
-#define M_BLOCK_OUT (M_BLOCK + 1000000)
-uchar inbuf[M_BLOCK];
-uchar outbuf[M_BLOCK_OUT];
-uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
-
-int nIn, nOut, nZ;
-
-static char *bzerrorstrings[] = {
- "OK"
- ,"SEQUENCE_ERROR"
- ,"PARAM_ERROR"
- ,"MEM_ERROR"
- ,"DATA_ERROR"
- ,"DATA_ERROR_MAGIC"
- ,"IO_ERROR"
- ,"UNEXPECTED_EOF"
- ,"OUTBUFF_FULL"
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
-};
-
-void flip_bit ( int bit )
-{
- int byteno = bit / 8;
- int bitno = bit % 8;
- uchar mask = 1 << bitno;
- //fprintf ( stderr, "(byte %d bit %d mask %d)",
- // byteno, bitno, (int)mask );
- zbuf[byteno] ^= mask;
-}
-
-int main ( int argc, char** argv )
-{
- FILE* f;
- int r;
- int bit;
- int i;
-
- if (argc != 2) {
- fprintf ( stderr, "usage: unzcrash filename\n" );
- return 1;
- }
-
- f = fopen ( argv[1], "r" );
- if (!f) {
- fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
- return 1;
- }
-
- nIn = fread ( inbuf, 1, M_BLOCK, f );
- fprintf ( stderr, "%d bytes read\n", nIn );
-
- nZ = M_BLOCK;
- r = BZ2_bzBuffToBuffCompress (
- zbuf, &nZ, inbuf, nIn, 9, 0, 30 );
-
- assert (r == BZ_OK);
- fprintf ( stderr, "%d after compression\n", nZ );
-
- for (bit = 0; bit < nZ*8; bit++) {
- fprintf ( stderr, "bit %d ", bit );
- flip_bit ( bit );
- nOut = M_BLOCK_OUT;
- r = BZ2_bzBuffToBuffDecompress (
- outbuf, &nOut, zbuf, nZ, 0, 0 );
- fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] );
-
- if (r != BZ_OK) {
- fprintf ( stderr, "\n" );
- } else {
- if (nOut != nIn) {
- fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
- return 1;
- } else {
- for (i = 0; i < nOut; i++)
- if (inbuf[i] != outbuf[i]) {
- fprintf(stderr, "mismatch at %d\n", i );
- return 1;
- }
- if (i == nOut) fprintf(stderr, "really ok!\n" );
- }
- }
-
- flip_bit ( bit );
- }
-
-#if 0
- assert (nOut == nIn);
- for (i = 0; i < nOut; i++) {
- if (inbuf[i] != outbuf[i]) {
- fprintf ( stderr, "difference at %d !\n", i );
- return 1;
- }
- }
-#endif
-
- fprintf ( stderr, "all ok\n" );
- return 0;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words0 b/contrib/vmap_extractor_v2/stormlib/bzip2/words0
deleted file mode 100644
index 164a8ed287a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/words0
+++ /dev/null
@@ -1,5 +0,0 @@
-
-If compilation produces errors, or a large number of warnings,
-please read README.COMPILATION.PROBLEMS -- you might be able to
-adjust the flags in this Makefile to improve matters.
-
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words1 b/contrib/vmap_extractor_v2/stormlib/bzip2/words1
deleted file mode 100644
index 2e83de9f083..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/words1
+++ /dev/null
@@ -1,4 +0,0 @@
-
-Doing 6 tests (3 compress, 3 uncompress) ...
-If there's a problem, things might stop at this point.
-
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words2 b/contrib/vmap_extractor_v2/stormlib/bzip2/words2
deleted file mode 100644
index 203ee39c4c2..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/words2
+++ /dev/null
@@ -1,5 +0,0 @@
-
-Checking test results. If any of the four "cmp"s which follow
-report any differences, something is wrong. If you can't easily
-figure out what, please let me know (jseward@acm.org).
-
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/words3 b/contrib/vmap_extractor_v2/stormlib/bzip2/words3
deleted file mode 100644
index 7a6b462443c..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/words3
+++ /dev/null
@@ -1,23 +0,0 @@
-
-If you got this far and the "cmp"s didn't complain, it looks
-like you're in business.
-
-To install in /usr/bin, /usr/lib, /usr/man and /usr/include, type
- make install
-To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
- make install PREFIX=/xxx/yyy
-If you are (justifiably) paranoid and want to see what 'make install'
-is going to do, you can first do
- make -n install or
- make -n install PREFIX=/xxx/yyy respectively.
-The -n instructs make to show the commands it would execute, but
-not actually execute them.
-
-Instructions for use are in the preformatted manual page, in the file
-bzip2.txt. For more detailed documentation, read the full manual.
-It is available in Postscript form (manual.ps), PDF form (manual.pdf),
-and HTML form (manual_toc.html).
-
-You can also do "bzip2 --help" to see some helpful information.
-"bzip2 -L" displays the software license.
-
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/xmlproc.sh b/contrib/vmap_extractor_v2/stormlib/bzip2/xmlproc.sh
deleted file mode 100644
index 6fe4d5748bb..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/xmlproc.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/bash
-# see the README in this directory for usage etc.
-
-usage() {
- echo '';
- echo 'Usage: xmlproc.sh -[option] <filename.xml>';
- echo 'Specify a target from:';
- echo '-v verify xml file conforms to dtd';
- echo '-html output in html format (single file)';
- echo '-ps output in postscript format';
- echo '-pdf output in pdf format';
- exit;
-}
-
-if test $# -ne 2; then
- usage
-fi
-# assign the variable for the output type
-action=$1; shift
-# assign the output filename
-xmlfile=$1; shift
-# and check user input it correct
-if !(test -f $xmlfile); then
- echo "No such file: $xmlfile";
- exit;
-fi
-# some other stuff we will use
-OUT=output
-xsl_fo=bz-fo.xsl
-xsl_html=bz-html.xsl
-
-basename=$xmlfile
-basename=${basename//'.xml'/''}
-
-fofile="${basename}.fo"
-htmlfile="${basename}.html"
-pdffile="${basename}.pdf"
-psfile="${basename}.ps"
-xmlfmtfile="${basename}.fmt"
-
-# first process the xmlfile with CDATA tags
-./format.pl $xmlfile $xmlfmtfile
-# so the shell knows where the catalogs live
-export XML_CATALOG_FILES=/etc/xml/catalog
-
-# post-processing tidy up
-cleanup() {
- echo "Cleaning up: # $@"
- while [ $# != 0 ]
- do
- arg=$1; shift;
- echo " deleting $arg";
- rm $arg
- done
-}
-
-case $action in
- -v)
- flags='--noout --xinclude --noblanks --postvalid'
- dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd'
- xmllint $flags $dtd $xmlfmtfile 2> $OUT
- egrep 'error' $OUT
- rm $OUT
- ;;
-
- -html)
- echo "Creating $htmlfile ..."
- xsltproc --nonet --xinclude -o $htmlfile $xsl_html $xmlfmtfile
- cleanup $xmlfmtfile
- ;;
-
- -pdf)
- echo "Creating $pdffile ..."
- xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
- pdfxmltex $fofile >$OUT </dev/null
- pdfxmltex $fofile >$OUT </dev/null
- pdfxmltex $fofile >$OUT </dev/null
- cleanup $OUT $xmlfmtfile *.aux *.fo *.log *.out
- ;;
-
- -ps)
- echo "Creating $psfile ..."
- xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
- pdfxmltex $fofile >$OUT </dev/null
- pdfxmltex $fofile >$OUT </dev/null
- pdfxmltex $fofile >$OUT </dev/null
- pdftops $pdffile $psfile
- cleanup $OUT $xmlfmtfile $pdffile *.aux *.fo *.log *.out
-# passivetex is broken, so we can't go this route yet.
-# xmltex $fofile >$OUT </dev/null
-# xmltex $fofile >$OUT </dev/null
-# xmltex $fofile >$OUT </dev/null
-# dvips -R -q -o bzip-manual.ps *.dvi
- ;;
-
- *)
- usage
- ;;
-esac
diff --git a/contrib/vmap_extractor_v2/stormlib/huffman/huff.cpp b/contrib/vmap_extractor_v2/stormlib/huffman/huff.cpp
deleted file mode 100644
index 612fcb08386..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/huffman/huff.cpp
+++ /dev/null
@@ -1,1453 +0,0 @@
-/*****************************************************************************/
-/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */
-/*---------------------------------------------------------------------------*/
-/* This module contains Huffmann (de)compression methods */
-/* */
-/* Authors : Ladislav Zezula (ladik.zezula.net) */
-/* ShadowFlare (BlakFlare@hotmail.com) */
-/* */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */
-/* 03.05.03 1.00 Lad Added compression methods */
-/* 19.11.03 1.01 Dan Big endian handling */
-/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "huff.h"
-
-// Special for Mac - we have to know if normal pointer greater or less
-// than 0x80000000. This variable is used in the PTR_VALID and PTR_INVALID
-// macros
-static long mul = 1;
-
-#define PTR_VALID(ptr) (((LONG_PTR)(ptr) * mul) > 0)
-#define PTR_INVALID(ptr) (((LONG_PTR)(ptr) * mul) < 0)
-#define PTR_INVALID_OR_NULL(ptr) (((LONG_PTR)(ptr) * mul) <= 0)
-
-
-//-----------------------------------------------------------------------------
-// Methods of the THTreeItem struct
-
-// 1501DB70
-THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast)
-{
- if(pLast == NULL)
- pLast = this + 1;
- return pLast;
-}
-
-// Gets previous Huffman tree item (?)
-THTreeItem * THTreeItem::GetPrevItem(LONG_PTR value)
-{
- if(PTR_INVALID(prev))
- return PTR_NOT(prev);
-
- if(value == -1 || PTR_INVALID(value))
- value = (long)(this - next->prev);
- return prev + value;
-
-// OLD VERSION
-// if(PTR_INT(value) < 0)
-// value = PTR_INT((item - item->next->prev));
-// return (THTreeItem *)((char *)prev + value);
-}
-
-// 1500F5E0
-void THTreeItem::ClearItemLinks()
-{
- next = prev = NULL;
-}
-
-// 1500BC90
-void THTreeItem::RemoveItem()
-{
- THTreeItem * pTemp; // EDX
-
- if(next != NULL)
- {
- pTemp = prev;
-
- if(PTR_INVALID_OR_NULL(pTemp))
- pTemp = PTR_NOT(pTemp);
- else
- pTemp += (this - next->prev);
-
- pTemp->next = next;
- next->prev = prev;
- next = prev = NULL;
- }
-}
-
-/*
-// OLD VERSION : Removes item from the tree (?)
-static void RemoveItem(THTreeItem * item)
-{
- THTreeItem * next = item->next; // ESI
- THTreeItem * prev = item->prev; // EDX
-
- if(next == NULL)
- return;
-
- if(PTR_INT(prev) < 0)
- prev = PTR_NOT(prev);
- else
- // ??? usually item == next->prev, so what is it ?
- prev = (THTreeItem *)((unsigned char *)prev + (unsigned long)((unsigned char *)item - (unsigned char *)(next->prev)));
-
- // Remove HTree item from the chain
- prev->next = next; // Sets the 'first' pointer
- next->prev = item->prev;
-
- // Invalidate pointers
- item->next = NULL;
- item->prev = NULL;
-}
-*/
-
-//-----------------------------------------------------------------------------
-// TOutputStream functions
-
-void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits)
-{
- dwBitBuff |= (dwBuff << nBits);
- nBits += nPutBits;
-
- // Flush completed bytes
- while(nBits >= 8)
- {
- if(dwOutSize != 0)
- {
- *pbOutPos++ = (unsigned char)dwBitBuff;
- dwOutSize--;
- }
-
- dwBitBuff >>= 8;
- nBits -= 8;
- }
-}
-
-//-----------------------------------------------------------------------------
-// TInputStream functions
-
-// Gets one bit from input stream
-unsigned long TInputStream::GetBit()
-{
- unsigned long dwBit = (dwBitBuff & 1);
-
- dwBitBuff >>= 1;
- if(--nBits == 0)
- {
- dwBitBuff = BSWAP_INT32_UNSIGNED(*(unsigned long *)pbInBuffer);
- pbInBuffer += sizeof(unsigned long);
- nBits = 32;
- }
- return dwBit;
-}
-
-// Gets 7 bits from the stream
-unsigned long TInputStream::Get7Bits()
-{
- if(nBits <= 7)
- {
- dwBitBuff |= BSWAP_INT16_UNSIGNED(*(unsigned short *)pbInBuffer) << nBits;
- pbInBuffer += sizeof(unsigned short);
- nBits += 16;
- }
-
- // Get 7 bits from input stream
- return (dwBitBuff & 0x7F);
-}
-
-// Gets the whole byte from the input stream.
-unsigned long TInputStream::Get8Bits()
-{
- unsigned long dwOneByte;
-
- if(nBits <= 8)
- {
- dwBitBuff |= BSWAP_INT16_UNSIGNED(*(unsigned short *)pbInBuffer) << nBits;
- pbInBuffer += sizeof(unsigned short);
- nBits += 16;
- }
-
- dwOneByte = (dwBitBuff & 0xFF);
- dwBitBuff >>= 8;
- nBits -= 8;
- return dwOneByte;
-}
-
-//-----------------------------------------------------------------------------
-// Functions for huffmann tree items
-
-// Inserts item into the tree (?)
-static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long where, THTreeItem * item2)
-{
- THTreeItem * next = item->next; // EDI - next to the first item
- THTreeItem * prev = item->prev; // ESI - prev to the first item
- THTreeItem * prev2; // Pointer to previous item
- LONG_PTR next2; // Pointer to the next item
-
- // The same code like in RemoveItem(item);
- if(next != 0) // If the first item already has next one
- {
- if(PTR_INVALID(prev))
- prev = PTR_NOT(prev);
- else
- prev += (item - next->prev);
-
- // 150083C1
- // Remove the item from the tree
- prev->next = next;
- next->prev = prev;
-
- // Invalidate 'prev' and 'next' pointer
- item->next = 0;
- item->prev = 0;
- }
-
- if(item2 == NULL) // EDX - If the second item is not entered,
- item2 = PTR_PTR(&itemPtr[1]); // take the first tree item
-
- switch(where)
- {
- case SWITCH_ITEMS : // Switch the two items
- item->next = item2->next; // item2->next (Pointer to pointer to first)
- item->prev = item2->next->prev;
- item2->next->prev = item;
- item2->next = item; // Set the first item
- return;
-
- case INSERT_ITEM: // Insert as the last item
- item->next = item2; // Set next item (or pointer to pointer to first item)
- item->prev = item2->prev; // Set prev item (or last item in the tree)
-
- next2 = PTR_INT(itemPtr[0]);// Usually NULL
- prev2 = item2->prev; // Prev item to the second (or last tree item)
-
- if(PTR_INVALID(prev2))
- {
- prev2 = PTR_NOT(prev);
-
- prev2->next = item;
- item2->prev = item; // Next after last item
- return;
- }
-
- if(PTR_INVALID(next2))
- next2 = (long)(item2 - item2->next->prev);
-// next2 = (THTreeItem *)(unsigned long)((unsigned char *)item2 - (unsigned char *)(item2->next->prev));
-
-// prev2 = (THTreeItem *)((char *)prev2 + (unsigned long)next2);// ???
- prev2 += next2;
- prev2->next = item;
- item2->prev = item; // Set the next/last item
- return;
-
- default:
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// THuffmannTree class functions
-
-THuffmannTree::THuffmannTree()
-{
- // We have to check if the "this" pointer is less than zero
- if((LONG_PTR)this < 0)
- mul = -1;
-}
-
-void THuffmannTree::InitTree(bool bCompression)
-{
- THTreeItem * pItem;
- unsigned int nCount;
-
- // Clear links for all the items in the tree
- for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--)
- pItem->ClearItemLinks();
-
- pItem3050 = NULL;
- pItem3054 = PTR_PTR(&pItem3054);
- pItem3058 = PTR_NOT(pItem3054);
-
- pItem305C = NULL;
- pFirst = PTR_PTR(&pFirst);
- pLast = PTR_NOT(pFirst);
-
- offs0004 = 1;
- nItems = 0;
-
- // Clear all TQDecompress items. Do this only if preparing for decompression
- if(bCompression == false)
- {
- for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++)
- qd3474[nCount].offs00 = 0;
- }
-}
-
-// Builds Huffman tree. Called with the first 8 bits loaded from input stream
-void THuffmannTree::BuildTree(unsigned int nCmpType)
-{
- unsigned long maxByte; // [ESP+10] - The greatest character found in table
- THTreeItem ** itemPtr; // [ESP+14] - Pointer to Huffman tree item pointer array
- unsigned char * byteArray; // [ESP+1C] - Pointer to unsigned char in Table1502A630
- THTreeItem * child1;
- unsigned long i; // egcs in linux doesn't like multiple for loops without an explicit i
-
- // Loop while pointer has a valid value
- while(PTR_VALID(pLast)) // ESI - Last entry
- {
- THTreeItem * temp; // EAX
-
- if(pLast->next != NULL) // ESI->next
- pLast->RemoveItem();
- // EDI = &offs3054
- pItem3058 = PTR_PTR(&pItem3054);// [EDI+4]
- pLast->prev = pItem3058; // EAX
-
- temp = PTR_PTR(&pItem3054)->GetPrevItem(PTR_INT(&pItem3050));
-
- temp->next = pLast;
- pItem3054 = pLast;
- }
-
- // Clear all pointers in HTree item array
- memset(items306C, 0, sizeof(items306C));
-
- maxByte = 0; // Greatest character found init to zero.
- itemPtr = (THTreeItem **)&items306C; // Pointer to current entry in HTree item pointer array
-
- // Ensure we have low 8 bits only
- nCmpType &= 0xFF;
- byteArray = Table1502A630 + nCmpType * 258; // EDI also
-
- for(i = 0; i < 0x100; i++, itemPtr++)
- {
- THTreeItem * item = pItem3058; // Item to be created
- THTreeItem * pItem3 = pItem3058;
- unsigned char oneByte = byteArray[i];
-
- // Skip all the bytes which are zero.
- if(byteArray[i] == 0)
- continue;
-
- // If not valid pointer, take the first available item in the array
- if(PTR_INVALID_OR_NULL(item))
- item = &items0008[nItems++];
-
- // Insert this item as the top of the tree
- InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
-
- item->parent = NULL; // Invalidate child and parent
- item->child = NULL;
- *itemPtr = item; // Store pointer into pointer array
-
- item->dcmpByte = i; // Store counter
- item->byteValue = oneByte; // Store byte value
- if(oneByte >= maxByte)
- {
- maxByte = oneByte;
- continue;
- }
-
- // Find the first item which has byte value greater than current one byte
- if(PTR_VALID(pItem3 = pLast)) // EDI - Pointer to the last item
- {
- // 15006AF7
- if(pItem3 != NULL)
- {
- do // 15006AFB
- {
- if(pItem3->byteValue >= oneByte)
- goto _15006B09;
- pItem3 = pItem3->prev;
- }
- while(PTR_VALID(pItem3));
- }
- }
- pItem3 = NULL;
-
- // 15006B09
- _15006B09:
- if(item->next != NULL)
- item->RemoveItem();
-
- // 15006B15
- if(pItem3 == NULL)
- pItem3 = PTR_PTR(&pFirst);
-
- // 15006B1F
- item->next = pItem3->next;
- item->prev = pItem3->next->prev;
- pItem3->next->prev = item;
- pItem3->next = item;
- }
-
- // 15006B4A
- for(; i < 0x102; i++)
- {
- THTreeItem ** itemPtr = &items306C[i]; // EDI
-
- // 15006B59
- THTreeItem * item = pItem3058; // ESI
- if(PTR_INVALID_OR_NULL(item))
- item = &items0008[nItems++];
-
- InsertItem(&pItem305C, item, INSERT_ITEM, NULL);
-
- // 15006B89
- item->dcmpByte = i;
- item->byteValue = 1;
- item->parent = NULL;
- item->child = NULL;
- *itemPtr++ = item;
- }
-
- // 15006BAA
- if(PTR_VALID(child1 = pLast)) // EDI - last item (first child to item
- {
- THTreeItem * child2; // EBP
- THTreeItem * item; // ESI
-
- // 15006BB8
- while(PTR_VALID(child2 = child1->prev))
- {
- if(PTR_INVALID_OR_NULL(item = pItem3058))
- item = &items0008[nItems++];
-
- // 15006BE3
- InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
-
- // 15006BF3
- item->parent = NULL;
- item->child = NULL;
-
- //EDX = child2->byteValue + child1->byteValue;
- //EAX = child1->byteValue;
- //ECX = maxByte; // The greatest character (0xFF usually)
-
- item->byteValue = child1->byteValue + child2->byteValue; // 0x02
- item->child = child1; // Prev item in the
- child1->parent = item;
- child2->parent = item;
-
- // EAX = item->byteValue;
- if(item->byteValue >= maxByte)
- maxByte = item->byteValue;
- else
- {
- THTreeItem * pItem2 = child2->prev; // EDI
-
- // 15006C2D
- while(PTR_VALID(pItem2))
- {
- if(pItem2->byteValue >= item->byteValue)
- goto _15006C3B;
- pItem2 = pItem2->prev;
- }
- pItem2 = NULL;
-
- _15006C3B:
- if(item->next != 0)
- {
- THTreeItem * temp4 = item->GetPrevItem(-1);
-
- temp4->next = item->next; // The first item changed
- item->next->prev = item->prev; // First->prev changed to negative value
- item->next = NULL;
- item->prev = NULL;
- }
-
- // 15006C62
- if(pItem2 == NULL)
- pItem2 = PTR_PTR(&pFirst);
-
- item->next = pItem2->next; // Set item with 0x100 byte value
- item->prev = pItem2->next->prev; // Set item with 0x17 byte value
- pItem2->next->prev = item; // Changed prev of item with
- pItem2->next = item;
- }
-
- // 15006C7B
- if(PTR_INVALID_OR_NULL(child1 = child2->prev))
- break;
- }
- }
- // 15006C88
- offs0004 = 1;
-}
-/*
-// Modifies Huffman tree. Adds new item and changes
-void THuffmannTree::ModifyTree(unsigned long dwIndex)
-{
- THTreeItem * pItem1 = pItem3058; // ESI
- THTreeItem * pSaveLast = (PTR_INT(pLast) <= 0) ? NULL : pLast; // EBX
- THTreeItem * temp; // EAX
-
- // Prepare the first item to insert to the tree
- if(PTR_INT(pItem1) <= 0)
- pItem1 = &items0008[nItems++];
-
- // If item has any next item, remove it from the chain
- if(pItem1->next != NULL)
- {
- THTreeItem * temp = pItem1->GetPrevItem(-1); // EAX
-
- temp->next = pItem1->next;
- pItem1->next->prev = pItem1->prev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- pItem1->next = PTR_PTR(&pFirst);
- pItem1->prev = pLast;
- temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
-
- // 150068E9
- temp->next = pItem1;
- pLast = pItem1;
-
- pItem1->parent = NULL;
- pItem1->child = NULL;
-
- // 150068F6
- pItem1->dcmpByte = pSaveLast->dcmpByte; // Copy item index
- pItem1->byteValue = pSaveLast->byteValue; // Copy item byte value
- pItem1->parent = pSaveLast; // Set parent to last item
- items306C[pSaveLast->dcmpByte] = pItem1; // Insert item into item pointer array
-
- // Prepare the second item to insert into the tree
- if(PTR_INT((pItem1 = pItem3058)) <= 0)
- pItem1 = &items0008[nItems++];
-
- // 1500692E
- if(pItem1->next != NULL)
- {
- temp = pItem1->GetPrevItem(-1); // EAX
-
- temp->next = pItem1->next;
- pItem1->next->prev = pItem1->prev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
- // 1500694C
- pItem1->next = PTR_PTR(&pFirst);
- pItem1->prev = pLast;
- temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
-
- // 15006968
- temp->next = pItem1;
- pLast = pItem1;
-
- // 1500696E
- pItem1->child = NULL;
- pItem1->dcmpByte = dwIndex;
- pItem1->byteValue = 0;
- pItem1->parent = pSaveLast;
- pSaveLast->child = pItem1;
- items306C[dwIndex] = pItem1;
-
- do
- {
- THTreeItem * pItem2 = pItem1;
- THTreeItem * pItem3;
- unsigned long byteValue;
-
- // 15006993
- byteValue = ++pItem1->byteValue;
-
- // Pass through all previous which have its value greater than byteValue
- while(PTR_INT((pItem3 = pItem2->prev)) > 0) // EBX
- {
- if(pItem3->byteValue >= byteValue)
- goto _150069AE;
-
- pItem2 = pItem2->prev;
- }
- // 150069AC
- pItem3 = NULL;
-
- _150069AE:
- if(pItem2 == pItem1)
- continue;
-
- // 150069B2
- // Switch pItem2 with item
- InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
- InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
-
- // 150069D0
- // Switch parents of pItem1 and pItem2
- temp = pItem2->parent->child;
- if(pItem1 == pItem1->parent->child)
- pItem1->parent->child = pItem2;
-
- if(pItem2 == temp)
- pItem2->parent->child = pItem1;
-
- // 150069ED
- // Switch parents of pItem1 and pItem3
- temp = pItem1->parent;
- pItem1 ->parent = pItem2->parent;
- pItem2->parent = temp;
- offs0004++;
- }
- while(PTR_INT((pItem1 = pItem1->parent)) > 0);
-}
-
-void THuffmannTree::UninitTree()
-{
- while(PTR_INT(pLast) > 0)
- {
- pItem = pItem305C->Call1501DB70(pLast);
- pItem->RemoveItem();
- }
-
- for(pItem = pFirst; PTR_INT(pItem3058) > 0; pItem = pItem3058)
- pItem->RemoveItem();
- PTR_PTR(&pItem3054)->RemoveItem();
-
- for(pItem = items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
- {
- pItem--;
- pItem->RemoveItem();
- pItem->RemoveItem();
- }
-}
-*/
-
-THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue)
-{
- THTreeItem * pItem1 = pItem3058; // EDX
- THTreeItem * pItem2; // EAX
- THTreeItem * pNext;
- THTreeItem * pPrev;
- THTreeItem ** ppItem;
-
- if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL)
- {
- if((pItem2 = &items0008[nItems++]) != NULL)
- pItem1 = pItem2;
- else
- pItem1 = pFirst;
- }
- else
- pItem1 = pItem2;
-
- pNext = pItem1->next;
- if(pNext != NULL)
- {
- pPrev = pItem1->prev;
- if(PTR_INVALID_OR_NULL(pPrev))
- pPrev = PTR_NOT(pPrev);
- else
- pPrev += (pItem1 - pItem1->next->prev);
-
- pPrev->next = pNext;
- pNext->prev = pPrev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- ppItem = &pFirst; // esi
- if(nValue > 1)
- {
- // ecx = pFirst->next;
- pItem1->next = *ppItem;
- pItem1->prev = (*ppItem)->prev;
-
- (*ppItem)->prev = pItem2;
- *ppItem = pItem1;
-
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- else
- {
- pItem1->next = (THTreeItem *)ppItem;
- pItem1->prev = ppItem[1];
- // edi = pItem305C;
- pPrev = ppItem[1]; // ecx
- if(PTR_INVALID_OR_NULL(pPrev))
- {
- pPrev = PTR_NOT(pPrev);
- pPrev->next = pItem1;
- pPrev->prev = pItem2;
-
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- else
- {
- if(PTR_INVALID(pItem305C))
- pPrev += (THTreeItem *)ppItem - (*ppItem)->prev;
- else
- pPrev += PTR_INT(pItem305C);
-
- pPrev->next = pItem1;
- ppItem[1] = pItem2;
- pItem2->parent = NULL;
- pItem2->child = NULL;
- }
- }
- return pItem2;
-}
-
-void THuffmannTree::Call1500E820(THTreeItem * pItem)
-{
- THTreeItem * pItem1; // edi
- THTreeItem * pItem2 = NULL; // eax
- THTreeItem * pItem3; // edx
- THTreeItem * pPrev; // ebx
-
- for(; pItem != NULL; pItem = pItem->parent)
- {
- pItem->byteValue++;
-
- for(pItem1 = pItem; ; pItem1 = pPrev)
- {
- pPrev = pItem1->prev;
- if(PTR_INVALID_OR_NULL(pPrev))
- {
- pPrev = NULL;
- break;
- }
-
- if(pPrev->byteValue >= pItem->byteValue)
- break;
- }
-
- if(pItem1 == pItem)
- continue;
-
- if(pItem1->next != NULL)
- {
- pItem2 = pItem1->GetPrevItem(-1);
- pItem2->next = pItem1->next;
- pItem1->next->prev = pItem1->prev;
- pItem1->next = NULL;
- pItem1->prev = NULL;
- }
-
- pItem2 = pItem->next;
- pItem1->next = pItem2;
- pItem1->prev = pItem2->prev;
- pItem2->prev = pItem1;
- pItem->next = pItem1;
- if((pItem2 = pItem1) != NULL)
- {
- pItem2 = pItem->GetPrevItem(-1);
- pItem2->next = pItem->next;
- pItem->next->prev = pItem->prev;
- pItem->next = NULL;
- pItem->prev = NULL;
- }
-
- if(pPrev == NULL)
- pPrev = PTR_PTR(&pFirst);
-
- pItem2 = pPrev->next;
- pItem->next = pItem2;
- pItem->prev = pItem2->prev;
- pItem2->prev = pItem;
- pPrev->next = pItem;
-
- pItem3 = pItem1->parent->child;
- pItem2 = pItem->parent;
- if(pItem2->child == pItem)
- pItem2->child = pItem1;
- if(pItem3 == pItem1)
- pItem1->parent->child = pItem;
-
- pItem2 = pItem->parent;
- pItem->parent = pItem1->parent;
- pItem1->parent = pItem2;
- offs0004++;
- }
-}
-
-// 1500E920
-unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType)
-{
- THTreeItem * pItem1;
- THTreeItem * pItem2;
- THTreeItem * pItem3;
- THTreeItem * pTemp;
- unsigned long dwBitBuff;
- unsigned int nBits;
- unsigned int nBit;
-
- BuildTree(nCmpType);
- bIsCmp0 = (nCmpType == 0);
-
- // Store the compression type into output buffer
- os->dwBitBuff |= (nCmpType << os->nBits);
- os->nBits += 8;
-
- // Flush completed bytes
- while(os->nBits >= 8)
- {
- if(os->dwOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->dwOutSize--;
- }
-
- os->dwBitBuff >>= 8;
- os->nBits -= 8;
- }
-
- for(; nInLength != 0; nInLength--)
- {
- unsigned char bOneByte = *pbInBuffer++;
-
- if((pItem1 = items306C[bOneByte]) == NULL)
- {
- pItem2 = items306C[0x101]; // ecx
- pItem3 = pItem2->parent; // eax
- dwBitBuff = 0;
- nBits = 0;
-
- for(; pItem3 != NULL; pItem3 = pItem3->parent)
- {
- nBit = (pItem3->child != pItem2) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem2 = pItem3;
- }
- os->PutBits(dwBitBuff, nBits);
-
- // Store the loaded byte into output stream
- os->dwBitBuff |= (bOneByte << os->nBits);
- os->nBits += 8;
-
- // Flush the whole byte(s)
- while(os->nBits >= 8)
- {
- if(os->dwOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->dwOutSize--;
- }
- os->dwBitBuff >>= 8;
- os->nBits -= 8;
- }
-
- pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
- pItem2 = Call1500E740(1);
- pItem2->dcmpByte = pItem1->dcmpByte;
- pItem2->byteValue = pItem1->byteValue;
- pItem2->parent = pItem1;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem2 = Call1500E740(1);
- pItem2->dcmpByte = bOneByte;
- pItem2->byteValue = 0;
- pItem2->parent = pItem1;
- items306C[pItem2->dcmpByte] = pItem2;
- pItem1->child = pItem2;
-
- Call1500E820(pItem2);
-
- if(bIsCmp0 != 0)
- {
- Call1500E820(items306C[bOneByte]);
- continue;
- }
-
- for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent)
- {
- pItem1->byteValue++;
- pItem2 = pItem1;
-
- for(;;)
- {
- pItem3 = pItem2->prev;
- if(PTR_INVALID_OR_NULL(pItem3))
- {
- pItem3 = NULL;
- break;
- }
- if(pItem3->byteValue >= pItem1->byteValue)
- break;
- pItem2 = pItem3;
- }
-
- if(pItem2 != pItem1)
- {
- InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
- InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
-
- pItem3 = pItem2->parent->child;
- if(pItem1->parent->child == pItem1)
- pItem1->parent->child = pItem2;
-
- if(pItem3 == pItem2)
- pItem2->parent->child = pItem1;
-
- pTemp = pItem1->parent;
- pItem1->parent = pItem2->parent;
- pItem2->parent = pTemp;
- offs0004++;
- }
- }
- }
-// 1500EB62
- else
- {
- dwBitBuff = 0;
- nBits = 0;
- for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
- {
- nBit = (pItem2->child != pItem1) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem1 = pItem2;
- }
- os->PutBits(dwBitBuff, nBits);
- }
-
-// 1500EB98
- if(bIsCmp0 != 0)
- Call1500E820(items306C[bOneByte]); // 1500EB9D
-// 1500EBAF
- } // for(; nInLength != 0; nInLength--)
-
-// 1500EBB8
- pItem1 = items306C[0x100];
- dwBitBuff = 0;
- nBits = 0;
- for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
- {
- nBit = (pItem2->child != pItem1) ? 1 : 0;
- dwBitBuff = (dwBitBuff << 1) | nBit;
- nBits++;
- pItem1 = pItem2;
- }
-
-// 1500EBE6
- os->PutBits(dwBitBuff, nBits);
-
-// 1500EBEF
- // Flush the remaining bits
- while(os->nBits != 0)
- {
- if(os->dwOutSize != 0)
- {
- *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
- os->dwOutSize--;
- }
- os->dwBitBuff >>= 8;
- os->nBits -= ((os->nBits > 8) ? 8 : os->nBits);
- }
-
- return (unsigned int)(os->pbOutPos - os->pbOutBuffer);
-}
-
-// Decompression using Huffman tree (1500E450)
-unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is)
-{
- TQDecompress * qd;
- THTreeItem * pItem1;
- THTreeItem * pItem2;
- unsigned char * pbOutPos = pbOutBuffer;
- unsigned long nBitCount;
- unsigned int nDcmpByte = 0;
- unsigned int n8Bits; // 8 bits loaded from input stream
- unsigned int n7Bits; // 7 bits loaded from input stream
- bool bHasQdEntry;
-
- // Test the output length. Must not be NULL.
- if(dwOutLength == 0)
- return 0;
-
- // Get the compression type from the input stream
- n8Bits = is->Get8Bits();
-
- // Build the Huffman tree
- BuildTree(n8Bits);
- bIsCmp0 = (n8Bits == 0) ? 1 : 0;
-
- for(;;)
- {
- n7Bits = is->Get7Bits(); // Get 7 bits from input stream
-
- // Try to use quick decompression. Check TQDecompress array for corresponding item.
- // If found, ise the result byte instead.
- qd = &qd3474[n7Bits];
-
- // If there is a quick-pass possible (ebx)
- bHasQdEntry = (qd->offs00 >= offs0004) ? true : false;
-
- // If we can use quick decompress, use it.
- if(bHasQdEntry)
- {
- if(qd->nBits > 7)
- {
- is->dwBitBuff >>= 7;
- is->nBits -= 7;
- pItem1 = qd->pItem;
- goto _1500E549;
- }
- is->dwBitBuff >>= qd->nBits;
- is->nBits -= qd->nBits;
- nDcmpByte = qd->dcmpByte;
- }
- else
- {
- pItem1 = pFirst->next->prev;
- if(PTR_INVALID_OR_NULL(pItem1))
- pItem1 = NULL;
-_1500E549:
- nBitCount = 0;
- pItem2 = NULL;
-
- do
- {
- pItem1 = pItem1->child; // Move down by one level
- if(is->GetBit()) // If current bit is set, move to previous
- pItem1 = pItem1->prev;
-
- if(++nBitCount == 7) // If we are at 7th bit, save current HTree item.
- pItem2 = pItem1;
- }
- while(pItem1->child != NULL); // Walk until tree has no deeper level
-
- if(bHasQdEntry == false)
- {
- if(nBitCount > 7)
- {
- qd->offs00 = offs0004;
- qd->nBits = nBitCount;
- qd->pItem = pItem2;
- }
- else
- {
- unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount));
- unsigned long nAdd = (1 << nBitCount);
-
- for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd)
- {
- qd->offs00 = offs0004;
- qd->nBits = nBitCount;
- qd->dcmpByte = pItem1->dcmpByte;
- }
- }
- }
- nDcmpByte = pItem1->dcmpByte;
- }
-
- if(nDcmpByte == 0x101) // Huffman tree needs to be modified
- {
- n8Bits = is->Get8Bits();
- pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
-
- pItem2 = Call1500E740(1);
- pItem2->parent = pItem1;
- pItem2->dcmpByte = pItem1->dcmpByte;
- pItem2->byteValue = pItem1->byteValue;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem2 = Call1500E740(1);
- pItem2->parent = pItem1;
- pItem2->dcmpByte = n8Bits;
- pItem2->byteValue = 0;
- items306C[pItem2->dcmpByte] = pItem2;
-
- pItem1->child = pItem2;
- Call1500E820(pItem2);
- if(bIsCmp0 == 0)
- Call1500E820(items306C[n8Bits]);
-
- nDcmpByte = n8Bits;
- }
-
- if(nDcmpByte == 0x100)
- break;
-
- *pbOutPos++ = (unsigned char)nDcmpByte;
- if(--dwOutLength == 0)
- break;
-
- if(bIsCmp0)
- Call1500E820(items306C[nDcmpByte]);
- }
-
- return (unsigned int)(pbOutPos - pbOutBuffer);
-}
-
-/* OLD VERSION
-unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is)
-{
- THTreeItem * pItem1; // Current item if walking HTree
- unsigned long bitCount; // Bit counter if walking HTree
- unsigned long oneByte; // 8 bits from bit stream/Pointer to target
- unsigned char * outPtr; // Current pointer to output buffer
- bool hasQDEntry; // true if entry for quick decompression if filled
- THTreeItem * itemAt7 = NULL; // HTree item found at 7th bit
- THTreeItem * temp; // For every use
- unsigned long dcmpByte = 0; // Decompressed byte value
- bool bFlag = 0;
-
- // Test the output length. Must not be NULL.
- if(dwOutLength == 0)
- return 0;
-
- // If too few bits in input bit buffer, we have to load next 16 bits
- is->EnsureHasMoreThan8Bits();
-
- // Get 8 bits from input stream
- oneByte = is->Get8Bits();
-
- // Build the Huffman tree
- BuildTree(oneByte);
-
- bIsCmp0 = (oneByte == 0) ? 1 : 0;
- outPtr = pbOutBuffer; // Copy pointer to output data
-
- for(;;)
- {
- TQDecompress * qd; // For quick decompress
- unsigned long sevenBits = is->Get7Bits();// 7 bits from input stream
-
- // Try to use quick decompression. Check TQDecompress array for corresponding item.
- // If found, ise the result byte instead.
- qd = &qd3474[sevenBits];
-
- // If there is a quick-pass possible
- hasQDEntry = (qd->offs00 == offs0004) ? 1 : 0;
-
- // Start passing the Huffman tree. Set item to tree root item
- pItem1 = pFirst;
-
- // If we can use quick decompress, use it.
- bFlag = 1;
- if(hasQDEntry == 1)
- {
- // Check the bit count is greater than 7, move item to 7 levels deeper
- if((bitCount = qd->bitCount) > 7)
- {
- is->dwBitBuff >>= 7;
- is->nBits -= 7;
- pItem1 = qd->item; // Don't start with root item, but with some deeper-laying
- }
- else
- {
- // If OK, use their byte value
- is->dwBitBuff >>= bitCount;
- is->nBits -= bitCount;
- dcmpByte = qd->dcmpByte;
- bFlag = 0;
- }
- }
- else
- {
- pItem1 = pFirst->next->prev;
- if(PTR_INT(pItem1) <= 0)
- pItem1 = NULL;
- }
-
- if(bFlag == 1)
- {
- // Walk through Huffman Tree
- bitCount = 0; // Clear bit counter
- do
- {
- pItem1 = pItem1->child;
- if(is->GetBit() != 0) // If current bit is set, move to previous
- pItem1 = pItem1->prev; // item in current level
-
- if(++bitCount == 7) // If we are at 7th bit, store current HTree item.
- itemAt7 = pItem1; // Store Huffman tree item
- }
- while(pItem1->child != NULL); // Walk until tree has no deeper level
-
- // If quick decompress entry is not filled yet, fill it.
- if(hasQDEntry == 0)
- {
- if(bitCount > 7) // If we passed more than 7 bits, store bitCount and item
- {
- qd->offs00 = offs0004; // Value indicates that entry is resolved
- qd->bitCount = bitCount; // Number of bits passed
- qd->item = itemAt7; // Store item at 7th bit
- }
- // If we passed less than 7 bits, fill entry and bit count multipliers
- else
- {
- unsigned long index = sevenBits & (0xFFFFFFFF >> (32 - bitCount)); // Index for quick-decompress entry
- unsigned long addIndex = (1 << bitCount); // Add value for index
-
- qd = &qd3474[index];
-
- do
- {
- qd->offs00 = offs0004;
- qd->bitCount = bitCount;
- qd->dcmpByte = pItem1->dcmpByte;
-
- index += addIndex;
- qd += addIndex;
- }
- while(index <= 0x7F);
- }
- }
- dcmpByte = pItem1->dcmpByte;
- }
-
- if(dcmpByte == 0x101) // Huffman tree needs to be modified
- {
- // Check if there is enough bits in the buffer
- is->EnsureHasMoreThan8Bits();
-
- // Get 8 bits from the buffer
- oneByte = is->Get8Bits();
-
- // Modify Huffman tree
- ModifyTree(oneByte);
-
- // Get lastly added tree item
- pItem1 = items306C[oneByte];
-
- if(bIsCmp0 == 0 && pItem1 != NULL)
- {
- // 15006F15
- do
- {
- THTreeItem * pItem2 = pItem1;
- THTreeItem * pItem3;
- unsigned long byteValue;
-
- byteValue = ++pItem1->byteValue;
-
- while(PTR_INT((pItem3 = pItem2->prev)) > 0)
- {
- if(pItem3->byteValue >= byteValue)
- goto _15006F30;
-
- pItem2 = pItem2->prev;
- }
- pItem3 = NULL;
-
- _15006F30:
- if(pItem2 == pItem1)
- continue;
-
- InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
- InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
-
- temp = pItem2->parent->child;
- if(pItem1 == pItem1->parent->child)
- pItem1->parent->child = pItem2;
-
- if(pItem2 == temp)
- pItem2->parent->child = pItem1;
-
- // Switch parents of pItem1 and pItem3
- temp = pItem1->parent;
- pItem1->parent = pItem2->parent;
- pItem2->parent = temp;
- offs0004++;
- }
- while(PTR_INT((pItem1 = pItem1->parent)) > 0);
- }
- dcmpByte = oneByte;
- }
-
- if(dcmpByte != 0x100) // Not at the end of data ?
- {
- *outPtr++ = (unsigned char)dcmpByte;
- if(--dwOutLength > 0)
- {
- if(bIsCmp0 != 0)
- Call1500E820(items306C[pItem1->byteValue]);
- }
- else
- break;
- }
- else
- break;
- }
- return (unsigned long)(outPtr - pbOutBuffer);
-}
-*/
-
-// Table for (de)compression. Every compression type has 258 entries
-unsigned char THuffmannTree::Table1502A630[] =
-{
- // Data for compression type 0x00
- 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00,
-
- // Data for compression type 0x01
- 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
- 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
- 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
- 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04,
- 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
- 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02,
- 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03,
- 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03,
- 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
- 0x00, 0x00,
-
- // Data for compression type 0x02
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
- 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01,
- 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02,
- 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
- 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
- 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x03
- 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
- 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01,
- 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03,
- 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03,
- 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01,
- 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
- 0x00, 0x00,
-
- // Data for compression type 0x04
- 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x05
- 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
- 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
- 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
- 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x06
- 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x07
- 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- // Data for compression type 0x08
- 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10,
- 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11,
- 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
-}; \ No newline at end of file
diff --git a/contrib/vmap_extractor_v2/stormlib/huffman/huff.h b/contrib/vmap_extractor_v2/stormlib/huffman/huff.h
deleted file mode 100644
index f06aa771acd..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/huffman/huff.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*****************************************************************************/
-/* huffman.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Description : */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* xx.xx.xx 1.00 Lad The first version of huffman.h */
-/* 03.05.03 2.00 Lad Added compression */
-/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
-/*****************************************************************************/
-
-#ifndef __HUFFMAN_H__
-#define __HUFFMAN_H__
-
-#include "../StormPort.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define INSERT_ITEM 1
-#define SWITCH_ITEMS 2 // Switch the item1 and item2
-
-#define PTR_NOT(ptr) (THTreeItem *)(~(DWORD_PTR)(ptr))
-#define PTR_PTR(ptr) ((THTreeItem *)(ptr))
-#define PTR_INT(ptr) (LONG_PTR)(ptr)
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-//-----------------------------------------------------------------------------
-// Structures and classes
-
-// Input stream for Huffmann decompression
-class TInputStream
-{
- public:
-
- unsigned long GetBit();
- unsigned long Get7Bits();
- unsigned long Get8Bits();
-
- unsigned char * pbInBuffer; // 00 - Input data
- unsigned long dwBitBuff; // 04 - Input bit buffer
- unsigned int nBits; // 08 - Number of bits remaining in 'dwValue'
-};
-
-// Output stream for Huffmann compression
-class TOutputStream
-{
- public:
-
- void PutBits(unsigned long dwBuff, unsigned int nPutBits);
-
- unsigned char * pbOutBuffer; // 00 : Output buffer
- unsigned long dwOutSize; // 04 : Size of output buffer
- unsigned char * pbOutPos; // 08 : Current output position
- unsigned long dwBitBuff; // 0C : Bit buffer
- unsigned long nBits; // 10 : Number of bits in the bit buffer
-};
-
-// Huffmann tree item (?)
-struct THTreeItem
-{
- public:
-
- THTreeItem * Call1501DB70(THTreeItem * pLast);
- THTreeItem * GetPrevItem(LONG_PTR value);
- void ClearItemLinks();
- void RemoveItem();
-
- THTreeItem * next; // 00 - Pointer to next THTreeItem
- THTreeItem * prev; // 04 - Pointer to prev THTreeItem (< 0 if none)
- unsigned long dcmpByte; // 08 - Index of this item in item pointer array, decompressed byte value
- unsigned long byteValue; // 0C - Some byte value
- THTreeItem * parent; // 10 - Pointer to parent THTreeItem (NULL if none)
- THTreeItem * child; // 14 - Pointer to child THTreeItem
- int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
-};
-
-// Structure used for quick decompress. The 'bitCount' contains number of bits
-// and byte value contains result decompressed byte value.
-// After each walk through Huffman tree are filled all entries which are
-// multiplies of number of bits loaded from input stream. These entries
-// contain number of bits and result value. At the next 7 bits is tested this
-// structure first. If corresponding entry found, decompression routine will
-// not walk through Huffman tree and directly stores output byte to output stream.
-struct TQDecompress
-{
- unsigned long offs00; // 00 - 1 if resolved
- unsigned long nBits; // 04 - Bit count
- union
- {
- unsigned long dcmpByte; // 08 - Byte value for decompress (if bitCount <= 7)
- THTreeItem * pItem; // 08 - THTreeItem (if number of bits is greater than 7
- };
-};
-
-// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert
-// for the decompression, I do not know actually if the class is really a Hufmann
-// tree. If someone knows the decompression details, please let me know
-class THuffmannTree
-{
- public:
-
- THuffmannTree();
- void InitTree(bool bCompression);
- void BuildTree(unsigned int nCmpType);
-// void ModifyTree(unsigned long dwIndex);
-// void UninitTree();
-
-// void Call15007010(Bit32 dwInLength, THTreeItem * item);
- THTreeItem * Call1500E740(unsigned int nValue);
- void Call1500E820(THTreeItem * pItem);
- unsigned int DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType);
- unsigned int DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is);
-
- unsigned long bIsCmp0; // 0000 - 1 if compression type 0
- unsigned long offs0004; // 0004 - Some flag
- THTreeItem items0008[0x203]; // 0008 - HTree items
-
- //- Sometimes used as HTree item -----------
- THTreeItem * pItem3050; // 3050 - Always NULL (?)
- THTreeItem * pItem3054; // 3054 - Pointer to Huffman tree item
- THTreeItem * pItem3058; // 3058 - Pointer to Huffman tree item (< 0 if invalid)
-
- //- Sometimes used as HTree item -----------
- THTreeItem * pItem305C; // 305C - Usually NULL
- THTreeItem * pFirst; // 3060 - Pointer to top (first) Huffman tree item
- THTreeItem * pLast; // 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid)
- unsigned long nItems; // 3068 - Number of used HTree items
-
- //-------------------------------------------
- THTreeItem * items306C[0x102]; // 306C - THTreeItem pointer array
- TQDecompress qd3474[0x80]; // 3474 - Array for quick decompression
- int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
-
- static unsigned char Table1502A630[];// Some table
-};
-
-#endif // __HUFFMAN_H__
diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/crc32.c b/contrib/vmap_extractor_v2/stormlib/pklib/crc32.c
deleted file mode 100644
index a7f52103be4..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/pklib/crc32.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*****************************************************************************/
-/* crc32.c Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Pkware Data Compression Library Version 1.11 */
-/* Dissassembled method crc32 - cdecl version */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 09.04.03 1.00 Lad The first version of crc32.c */
-/* 02.05.03 1.00 Lad Stress test done */
-/*****************************************************************************/
-
-#include "pklib.h"
-
-static char CopyRight[] = "PKWARE Data Compression Library for Win32\r\n"
- "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
- "Patent No. 5,051,745\r\n"
- "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
- "Version 1.11\r\n";
-
-static unsigned long crc_table[] =
-{
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
-};
-
-
-unsigned long PKEXPORT crc32pk(char * buffer, unsigned int * psize, unsigned long * old_crc)
-{
- unsigned int size = *psize;
- unsigned long ch;
- unsigned long crc_value = *old_crc;
-
- while(size-- != 0)
- {
- ch = *buffer++ ^ (char)crc_value;
- crc_value >>= 8;
-
- crc_value = crc_table[ch & 0x0FF] ^ crc_value;
- }
- return crc_value;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/crc32_pk.c b/contrib/vmap_extractor_v2/stormlib/pklib/crc32_pk.c
deleted file mode 100644
index a7f52103be4..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/pklib/crc32_pk.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*****************************************************************************/
-/* crc32.c Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Pkware Data Compression Library Version 1.11 */
-/* Dissassembled method crc32 - cdecl version */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 09.04.03 1.00 Lad The first version of crc32.c */
-/* 02.05.03 1.00 Lad Stress test done */
-/*****************************************************************************/
-
-#include "pklib.h"
-
-static char CopyRight[] = "PKWARE Data Compression Library for Win32\r\n"
- "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
- "Patent No. 5,051,745\r\n"
- "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
- "Version 1.11\r\n";
-
-static unsigned long crc_table[] =
-{
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
-};
-
-
-unsigned long PKEXPORT crc32pk(char * buffer, unsigned int * psize, unsigned long * old_crc)
-{
- unsigned int size = *psize;
- unsigned long ch;
- unsigned long crc_value = *old_crc;
-
- while(size-- != 0)
- {
- ch = *buffer++ ^ (char)crc_value;
- crc_value >>= 8;
-
- crc_value = crc_table[ch & 0x0FF] ^ crc_value;
- }
- return crc_value;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/explode.c b/contrib/vmap_extractor_v2/stormlib/pklib/explode.c
deleted file mode 100644
index a5b41e3dcf9..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/pklib/explode.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*****************************************************************************/
-/* explode.c Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Implode function of PKWARE Data Compression library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
-/* 08.04.03 1.01 Lad Renamed to explode.c to be compatible with pklib */
-/* 02.05.03 1.01 Lad Stress test done */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "pklib.h"
-
-//-----------------------------------------------------------------------------
-// Tables
-
-static unsigned char DistBits[] =
-{
- 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
-};
-
-static unsigned char DistCode[] =
-{
- 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
- 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
- 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
- 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
-};
-
-static unsigned char ExLenBits[] =
-{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
-};
-
-static unsigned short LenBase[] =
-{
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
-};
-
-static unsigned char LenBits[] =
-{
- 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
-};
-
-static unsigned char LenCode[] =
-{
- 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
-};
-
-static unsigned char ChBitsAsc[] =
-{
- 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
- 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
- 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
- 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
- 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
- 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
- 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
-};
-
-static unsigned short ChCodeAsc[] =
-{
- 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
- 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
- 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
- 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
- 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
- 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
- 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
- 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
- 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
- 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
- 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
- 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
- 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
- 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
- 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
- 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
- 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
- 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
- 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
- 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
- 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
- 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
- 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
- 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
- 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
- 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
- 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
- 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
- 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
- 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
- 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
- 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
-};
-
-//-----------------------------------------------------------------------------
-// Local variables
-
-static char Copyright[] = "PKWARE Data Compression Library for Win32\r\n"
- "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
- "Patent No. 5,051,745\r\n"
- "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
- "Version 1.11\r\n";
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-// Copies a block to another location
-static void lmemcpy(void * trg, const void * src, size_t count)
-{
- memcpy(trg, src, count);
-}
-
-static void GenDecodeTabs(long count, unsigned char * bits, unsigned char * pCode, unsigned char * buffer2)
-{
- long i;
-
- for(i = count-1; i >= 0; i--) // EBX - count
- {
- unsigned long idx1 = pCode[i];
- unsigned long idx2 = 1 << bits[i];
-
- do
- {
- buffer2[idx1] = (unsigned char)i;
- idx1 += idx2;
- }
- while(idx1 < 0x100);
- }
-}
-
-static void GenAscTabs(TDcmpStruct * pWork)
-{
- unsigned short * pChCodeAsc = &ChCodeAsc[0xFF];
- unsigned long acc, add;
- unsigned short count;
-
- for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--)
- {
- unsigned char * pChBitsAsc = pWork->ChBitsAsc + count;
- unsigned char bits_asc = *pChBitsAsc;
-
- if(bits_asc <= 8)
- {
- add = (1 << bits_asc);
- acc = *pChCodeAsc;
-
- do
- {
- pWork->offs2C34[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x100);
- }
- else if((acc = (*pChCodeAsc & 0xFF)) != 0)
- {
- pWork->offs2C34[acc] = 0xFF;
-
- if(*pChCodeAsc & 0x3F)
- {
- bits_asc -= 4;
- *pChBitsAsc = bits_asc;
-
- add = (1 << bits_asc);
- acc = *pChCodeAsc >> 4;
- do
- {
- pWork->offs2D34[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x100);
- }
- else
- {
- bits_asc -= 6;
- *pChBitsAsc = bits_asc;
-
- add = (1 << bits_asc);
- acc = *pChCodeAsc >> 6;
- do
- {
- pWork->offs2E34[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x80);
- }
- }
- else
- {
- bits_asc -= 8;
- *pChBitsAsc = bits_asc;
-
- add = (1 << bits_asc);
- acc = *pChCodeAsc >> 8;
- do
- {
- pWork->offs2EB4[acc] = (unsigned char)count;
- acc += add;
- }
- while(acc < 0x100);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Skips given number of bits in bit buffer. Result is stored in pWork->bit_buff
-// If no data in input buffer, returns true
-
-static int WasteBits(TDcmpStruct * pWork, unsigned long nBits)
-{
- // If number of bits required is less than number of (bits in the buffer) ?
- if(nBits <= pWork->extra_bits)
- {
- pWork->extra_bits -= nBits;
- pWork->bit_buff >>= nBits;
- return 0;
- }
-
- // Load input buffer if necessary
- pWork->bit_buff >>= pWork->extra_bits;
- if(pWork->in_pos == pWork->in_bytes)
- {
- pWork->in_pos = sizeof(pWork->in_buff);
- if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0)
- return 1;
- pWork->in_pos = 0;
- }
-
- // Update bit buffer
- pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8);
- pWork->bit_buff >>= (nBits - pWork->extra_bits);
- pWork->extra_bits = (pWork->extra_bits - nBits) + 8;
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Returns : 0x000 - 0x0FF : One byte from compressed file.
-// 0x100 - 0x305 : Copy previous block (0x100 = 1 byte)
-// 0x306 : Out of buffer (?)
-
-static unsigned long DecodeLit(TDcmpStruct * pWork)
-{
- unsigned long nBits; // Number of bits to skip
- unsigned long value; // Position in buffers
-
- // Test the current bit in byte buffer. If is not set, simply return the next byte.
- if(pWork->bit_buff & 1)
- {
- // Skip current bit in the buffer
- if(WasteBits(pWork, 1))
- return 0x306;
-
- // The next bits are position in buffers
- value = pWork->position2[(pWork->bit_buff & 0xFF)];
-
- // Get number of bits to skip
- if(WasteBits(pWork, pWork->LenBits[value]))
- return 0x306;
-
- if((nBits = pWork->ExLenBits[value]) != 0)
- {
- unsigned long val2 = pWork->bit_buff & ((1 << nBits) - 1);
-
- if(WasteBits(pWork, nBits))
- {
- if((value + val2) != 0x10E)
- return 0x306;
- }
- value = pWork->LenBase[value] + val2;
- }
- return value + 0x100; // Return number of bytes to repeat
- }
-
- // Waste one bit
- if(WasteBits(pWork, 1))
- return 0x306;
-
- // If the binary compression type, read 8 bits and return them as one byte.
- if(pWork->ctype == CMP_BINARY)
- {
- value = pWork->bit_buff & 0xFF;
- if(WasteBits(pWork, 8))
- return 0x306;
- return value;
- }
-
- // When ASCII compression ...
- if(pWork->bit_buff & 0xFF)
- {
- value = pWork->offs2C34[pWork->bit_buff & 0xFF];
-
- if(value == 0xFF)
- {
- if(pWork->bit_buff & 0x3F)
- {
- if(WasteBits(pWork, 4))
- return 0x306;
-
- value = pWork->offs2D34[pWork->bit_buff & 0xFF];
- }
- else
- {
- if(WasteBits(pWork, 6))
- return 0x306;
-
- value = pWork->offs2E34[pWork->bit_buff & 0x7F];
- }
- }
- }
- else
- {
- if(WasteBits(pWork, 8))
- return 0x306;
-
- value = pWork->offs2EB4[pWork->bit_buff & 0xFF];
- }
-
- return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value;
-}
-
-//-----------------------------------------------------------------------------
-// Retrieves the number of bytes to move back
-
-static unsigned long DecodeDist(TDcmpStruct * pWork, unsigned long dwLength)
-{
- unsigned long pos = pWork->position1[(pWork->bit_buff & 0xFF)];
- unsigned long nSkip = pWork->DistBits[pos]; // Number of bits to skip
-
- // Skip the appropriate number of bits
- if(WasteBits(pWork, nSkip) == 1)
- return 0;
-
- if(dwLength == 2)
- {
- pos = (pos << 2) | (pWork->bit_buff & 0x03);
-
- if(WasteBits(pWork, 2) == 1)
- return 0;
- }
- else
- {
- pos = (pos << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask);
-
- // Skip the bits
- if(WasteBits(pWork, pWork->dsize_bits) == 1)
- return 0;
- }
- return pos+1;
-}
-
-static unsigned long Expand(TDcmpStruct * pWork)
-{
- unsigned int copyBytes; // Number of bytes to copy
- unsigned long oneByte; // One byte from compressed file
- unsigned long dwResult;
-
- pWork->outputPos = 0x1000; // Initialize output buffer position
-
- // If end of data or error, terminate decompress
- while((dwResult = oneByte = DecodeLit(pWork)) < 0x305)
- {
- // If one byte is greater than 0x100, means "Repeat n - 0xFE bytes"
- if(oneByte >= 0x100)
- {
- unsigned char * source; // ECX
- unsigned char * target; // EDX
- unsigned long copyLength = oneByte - 0xFE;
- unsigned long moveBack;
-
- // Get length of data to copy
- if((moveBack = DecodeDist(pWork, copyLength)) == 0)
- {
- dwResult = 0x306;
- break;
- }
-
- // Target and source pointer
- target = &pWork->out_buff[pWork->outputPos];
- source = target - moveBack;
- pWork->outputPos += copyLength;
-
- while(copyLength-- > 0)
- *target++ = *source++;
- }
- else
- pWork->out_buff[pWork->outputPos++] = (unsigned char)oneByte;
-
- // If number of extracted bytes has reached 1/2 of output buffer,
- // flush output buffer.
- if(pWork->outputPos >= 0x2000)
- {
- // Copy decompressed data into user buffer
- copyBytes = 0x1000;
- pWork->write_buf((char *)&pWork->out_buff[0x1000], &copyBytes, pWork->param);
-
- // If there are some data left, keep them alive
- lmemcpy(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000);
- pWork->outputPos -= 0x1000;
- }
- }
-
- copyBytes = pWork->outputPos - 0x1000;
- pWork->write_buf((char *)&pWork->out_buff[0x1000], &copyBytes, pWork->param);
- return dwResult;
-}
-
-
-//-----------------------------------------------------------------------------
-// Main exploding function.
-
-unsigned int explode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param)
-{
- TDcmpStruct * pWork = (TDcmpStruct *)work_buf;
-
- // Set the whole work buffer to zeros
- memset(pWork, 0, sizeof(TDcmpStruct));
-
- // Initialize work struct and load compressed data
- pWork->read_buf = read_buf;
- pWork->write_buf = write_buf;
- pWork->param = param;
- pWork->in_pos = sizeof(pWork->in_buff);
- pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param);
- if(pWork->in_bytes <= 4)
- return CMP_BAD_DATA;
-
- pWork->ctype = pWork->in_buff[0]; // Get the compression type
- pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size
- pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer
- pWork->extra_bits = 0; // Extra (over 8) bits
- pWork->in_pos = 3; // Position in input buffer
-
- // Test for the valid dictionary size
- if(4 > pWork->dsize_bits || pWork->dsize_bits > 6)
- return CMP_INVALID_DICTSIZE;
-
- pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction
-
- if(pWork->ctype != CMP_BINARY)
- {
- if(pWork->ctype != CMP_ASCII)
- return CMP_INVALID_MODE;
-
- lmemcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc));
- GenAscTabs(pWork);
- }
-
- lmemcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits));
- GenDecodeTabs(0x10, pWork->LenBits, LenCode, pWork->position2);
- lmemcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits));
- lmemcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase));
- lmemcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits));
- GenDecodeTabs(0x40, pWork->DistBits, DistCode, pWork->position1);
- if(Expand(pWork) != 0x306)
- return CMP_NO_ERROR;
-
- return CMP_ABORT;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/implode.c b/contrib/vmap_extractor_v2/stormlib/pklib/implode.c
deleted file mode 100644
index 68d5301cc8d..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/pklib/implode.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*****************************************************************************/
-/* implode.c Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Implode function of PKWARE Data Compression library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.04.03 1.00 Lad First version of implode.c */
-/* 02.05.03 1.00 Lad Stress test done */
-/*****************************************************************************/
-
-#include <assert.h>
-#include <string.h>
-
-#include "pklib.h"
-
-#if ((1200 < _MSC_VER) && (_MSC_VER < 1400))
-#pragma optimize("", off) // Fucking Microsoft VS.NET 2003 compiler !!!
- // (_MSC_VER=1310)
-#endif
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define DICT_OFFSET 0x204
-#define UNCMP_OFFSET (pWork->dsize_bytes + DICT_OFFSET)
-
-//-----------------------------------------------------------------------------
-// Tables
-
-static unsigned char DistBits[] =
-{
- 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
-};
-
-static unsigned char DistCode[] =
-{
- 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
- 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
- 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
- 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
-};
-
-static unsigned char ExLenBits[] =
-{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
-};
-
-static unsigned char LenBits[] =
-{
- 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
-};
-
-static unsigned char LenCode[] =
-{
- 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
-};
-
-static unsigned char ChBitsAsc[] =
-{
- 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
- 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
- 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
- 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
- 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
- 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
- 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
-};
-
-static unsigned short ChCodeAsc[] =
-{
- 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
- 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
- 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
- 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
- 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
- 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
- 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
- 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
- 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
- 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
- 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
- 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
- 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
- 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
- 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
- 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
- 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
- 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
- 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
- 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
- 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
- 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
- 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
- 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
- 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
- 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
- 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
- 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
- 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
- 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
- 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
- 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
-};
-
-//-----------------------------------------------------------------------------
-// Local variables
-
-static char Copyright[] = "PKWARE Data Compression Library for Win32\r\n"
- "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n"
- "Patent No. 5,051,745\r\n"
- "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n"
- "Version 1.11\r\n";
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-// Fills memory block with a character
-static void lmemset(void * buff, int c, size_t count)
-{
- memset(buff, c, count);
-}
-
-// Copies memory block to another location
-static void lmemcpy(void * trg, const void * src, size_t count)
-{
- memcpy(trg, src, count);
-}
-
-static void SortBuffer(TCmpStruct * pWork, unsigned char * uncmp_data, unsigned char * work_end)
-{
- unsigned short * pin0DC8;
- unsigned char * puncmp;
- unsigned long offs1, offs2;
- unsigned long ndwords;
- unsigned int add;
-
- // Fill 0x480 dwords (0x1200 bytes)
- ndwords = (unsigned long)((pWork->out_buff - (char *)pWork->offs0DC8 + 1) >> 2);
- if(ndwords <= 1)
- ndwords = 1;
- memset(pWork->offs0DC8, 0, ndwords << 2);
-
- for(puncmp = uncmp_data; work_end > puncmp; puncmp++)
- pWork->offs0DC8[(puncmp[0] * 4) + (puncmp[1] * 5)]++;
-
- add = 0;
- for(pin0DC8 = pWork->offs0DC8; pin0DC8 < &pWork->offs1FC8; pin0DC8++)
- {
- add += *pin0DC8;
- *pin0DC8 = (unsigned short)add;
- }
-
- for(work_end--; work_end >= uncmp_data; work_end--)
- {
- offs1 = (work_end[0] * 4) + (work_end[1] * 5); // EAX
- offs2 = (unsigned long)(work_end - pWork->work_buff); // EDI
-
- pWork->offs0DC8[offs1]--;
- pWork->offs49D0[pWork->offs0DC8[offs1]] = (unsigned short)offs2;
- }
-}
-
-static void FlushBuf(TCmpStruct * pWork)
-{
- unsigned char save_ch1;
- unsigned char save_ch2;
- unsigned int size = 0x800;
-
- pWork->write_buf(pWork->out_buff, &size, pWork->param);
-
- save_ch1 = pWork->out_buff[0x800];
- save_ch2 = pWork->out_buff[pWork->out_bytes];
- pWork->out_bytes -= 0x800;
-
- lmemset(pWork->out_buff, 0, 0x802);
-
- if(pWork->out_bytes != 0)
- pWork->out_buff[0] = save_ch1;
- if(pWork->out_bits != 0)
- pWork->out_buff[pWork->out_bytes] = save_ch2;
-}
-
-static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit_buff)
-{
- unsigned int out_bits;
-
- // If more than 8 bits to output, do recursion
- if(nbits > 8)
- {
- OutputBits(pWork, 8, bit_buff);
- bit_buff >>= 8;
- nbits -= 8;
- }
-
- // Add bits to the last out byte in out_buff;
- out_bits = pWork->out_bits;
- pWork->out_buff[pWork->out_bytes] |= (unsigned char)(bit_buff << out_bits);
- pWork->out_bits += nbits;
-
- // If 8 or more bits, increment number of bytes
- if(pWork->out_bits > 8)
- {
- pWork->out_bytes++;
- bit_buff >>= (8 - out_bits);
-
- pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff;
- pWork->out_bits &= 7;
- }
- else
- {
- pWork->out_bits &= 7;
- if(pWork->out_bits == 0)
- pWork->out_bytes++;
- }
-
- // If there is enough compressed bytes, flush them
- if(pWork->out_bytes >= 0x800)
- FlushBuf(pWork);
-}
-
-static unsigned long FindRep(TCmpStruct * pWork, unsigned char * srcbuff)
-{
- unsigned short esp12;
- unsigned char * esp14;
- unsigned short esp18;
- unsigned char * srcbuff2;
- unsigned char esp20;
-
- unsigned char * srcbuff3;
- unsigned short * pin0DC8;
- unsigned char * pin27CC;
- unsigned short * pin49D0;
- unsigned long nreps = 1; // EAX
- unsigned long ebx, esi;
- unsigned short di;
-
- pin0DC8 = pWork->offs0DC8 + (srcbuff[0] * 4) + (srcbuff[1] * 5);
- esi = (unsigned long)(srcbuff - pWork->dsize_bytes - pWork->work_buff + 1);
- esp18 = *pin0DC8;
- pin49D0 = pWork->offs49D0 + esp18;
-
- if(*pin49D0 < esi)
- {
- while(*pin49D0 < esi)
- {
- pin49D0++;
- esp18++;
- }
- *pin0DC8 = esp18;
- }
-//---------------------------------------------------------------------------
- srcbuff2 = srcbuff - 1;
- pin49D0 = pWork->offs49D0 + esp18;
- pin27CC = pWork->work_buff + *pin49D0;
- if(srcbuff2 <= pin27CC)
- return 0;
-//---------------------------------------------------------------------------
- srcbuff3 = srcbuff;
- for(;;)
- {
- if(srcbuff3[nreps-1] == pin27CC[nreps-1] && *srcbuff3 == *pin27CC)
- {
- //
- // The following code does not work when compiled with MSVC.NET 2003
- // optimizing compiler. We have to switch the optimizations off to make it work
- // I found that in debug version (where the optimizations are off), the value
- // of "pin27CC" gets incremented twice (once at below, once in the "for" loop)
- //
-
- pin27CC++;
- srcbuff3++;
-
- for(ebx = 2; ebx < DICT_OFFSET; ebx++)
- {
- pin27CC++;
- srcbuff3++;
- if(*pin27CC != *srcbuff3)
- break;
- }
-
- srcbuff3 = srcbuff;
- if(ebx >= nreps)
- {
- pWork->offs0000 = (unsigned int)(srcbuff3 - pin27CC + ebx - 1);
- if((nreps = ebx) > 10)
- break;
- }
- }
-
- pin49D0++;
- esp18++;
- pin27CC = pWork->work_buff + *pin49D0;
-
- if(srcbuff2 > pin27CC)
- continue;
-
- return (nreps >= 2) ? nreps : 0;
- }
-//---------------------------------------------------------------------------
- if(ebx == DICT_OFFSET)
- {
- pWork->offs0000--;
- return ebx;
- }
-//---------------------------------------------------------------------------
- pin49D0 = pWork->offs49D0 + esp18;
- if(pWork->work_buff + pin49D0[1] >= srcbuff2)
- return nreps;
-//---------------------------------------------------------------------------
- di = 0;
- pWork->offs09BC[0] = 0xFFFF;
- pWork->offs09BC[1] = di;
- esp12 = 1;
-
- do
- {
- esi = di;
- if(srcbuff[esp12] != srcbuff[esi])
- {
- di = pWork->offs09BC[esi];
- if(di != 0xFFFF)
- continue;
- }
- pWork->offs09BC[++esp12] = ++di;
- }
- while(esp12 < nreps);
-//---------------------------------------------------------------------------
- esi = nreps;
- pin27CC = pWork->work_buff + pin49D0[0] + nreps;
- esp14 = pin27CC;
-
- for(;;) // 0040268B
- {
- esi = pWork->offs09BC[esi];
- if(esi == 0xFFFF)
- esi = 0;
-
- pin49D0 = pWork->offs49D0 + esp18;
- do
- {
- pin49D0++;
- esp18++;
- pin27CC = pWork->work_buff + pin49D0[0];
- if(pin27CC >= srcbuff2)
- return nreps;
- }
- while(pin27CC + esi < esp14);
-//---------------------------------------------------------------------------
- esp20 = srcbuff[nreps - 2];
- if(esp20 == pin27CC[nreps - 2])
- {
- if(pin27CC + esi != esp14)
- {
- esp14 = pin27CC;
- esi = 0;
- }
- }
- else
- {
- pin49D0 = pWork->offs49D0 + esp18;
- do
- {
- pin49D0++;
- esp18++;
- pin27CC = pWork->work_buff + pin49D0[0];
- if(pin27CC >= srcbuff2)
- return nreps;
- }
- while(pin27CC[nreps - 2] != esp20 || pin27CC[0] != *srcbuff);
-
- esp14 = pin27CC + 2;
- esi = 2;
- }
-//---------------------------------------------------------------------------
- for(; esp14[0] == srcbuff[esi]; esp14++)
- {
- if(++esi >= DICT_OFFSET)
- break;
- }
-
- if(esi < nreps)
- continue;
- pWork->offs0000 = (unsigned int)(srcbuff - pin27CC - 1);
- if(esi <= nreps)
- continue;
- nreps = esi;
- if(esi == DICT_OFFSET)
- return nreps;
-
- do
- {
- if(srcbuff[esp12] != srcbuff[di])
- {
- di = pWork->offs09BC[di];
- if(di != 0xFFFF)
- continue;
- }
- pWork->offs09BC[++esp12] = ++di;
- }
- while(esp12 < esi);
- }
-}
-
-static void WriteCmpData(TCmpStruct * pWork)
-{
- unsigned int nreps = 0; // ESP+10 : Number of repeats
- unsigned char * uncmp_end; // ESP+14 : End of uncompressed data
- unsigned int esp18 = 0; // ESP+18 :
- unsigned int bytes_required; // ESP+1C : Number of bytes required to read
- unsigned int esp20 = 0; // ESP+20 :
- unsigned char * uncmp_begin = pWork->work_buff + UNCMP_OFFSET; // EDI
- unsigned long nreps1;
- unsigned long save_offs0000 = 0;
-
- // Store the compression type and dictionary size
- pWork->out_buff[0] = (char)pWork->ctype;
- pWork->out_buff[1] = (char)pWork->dsize_bits;
- pWork->out_bytes = 2;
-
- // Reset output buffer to zero
- lmemset(&pWork->out_buff[2], 0, sizeof(pWork->out_buff) - 2);
- pWork->out_bits = 0;
-
- do
- {
- int total_loaded = 0;
-
- for(bytes_required = 0x1000; bytes_required != 0; )
- {
- int loaded = pWork->read_buf((char *)pWork->work_buff + UNCMP_OFFSET + total_loaded,
- &bytes_required, pWork->param);
-
- if(loaded == 0)
- {
- if(total_loaded == 0 && esp20 == 0)
- goto __Exit;
- esp18 = 1;
- break;
- }
- else
- {
- total_loaded += loaded;
- bytes_required -= loaded;
- }
- }
-
- uncmp_end = pWork->work_buff + pWork->dsize_bytes + total_loaded;
- if(esp18 != 0)
- uncmp_end += DICT_OFFSET;
-
- //
- // Warning: Passing "uncmp_end + 1" to the SortBuffer function may cause
- // the output to be unpredictable in Storm.dll's compression. Because Storm.dll
- // does not pass the zeroed buffer to the "implode" function, the byte after
- // uncmp_end contains random data. This causes difference within dictionary
- // created in SortBuffer function and may also cause different compressed output.
- // We always zero the data before compression, so this thing never occurs.
- // Funny is that it is actually not a bug, because if we decompress the data back,
- // we'll get the identical data with the original input.
- //
- switch(esp20)
- {
- case 0:
- SortBuffer(pWork, uncmp_begin, uncmp_end + 1);
- esp20++;
- if(pWork->dsize_bytes != 0x1000)
- esp20++;
- break;
-
- case 1:
- SortBuffer(pWork, uncmp_begin - pWork->dsize_bytes + DICT_OFFSET, uncmp_end + 1);
- esp20++;
- break;
-
- default:
- SortBuffer(pWork, uncmp_begin - pWork->dsize_bytes, uncmp_end + 1);
- break;
- }
-
- while(uncmp_end > uncmp_begin)
- {
- nreps1 = FindRep(pWork, uncmp_begin);
- while(nreps1 != 0)
- {
- if(nreps1 == 2 && pWork->offs0000 >= 0x100)
- break;
-
- if(esp18 != 0 && uncmp_begin + nreps1 > uncmp_end)
- goto _004022DB;
-
- if(nreps1 >= 8 || uncmp_begin + 1 >= uncmp_end)
- goto _004022FF;
-
- save_offs0000 = pWork->offs0000; // ebp
- nreps = nreps1;
- nreps1 = FindRep(pWork, uncmp_begin + 1);
-
- if(nreps >= nreps1)
- goto _004022F9;
-
- if(nreps + 1 >= nreps1 && save_offs0000 <= 0x80)
- goto _004022F9;
-
- OutputBits(pWork, pWork->nChBits[*uncmp_begin], pWork->nChCodes[*uncmp_begin]);
- uncmp_begin++;
- }
-
-_0040222F:
- OutputBits(pWork, pWork->nChBits[*uncmp_begin], pWork->nChCodes[*uncmp_begin]);
- uncmp_begin++;
-_00402252:;
- }
-
- if(esp18 == 0)
- {
- uncmp_begin -= 0x1000;
- lmemcpy(pWork->work_buff, pWork->work_buff + 0x1000, pWork->dsize_bytes + DICT_OFFSET);
- }
- }
- while(esp18 == 0);
-
-__Exit:
- OutputBits(pWork, pWork->nChBits[0x305], pWork->nChCodes[0x305]);
- if(pWork->out_bits != 0)
- pWork->out_bytes++;
- pWork->write_buf(pWork->out_buff, &pWork->out_bytes, pWork->param);
- return;
-
-_004022DB:
- nreps1 = (unsigned long)(uncmp_end - uncmp_begin);
- if(nreps1 < 2)
- goto _0040222F;
-
- if(nreps1 != 2 || pWork->offs0000 < 0x100)
- goto _004022FF;
- goto _0040222F;
-
-_004022F9:
- nreps1 = nreps;
- pWork->offs0000 = save_offs0000;
-
-_004022FF:
- OutputBits(pWork, pWork->nChBits[nreps1 + 0xFE], pWork->nChCodes[nreps1 + 0xFE]);
-
- if(nreps1 == 2)
- {
- OutputBits(pWork, pWork->dist_bits[pWork->offs0000 >> 2],
- pWork->dist_codes[pWork->offs0000 >> 2]);
- OutputBits(pWork, 2, pWork->offs0000 & 3);
- }
- else
- {
- OutputBits(pWork, pWork->dist_bits[pWork->offs0000 >> pWork->dsize_bits],
- pWork->dist_codes[pWork->offs0000 >> pWork->dsize_bits]);
- OutputBits(pWork, pWork->dsize_bits, pWork->dsize_mask & pWork->offs0000);
- }
- uncmp_begin += nreps1;
- goto _00402252;
-}
-
-//-----------------------------------------------------------------------------
-// Main imploding function
-
-unsigned int PKEXPORT implode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param,
- unsigned int *type,
- unsigned int *dsize)
-{
- TCmpStruct * pWork = (TCmpStruct *)work_buf;
- unsigned int nChCode;
- unsigned int nCount;
- unsigned int i;
-
- // Initialize the work buffer. This is not in the Pklib,
- // but it seems to be a bug. Storm always pre-fills the data with zeros,
- // and always compresses one block only. So the bug will not appear.
- // But when a larger data block (size > 0x1000) is compressed,
- // it may fail.
- memset(pWork, 0, sizeof(TCmpStruct));
-
- // Fill the work buffer information
- pWork->read_buf = read_buf;
- pWork->write_buf = write_buf;
- pWork->dsize_bytes = *dsize;
- pWork->ctype = *type;
- pWork->param = param;
- pWork->dsize_bits = 4;
- pWork->dsize_mask = 0x0F;
-
- // Test dictionary size
- switch(*dsize)
- {
- case 0x1000 :
- pWork->dsize_bits++;
- pWork->dsize_mask |= 0x20;
- // No break here !!!
-
- case 0x0800 :
- pWork->dsize_bits++;
- pWork->dsize_mask |= 0x10;
- // No break here !!!
-
- case 0x0400 :
- break;
-
- default:
- return CMP_INVALID_DICTSIZE;
- }
-
- // Test the compression type
- switch(*type)
- {
- case CMP_BINARY: // We will compress data with binary compression type
- for(nChCode = 0, nCount = 0; nCount < 0x100; nCount++)
- {
- pWork->nChBits[nCount] = 9;
- pWork->nChCodes[nCount] = (unsigned short)nChCode;
- nChCode = (nChCode & 0x0000FFFF) + 2;
- }
- break;
-
-
- case CMP_ASCII: // We will compress data with ASCII compression type
- for(nCount = 0; nCount < 0x100; nCount++)
- {
- pWork->nChBits[nCount] = (unsigned char )(ChBitsAsc[nCount] + 1);
- pWork->nChCodes[nCount] = (unsigned short)(ChCodeAsc[nCount] * 2);
- }
- break;
-
- default:
- return CMP_INVALID_MODE;
- }
-
- for(i = 0; i < 0x10; i++)
- {
- int nCount2 = 0; // EBX
-
- if((1 << ExLenBits[i]) == 0)
- continue;
-
- do
- {
- pWork->nChBits[nCount] = (unsigned char)(ExLenBits[i] + LenBits[i] + 1);
- pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1);
-
- nCount2++;
- nCount++;
- }
- while((1 << ExLenBits[i]) > nCount2);
- }
-
- // Copy the distance codes and distance bits and perform the compression
- lmemcpy(&pWork->dist_codes, DistCode, sizeof(DistCode));
- lmemcpy(&pWork->dist_bits, DistBits, sizeof(DistBits));
- WriteCmpData(pWork);
- return CMP_NO_ERROR;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/pklib/pklib.h b/contrib/vmap_extractor_v2/stormlib/pklib/pklib.h
deleted file mode 100644
index 881262e3839..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/pklib/pklib.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*****************************************************************************/
-/* pklib.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Header file for PKWARE Data Compression Library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 31.03.03 1.00 Lad The first version of pkware.h */
-/*****************************************************************************/
-
-#ifndef __PKLIB_H__
-#define __PKLIB_H__
-
-#include "../StormPort.h"
-
-//-----------------------------------------------------------------------------
-// Defines
-
-#define CMP_BINARY 0 // Binary compression
-#define CMP_ASCII 1 // Ascii compression
-
-#define CMP_NO_ERROR 0
-#define CMP_INVALID_DICTSIZE 1
-#define CMP_INVALID_MODE 2
-#define CMP_BAD_DATA 3
-#define CMP_ABORT 4
-
-//-----------------------------------------------------------------------------
-// Define calling convention
-
-#ifndef PKEXPORT
-#define PKEXPORT //__cdecl // Use for normal __cdecl calling
-#endif
-//#define PKEXPORT __stdcall
-//#define PKEXPORT __fastcall
-
-//-----------------------------------------------------------------------------
-// Internal structures
-
-// Compression structure
-typedef struct
-{
- unsigned int offs0000; // 0000 :
- unsigned int out_bytes; // 0004 : # bytes available in out_buff
- unsigned int out_bits; // 0008 : # of bits available in the last out byte
- unsigned int dsize_bits; // 000C : Dict size : 4=0x400, 5=0x800, 6=0x1000
- unsigned int dsize_mask; // 0010 : Dict size : 0x0F=0x400, 0x1F=0x800, 0x3F=0x1000
- unsigned int ctype; // 0014 : Compression type (Ascii or binary)
- unsigned int dsize_bytes; // 0018 : Dictionary size in bytes
- unsigned char dist_bits[0x40]; // 001C : Distance bits
- unsigned char dist_codes[0x40]; // 005C : Distance codes
- unsigned char nChBits[0x306]; // 009C :
- unsigned short nChCodes[0x306]; // 03A2 :
- unsigned short offs09AE; // 09AE :
-
- void * param; // 09B0 : User parameter
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 9B4
- void (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8
-
- unsigned short offs09BC[0x204]; // 09BC :
- unsigned long offs0DC4; // 0DC4 :
- unsigned short offs0DC8[0x900]; // 0DC8 :
- unsigned short offs1FC8; // 1FC8 :
- char out_buff[0x802]; // 1FCA : Output (compressed) data
- unsigned char work_buff[0x2204]; // 27CC : Work buffer
- // + DICT_OFFSET => Dictionary
- // + UNCMP_OFFSET => Uncompressed data
- unsigned short offs49D0[0x2000]; // 49D0 :
-} TCmpStruct;
-
-#define CMP_BUFFER_SIZE sizeof(TCmpStruct) // Size of compression buffer
-
-
-// Decompression structure
-typedef struct
-{
- unsigned long offs0000; // 0000
- unsigned long ctype; // 0004 - Compression type (CMP_BINARY or CMP_ASCII)
- unsigned long outputPos; // 0008 - Position in output buffer
- unsigned long dsize_bits; // 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000)
- unsigned long dsize_mask; // 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000)
- unsigned long bit_buff; // 0014 - 16-bit buffer for processing input data
- unsigned long extra_bits; // 0018 - Number of extra (above 8) bits in bit buffer
- unsigned int in_pos; // 001C - Position in in_buff
- unsigned long in_bytes; // 0020 - Number of bytes in input buffer
- void * param; // 0024 - Custom parameter
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 0028
- void (*write_buf)(char *buf, unsigned int *size, void *param);// 002C
- unsigned char out_buff[0x2000]; // 0030 - Output circle buffer. Starting position is 0x1000
- unsigned char offs2030[0x204]; // 2030 - ???
- unsigned char in_buff[0x800]; // 2234 - Buffer for data to be decompressed
- unsigned char position1[0x100]; // 2A34 - Positions in buffers
- unsigned char position2[0x100]; // 2B34 - Positions in buffers
- unsigned char offs2C34[0x100]; // 2C34 - Buffer for
- unsigned char offs2D34[0x100]; // 2D34 - Buffer for
- unsigned char offs2E34[0x80]; // 2EB4 - Buffer for
- unsigned char offs2EB4[0x100]; // 2EB4 - Buffer for
- unsigned char ChBitsAsc[0x100]; // 2FB4 - Buffer for
- unsigned char DistBits[0x40]; // 30B4 - Numbers of bytes to skip copied block length
- unsigned char LenBits[0x10]; // 30F4 - Numbers of bits for skip copied block length
- unsigned char ExLenBits[0x10]; // 3104 - Number of valid bits for copied block
- unsigned short LenBase[0x10]; // 3114 - Buffer for
-} TDcmpStruct;
-
-#define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompress buffer
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-unsigned int PKEXPORT implode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param,
- unsigned int *type,
- unsigned int *dsize);
-
-
-unsigned int PKEXPORT explode(
- unsigned int (*read_buf)(char *buf, unsigned int *size, void *param),
- void (*write_buf)(char *buf, unsigned int *size, void *param),
- char *work_buf,
- void *param);
-
-// The original name "crc32" was changed to "crc32pk" due
-// to compatibility with zlib
-unsigned long PKEXPORT crc32pk(char *buffer, unsigned int *size, unsigned long *old_crc);
-
-#ifdef __cplusplus
- } // End of 'extern "C"' declaration
-#endif
-
-#endif // __PKLIB_H__
diff --git a/contrib/vmap_extractor_v2/stormlib/wave/wave.cpp b/contrib/vmap_extractor_v2/stormlib/wave/wave.cpp
deleted file mode 100644
index 936525f4eae..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/wave/wave.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/*****************************************************************************/
-/* wave.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* This module contains decompression methods used by Storm.dll to decompress*/
-/* WAVe files. Thanks to Tom Amigo for releasing his sources. */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
-/* 20.05.03 2.00 Lad Added compression */
-/* 19.11.03 2.01 Dan Big endian handling */
-/*****************************************************************************/
-
-#include "wave.h"
-
-//------------------------------------------------------------------------------
-// Structures
-
-union TByteAndWordPtr
-{
- short * pw;
- unsigned char * pb;
-};
-
-union TWordAndByteArray
-{
- short w;
- unsigned char b[2];
-};
-
-//-----------------------------------------------------------------------------
-// Tables necessary dor decompression
-
-static long Table1503F120[] =
-{
- 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
- 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
- 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
- 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008
-};
-
-static long Table1503F1A0[] =
-{
- 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
- 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
- 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
- 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
- 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
- 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
- 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
- 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
- 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
- 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
- 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
- 0x00007FFF
-};
-
-//----------------------------------------------------------------------------
-// CompressWave
-
-// 1500EF70
-int CompressWave(unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nChannels, int nCmpLevel)
-// ECX EDX
-{
- TWordAndByteArray Wcmp;
- TByteAndWordPtr out; // Pointer to the output buffer
- long SInt32Array1[2];
- long SInt32Array2[2];
- long SInt32Array3[2];
- long nBytesRemains = dwOutLength; // Number of bytes remaining
- long nWordsRemains; // Number of words remaining
-// unsigned char * pbSaveOutBuffer; // Copy of output buffer (actually not used)
- unsigned long dwBitBuff;
- unsigned long dwStopBit;
- unsigned long dwBit;
- unsigned long ebx;
- unsigned long esi;
- long nTableValue;
- long nOneWord;
- long var_1C;
- long var_2C;
- int nLength;
- int nIndex;
- int nValue;
-
- // If less than 2 bytes remain, don't decompress anything
-// pbSaveOutBuffer = pbOutBuffer;
- out.pb = pbOutBuffer;
- if(nBytesRemains < 2)
- return 2;
-
- Wcmp.b[1] = (unsigned char)(nCmpLevel - 1);
- Wcmp.b[0] = (unsigned char)0;
-
- *out.pw++ = BSWAP_INT16_SIGNED(Wcmp.w);
- if((out.pb - pbOutBuffer + (nChannels * 2)) > nBytesRemains)
- return (int)(out.pb - pbOutBuffer + (nChannels * 2));
-
- SInt32Array1[0] = SInt32Array1[1] = 0x2C;
-
- for(int i = 0; i < nChannels; i++)
- {
- nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++);
- *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
- SInt32Array2[i] = nOneWord;
- }
-
- // Weird. But it's there
- nLength = dwInLength;
- if(nLength < 0) // mov eax, dwInLength; cdq; sub eax, edx;
- nLength++;
-
- nLength = (nLength / 2) - (int)(out.pb - pbOutBuffer);
- nLength = (nLength < 0) ? 0 : nLength;
-
- nIndex = nChannels - 1; // edi
- nWordsRemains = dwInLength / 2; // eax
-
- // ebx - nChannels
- // ecx - pwOutPos
- for(int chnl = nChannels; chnl < nWordsRemains; chnl++)
- {
- // 1500F030
- if((out.pb - pbOutBuffer + 2) > nBytesRemains)
- return (int)(out.pb - pbOutBuffer + 2);
-
- // Switch index
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
-
- // Load one word from the input stream
- nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++); // ecx - nOneWord
- SInt32Array3[nIndex] = nOneWord;
-
- // esi - SInt32Array2[nIndex]
- // eax - nValue
- nValue = nOneWord - SInt32Array2[nIndex];
- nValue = (nValue < 0) ? ((nValue ^ 0xFFFFFFFF) + 1) : nValue;
-
- ebx = (nOneWord >= SInt32Array2[nIndex]) ? 0 : 0x40;
-
- // esi - SInt32Array2[nIndex]
- // edx - Table1503F1A0[SInt32Array2[nIndex]]
- // edi - (Table1503F1A0[SInt32Array1[nIndex]] >> nCmpLevel)
- nTableValue = Table1503F1A0[SInt32Array1[nIndex]];
- dwStopBit = (unsigned long)nCmpLevel;
-
- // edi - nIndex;
- if(nValue < (nTableValue >> nCmpLevel))
- {
- if(SInt32Array1[nIndex] != 0)
- SInt32Array1[nIndex]--;
- *out.pb++ = 0x80;
- }
- else
- {
- while(nValue > nTableValue * 2)
- {
- if(SInt32Array1[nIndex] >= 0x58 || nLength == 0)
- break;
-
- SInt32Array1[nIndex] += 8;
- if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
-
- nTableValue = Table1503F1A0[SInt32Array1[nIndex]];
- *out.pb++ = 0x81;
- nLength--;
- }
-
- var_2C = nTableValue >> Wcmp.b[1];
- dwBitBuff = 0;
-
- esi = (1 << (dwStopBit - 2));
- dwStopBit = (esi <= 0x20) ? esi : 0x20;
-
- for(var_1C = 0, dwBit = 1; ; dwBit <<= 1)
- {
-// esi = var_1C + nTableValue;
- if((var_1C + nTableValue) <= nValue)
- {
- var_1C += nTableValue;
- dwBitBuff |= dwBit;
- }
- if(dwBit == dwStopBit)
- break;
-
- nTableValue >>= 1;
- }
-
- nValue = SInt32Array2[nIndex];
- if(ebx != 0)
- {
- nValue -= (var_1C + var_2C);
- if(nValue < -32768)
- nValue = -32768;
- }
- else
- {
- nValue += (var_1C + var_2C);
- if(nValue > 32767)
- nValue = 32767;
- }
-
- SInt32Array2[nIndex] = nValue;
- *out.pb++ = (unsigned char)(dwBitBuff | ebx);
- nTableValue = Table1503F120[dwBitBuff & 0x1F];
- SInt32Array1[nIndex] = SInt32Array1[nIndex] + nTableValue;
- if(SInt32Array1[nIndex] < 0)
- SInt32Array1[nIndex] = 0;
- else if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
- }
- }
-
- return (int)(out.pb - pbOutBuffer);
-}
-
-//----------------------------------------------------------------------------
-// DecompressWave
-
-// 1500F230
-int DecompressWave(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels)
-{
- TByteAndWordPtr out; // Output buffer
- TByteAndWordPtr in;
- unsigned char * pbInBufferEnd = (pbInBuffer + dwInLength);
- long SInt32Array1[2];
- long SInt32Array2[2];
- long nOneWord;
- int dwOutLengthCopy = dwOutLength;
- int nIndex;
-
- SInt32Array1[0] = SInt32Array1[1] = 0x2C;
- out.pb = pbOutBuffer;
- in.pb = pbInBuffer;
- in.pw++;
-
- // Fill the Uint32Array2 array by channel values.
- for(int i = 0; i < nChannels; i++)
- {
- nOneWord = BSWAP_INT16_SIGNED(*in.pw++);
- SInt32Array2[i] = nOneWord;
- if(dwOutLengthCopy < 2)
- return (int)(out.pb - pbOutBuffer);
-
- *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
- dwOutLengthCopy -= sizeof(short);
- }
-
- // Get the initial index
- nIndex = nChannels - 1;
-
- // Perform the decompression
- while(in.pb < pbInBufferEnd)
- {
- unsigned char nOneByte = *in.pb++;
-
- // Switch index
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
-
- // 1500F2A2: Get one byte from input buffer
- if(nOneByte & 0x80)
- {
- switch(nOneByte & 0x7F)
- {
- case 0: // 1500F315
- if(SInt32Array1[nIndex] != 0)
- SInt32Array1[nIndex]--;
-
- if(dwOutLengthCopy < 2)
- return (int)(out.pb - pbOutBuffer);
-
- *out.pw++ = BSWAP_INT16_SIGNED((unsigned short)SInt32Array2[nIndex]);
- dwOutLength -= sizeof(unsigned short);
- break;
-
- case 1: // 1500F2E8
- SInt32Array1[nIndex] += 8;
- if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
-
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
- break;
-
- case 2: // 1500F41E
- break;
-
- default: // 1500F2C4
- SInt32Array1[nIndex] -= 8;
- if(SInt32Array1[nIndex] < 0)
- SInt32Array1[nIndex] = 0;
-
- if(nChannels == 2)
- nIndex = (nIndex == 0) ? 1 : 0;
- break;
- }
- }
- else
- {
- // 1500F349
- long temp1 = Table1503F1A0[SInt32Array1[nIndex]]; // EDI
- long temp2 = temp1 >> pbInBuffer[1]; // ESI
- long temp3 = SInt32Array2[nIndex]; // ECX
-
- if(nOneByte & 0x01) // EBX = nOneByte
- temp2 += (temp1 >> 0);
-
- if(nOneByte & 0x02)
- temp2 += (temp1 >> 1);
-
- if(nOneByte & 0x04)
- temp2 += (temp1 >> 2);
-
- if(nOneByte & 0x08)
- temp2 += (temp1 >> 3);
-
- if(nOneByte & 0x10)
- temp2 += (temp1 >> 4);
-
- if(nOneByte & 0x20)
- temp2 += (temp1 >> 5);
-
- if(nOneByte & 0x40)
- {
- temp3 = temp3 - temp2;
- if(temp3 <= -32768)
- temp3 = -32768;
- }
- else
- {
- temp3 = temp3 + temp2;
- if(temp3 >= 32767)
- temp3 = 32767;
- }
-
- SInt32Array2[nIndex] = temp3;
- if(dwOutLength < 2)
- break;
-
- // Store the output 16-bit value
- *out.pw++ = BSWAP_INT16_SIGNED((short)SInt32Array2[nIndex]);
- dwOutLength -= 2;
-
- SInt32Array1[nIndex] += Table1503F120[nOneByte & 0x1F];
-
- if(SInt32Array1[nIndex] < 0)
- SInt32Array1[nIndex] = 0;
- else if(SInt32Array1[nIndex] > 0x58)
- SInt32Array1[nIndex] = 0x58;
- }
- }
- return (int)(out.pb - pbOutBuffer);
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/wave/wave.h b/contrib/vmap_extractor_v2/stormlib/wave/wave.h
deleted file mode 100644
index 81b5add9cfc..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/wave/wave.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*****************************************************************************/
-/* Wave.h Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Header file for WAVe unplode functions */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 31.03.03 1.00 Lad The first version of Wave.h */
-/*****************************************************************************/
-
-#ifndef __WAVE_H__
-#define __WAVE_H__
-
-//-----------------------------------------------------------------------------
-// Functions
-
-#include "../StormPort.h"
-
-int CompressWave (unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nCmpType, int nChannels);
-int DecompressWave(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels);
-
-#endif // __WAVE_H__
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/ChangeLog b/contrib/vmap_extractor_v2/stormlib/zlib/ChangeLog
deleted file mode 100644
index bf2e3f925bc..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/ChangeLog
+++ /dev/null
@@ -1,481 +0,0 @@
-
- ChangeLog file for zlib
-
-Changes in 1.1.4 (11 March 2002)
-- ZFREE was repeated on same allocation on some error conditions.
- This creates a security problem described in
- http://www.zlib.org/advisory-2002-03-11.txt
-- Returned incorrect error (Z_MEM_ERROR) on some invalid data
-- Avoid accesses before window for invalid distances with inflate window
- less than 32K.
-- force windowBits > 8 to avoid a bug in the encoder for a window size
- of 256 bytes. (A complete fix will be available in 1.1.5).
-
-Changes in 1.1.3 (9 July 1998)
-- fix "an inflate input buffer bug that shows up on rare but persistent
- occasions" (Mark)
-- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
-- fix gzseek(..., SEEK_SET) in write mode
-- fix crc check after a gzeek (Frank Faubert)
-- fix miniunzip when the last entry in a zip file is itself a zip file
- (J Lillge)
-- add contrib/asm586 and contrib/asm686 (Brian Raiter)
- See http://www.muppetlabs.com/~breadbox/software/assembly.html
-- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
-- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
-- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
-- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
-- added a FAQ file
-
-- Support gzdopen on Mac with Metrowerks (Jason Linhart)
-- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
-- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
-- avoid some warnings with Borland C (Tom Tanner)
-- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
-- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
-- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
-- use libdir and includedir in Makefile.in (Tim Mooney)
-- support shared libraries on OSF1 V4 (Tim Mooney)
-- remove so_locations in "make clean" (Tim Mooney)
-- fix maketree.c compilation error (Glenn, Mark)
-- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
-- new Makefile.riscos (Rich Walker)
-- initialize static descriptors in trees.c for embedded targets (Nick Smith)
-- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
-- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
-- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
-- fix maketree.c to allow clean compilation of inffixed.h (Mark)
-- fix parameter check in deflateCopy (Gunther Nikl)
-- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
-- Many portability patches by Christian Spieler:
- . zutil.c, zutil.h: added "const" for zmem*
- . Make_vms.com: fixed some typos
- . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
- . msdos/Makefile.msc: remove "default rtl link library" info from obj files
- . msdos/Makefile.*: use model-dependent name for the built zlib library
- . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
- new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
-- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
-- replace __far with _far for better portability (Christian Spieler, Tom Lane)
-- fix test for errno.h in configure (Tim Newsham)
-
-Changes in 1.1.2 (19 March 98)
-- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
- See http://www.winimage.com/zLibDll/unzip.html
-- preinitialize the inflate tables for fixed codes, to make the code
- completely thread safe (Mark)
-- some simplifications and slight speed-up to the inflate code (Mark)
-- fix gzeof on non-compressed files (Allan Schrum)
-- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
-- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
-- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
-- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
-- do not wrap extern "C" around system includes (Tom Lane)
-- mention zlib binding for TCL in README (Andreas Kupries)
-- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
-- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
-- allow "configure --prefix $HOME" (Tim Mooney)
-- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
-- move Makefile.sas to amiga/Makefile.sas
-
-Changes in 1.1.1 (27 Feb 98)
-- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
-- remove block truncation heuristic which had very marginal effect for zlib
- (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
- compression ratio on some files. This also allows inlining _tr_tally for
- matches in deflate_slow.
-- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
-
-Changes in 1.1.0 (24 Feb 98)
-- do not return STREAM_END prematurely in inflate (John Bowler)
-- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
-- compile with -DFASTEST to get compression code optimized for speed only
-- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
-- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
- on Sun but significant on HP)
-
-- add a pointer to experimental unzip library in README (Gilles Vollant)
-- initialize variable gcc in configure (Chris Herborth)
-
-Changes in 1.0.9 (17 Feb 1998)
-- added gzputs and gzgets functions
-- do not clear eof flag in gzseek (Mark Diekhans)
-- fix gzseek for files in transparent mode (Mark Diekhans)
-- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
-- replace EXPORT with ZEXPORT to avoid conflict with other programs
-- added compress2 in zconf.h, zlib.def, zlib.dnt
-- new asm code from Gilles Vollant in contrib/asm386
-- simplify the inflate code (Mark):
- . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
- . ZALLOC the length list in inflate_trees_fixed() instead of using stack
- . ZALLOC the value area for huft_build() instead of using stack
- . Simplify Z_FINISH check in inflate()
-
-- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
-- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
-- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
- the declaration of FAR (Gilles VOllant)
-- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
-- read_buf buf parameter of type Bytef* instead of charf*
-- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
-- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
-- fix check for presence of directories in "make install" (Ian Willis)
-
-Changes in 1.0.8 (27 Jan 1998)
-- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
-- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
-- added compress2() to allow setting the compression level
-- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
-- use constant arrays for the static trees in trees.c instead of computing
- them at run time (thanks to Ken Raeburn for this suggestion). To create
- trees.h, compile with GEN_TREES_H and run "make test".
-- check return code of example in "make test" and display result
-- pass minigzip command line options to file_compress
-- simplifying code of inflateSync to avoid gcc 2.8 bug
-
-- support CC="gcc -Wall" in configure -s (QingLong)
-- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
-- fix test for shared library support to avoid compiler warnings
-- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
-- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
-- do not use fdopen for Metrowerks on Mac (Brad Pettit))
-- add checks for gzputc and gzputc in example.c
-- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
-- use const for the CRC table (Ken Raeburn)
-- fixed "make uninstall" for shared libraries
-- use Tracev instead of Trace in infblock.c
-- in example.c use correct compressed length for test_sync
-- suppress +vnocompatwarnings in configure for HPUX (not always supported)
-
-Changes in 1.0.7 (20 Jan 1998)
-- fix gzseek which was broken in write mode
-- return error for gzseek to negative absolute position
-- fix configure for Linux (Chun-Chung Chen)
-- increase stack space for MSC (Tim Wegner)
-- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
-- define EXPORTVA for gzprintf (Gilles Vollant)
-- added man page zlib.3 (Rick Rodgers)
-- for contrib/untgz, fix makedir() and improve Makefile
-
-- check gzseek in write mode in example.c
-- allocate extra buffer for seeks only if gzseek is actually called
-- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
-- add inflateSyncPoint in zconf.h
-- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
-
-Changes in 1.0.6 (19 Jan 1998)
-- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
- gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
-- Fix a deflate bug occuring only with compression level 0 (thanks to
- Andy Buckler for finding this one).
-- In minigzip, pass transparently also the first byte for .Z files.
-- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
-- check Z_FINISH in inflate (thanks to Marc Schluper)
-- Implement deflateCopy (thanks to Adam Costello)
-- make static libraries by default in configure, add --shared option.
-- move MSDOS or Windows specific files to directory msdos
-- suppress the notion of partial flush to simplify the interface
- (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
-- suppress history buffer provided by application to simplify the interface
- (this feature was not implemented anyway in 1.0.4)
-- next_in and avail_in must be initialized before calling inflateInit or
- inflateInit2
-- add EXPORT in all exported functions (for Windows DLL)
-- added Makefile.nt (thanks to Stephen Williams)
-- added the unsupported "contrib" directory:
- contrib/asm386/ by Gilles Vollant <info@winimage.com>
- 386 asm code replacing longest_match().
- contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
- A C++ I/O streams interface to the zlib gz* functions
- contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
- Another C++ I/O streams interface
- contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
- A very simple tar.gz file extractor using zlib
- contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
- How to use compress(), uncompress() and the gz* functions from VB.
-- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
- level) in minigzip (thanks to Tom Lane)
-
-- use const for rommable constants in deflate
-- added test for gzseek and gztell in example.c
-- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
-- add undocumented function zError to convert error code to string
- (for Tim Smithers)
-- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
-- Use default memcpy for Symantec MSDOS compiler.
-- Add EXPORT keyword for check_func (needed for Windows DLL)
-- add current directory to LD_LIBRARY_PATH for "make test"
-- create also a link for libz.so.1
-- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
-- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
-- added -soname for Linux in configure (Chun-Chung Chen,
-- assign numbers to the exported functions in zlib.def (for Windows DLL)
-- add advice in zlib.h for best usage of deflateSetDictionary
-- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
-- allow compilation with ANSI keywords only enabled for TurboC in large model
-- avoid "versionString"[0] (Borland bug)
-- add NEED_DUMMY_RETURN for Borland
-- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
-- allow compilation with CC
-- defined STDC for OS/2 (David Charlap)
-- limit external names to 8 chars for MVS (Thomas Lund)
-- in minigzip.c, use static buffers only for 16-bit systems
-- fix suffix check for "minigzip -d foo.gz"
-- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
-- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
-- added makelcc.bat for lcc-win32 (Tom St Denis)
-- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
-- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
-- check for unistd.h in configure (for off_t)
-- remove useless check parameter in inflate_blocks_free
-- avoid useless assignment of s->check to itself in inflate_blocks_new
-- do not flush twice in gzclose (thanks to Ken Raeburn)
-- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
-- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
-- work around buggy fclose on pipes for HP/UX
-- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
-- fix configure if CC is already equal to gcc
-
-Changes in 1.0.5 (3 Jan 98)
-- Fix inflate to terminate gracefully when fed corrupted or invalid data
-- Use const for rommable constants in inflate
-- Eliminate memory leaks on error conditions in inflate
-- Removed some vestigial code in inflate
-- Update web address in README
-
-Changes in 1.0.4 (24 Jul 96)
-- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
- bit, so the decompressor could decompress all the correct data but went
- on to attempt decompressing extra garbage data. This affected minigzip too.
-- zlibVersion and gzerror return const char* (needed for DLL)
-- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
-- use z_error only for DEBUG (avoid problem with DLLs)
-
-Changes in 1.0.3 (2 Jul 96)
-- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
- small and medium models; this makes the library incompatible with previous
- versions for these models. (No effect in large model or on other systems.)
-- return OK instead of BUF_ERROR if previous deflate call returned with
- avail_out as zero but there is nothing to do
-- added memcmp for non STDC compilers
-- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
-- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
-- better check for 16-bit mode MSC (avoids problem with Symantec)
-
-Changes in 1.0.2 (23 May 96)
-- added Windows DLL support
-- added a function zlibVersion (for the DLL support)
-- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
-- Bytef is define's instead of typedef'd only for Borland C
-- avoid reading uninitialized memory in example.c
-- mention in README that the zlib format is now RFC1950
-- updated Makefile.dj2
-- added algorithm.doc
-
-Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
-- fix array overlay in deflate.c which sometimes caused bad compressed data
-- fix inflate bug with empty stored block
-- fix MSDOS medium model which was broken in 0.99
-- fix deflateParams() which could generated bad compressed data.
-- Bytef is define'd instead of typedef'ed (work around Borland bug)
-- added an INDEX file
-- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
- Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
-- speed up adler32 for modern machines without auto-increment
-- added -ansi for IRIX in configure
-- static_init_done in trees.c is an int
-- define unlink as delete for VMS
-- fix configure for QNX
-- add configure branch for SCO and HPUX
-- avoid many warnings (unused variables, dead assignments, etc...)
-- no fdopen for BeOS
-- fix the Watcom fix for 32 bit mode (define FAR as empty)
-- removed redefinition of Byte for MKWERKS
-- work around an MWKERKS bug (incorrect merge of all .h files)
-
-Changes in 0.99 (27 Jan 96)
-- allow preset dictionary shared between compressor and decompressor
-- allow compression level 0 (no compression)
-- add deflateParams in zlib.h: allow dynamic change of compression level
- and compression strategy.
-- test large buffers and deflateParams in example.c
-- add optional "configure" to build zlib as a shared library
-- suppress Makefile.qnx, use configure instead
-- fixed deflate for 64-bit systems (detected on Cray)
-- fixed inflate_blocks for 64-bit systems (detected on Alpha)
-- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
-- always return Z_BUF_ERROR when deflate() has nothing to do
-- deflateInit and inflateInit are now macros to allow version checking
-- prefix all global functions and types with z_ with -DZ_PREFIX
-- make falloc completely reentrant (inftrees.c)
-- fixed very unlikely race condition in ct_static_init
-- free in reverse order of allocation to help memory manager
-- use zlib-1.0/* instead of zlib/* inside the tar.gz
-- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
- -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
-- allow gzread on concatenated .gz files
-- deflateEnd now returns Z_DATA_ERROR if it was premature
-- deflate is finally (?) fully deterministic (no matches beyond end of input)
-- Document Z_SYNC_FLUSH
-- add uninstall in Makefile
-- Check for __cpluplus in zlib.h
-- Better test in ct_align for partial flush
-- avoid harmless warnings for Borland C++
-- initialize hash_head in deflate.c
-- avoid warning on fdopen (gzio.c) for HP cc -Aa
-- include stdlib.h for STDC compilers
-- include errno.h for Cray
-- ignore error if ranlib doesn't exist
-- call ranlib twice for NeXTSTEP
-- use exec_prefix instead of prefix for libz.a
-- renamed ct_* as _tr_* to avoid conflict with applications
-- clear z->msg in inflateInit2 before any error return
-- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
-- fixed typo in zconf.h (_GNUC__ => __GNUC__)
-- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
-- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
-- in fcalloc, normalize pointer if size > 65520 bytes
-- don't use special fcalloc for 32 bit Borland C++
-- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
-- use Z_BINARY instead of BINARY
-- document that gzclose after gzdopen will close the file
-- allow "a" as mode in gzopen.
-- fix error checking in gzread
-- allow skipping .gz extra-field on pipes
-- added reference to Perl interface in README
-- put the crc table in FAR data (I dislike more and more the medium model :)
-- added get_crc_table
-- added a dimension to all arrays (Borland C can't count).
-- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
-- guard against multiple inclusion of *.h (for precompiled header on Mac)
-- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
-- don't use unsized arrays to avoid silly warnings by Visual C++:
- warning C4746: 'inflate_mask' : unsized array treated as '__far'
- (what's wrong with far data in far model?).
-- define enum out of inflate_blocks_state to allow compilation with C++
-
-Changes in 0.95 (16 Aug 95)
-- fix MSDOS small and medium model (now easier to adapt to any compiler)
-- inlined send_bits
-- fix the final (:-) bug for deflate with flush (output was correct but
- not completely flushed in rare occasions).
-- default window size is same for compression and decompression
- (it's now sufficient to set MAX_WBITS in zconf.h).
-- voidp -> voidpf and voidnp -> voidp (for consistency with other
- typedefs and because voidnp was not near in large model).
-
-Changes in 0.94 (13 Aug 95)
-- support MSDOS medium model
-- fix deflate with flush (could sometimes generate bad output)
-- fix deflateReset (zlib header was incorrectly suppressed)
-- added support for VMS
-- allow a compression level in gzopen()
-- gzflush now calls fflush
-- For deflate with flush, flush even if no more input is provided.
-- rename libgz.a as libz.a
-- avoid complex expression in infcodes.c triggering Turbo C bug
-- work around a problem with gcc on Alpha (in INSERT_STRING)
-- don't use inline functions (problem with some gcc versions)
-- allow renaming of Byte, uInt, etc... with #define.
-- avoid warning about (unused) pointer before start of array in deflate.c
-- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
-- avoid reserved word 'new' in trees.c
-
-Changes in 0.93 (25 June 95)
-- temporarily disable inline functions
-- make deflate deterministic
-- give enough lookahead for PARTIAL_FLUSH
-- Set binary mode for stdin/stdout in minigzip.c for OS/2
-- don't even use signed char in inflate (not portable enough)
-- fix inflate memory leak for segmented architectures
-
-Changes in 0.92 (3 May 95)
-- don't assume that char is signed (problem on SGI)
-- Clear bit buffer when starting a stored block
-- no memcpy on Pyramid
-- suppressed inftest.c
-- optimized fill_window, put longest_match inline for gcc
-- optimized inflate on stored blocks.
-- untabify all sources to simplify patches
-
-Changes in 0.91 (2 May 95)
-- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
-- Document the memory requirements in zconf.h
-- added "make install"
-- fix sync search logic in inflateSync
-- deflate(Z_FULL_FLUSH) now works even if output buffer too short
-- after inflateSync, don't scare people with just "lo world"
-- added support for DJGPP
-
-Changes in 0.9 (1 May 95)
-- don't assume that zalloc clears the allocated memory (the TurboC bug
- was Mark's bug after all :)
-- let again gzread copy uncompressed data unchanged (was working in 0.71)
-- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
-- added a test of inflateSync in example.c
-- moved MAX_WBITS to zconf.h because users might want to change that.
-- document explicitly that zalloc(64K) on MSDOS must return a normalized
- pointer (zero offset)
-- added Makefiles for Microsoft C, Turbo C, Borland C++
-- faster crc32()
-
-Changes in 0.8 (29 April 95)
-- added fast inflate (inffast.c)
-- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
- is incompatible with previous versions of zlib which returned Z_OK.
-- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
- (actually that was not a compiler bug, see 0.81 above)
-- gzread no longer reads one extra byte in certain cases
-- In gzio destroy(), don't reference a freed structure
-- avoid many warnings for MSDOS
-- avoid the ERROR symbol which is used by MS Windows
-
-Changes in 0.71 (14 April 95)
-- Fixed more MSDOS compilation problems :( There is still a bug with
- TurboC large model.
-
-Changes in 0.7 (14 April 95)
-- Added full inflate support.
-- Simplified the crc32() interface. The pre- and post-conditioning
- (one's complement) is now done inside crc32(). WARNING: this is
- incompatible with previous versions; see zlib.h for the new usage.
-
-Changes in 0.61 (12 April 95)
-- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
-
-Changes in 0.6 (11 April 95)
-- added minigzip.c
-- added gzdopen to reopen a file descriptor as gzFile
-- added transparent reading of non-gziped files in gzread.
-- fixed bug in gzread (don't read crc as data)
-- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
-- don't allocate big arrays in the stack (for MSDOS)
-- fix some MSDOS compilation problems
-
-Changes in 0.5:
-- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
- not yet Z_FULL_FLUSH.
-- support decompression but only in a single step (forced Z_FINISH)
-- added opaque object for zalloc and zfree.
-- added deflateReset and inflateReset
-- added a variable zlib_version for consistency checking.
-- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
- Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
-
-Changes in 0.4:
-- avoid "zip" everywhere, use zlib instead of ziplib.
-- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
- if compression method == 8.
-- added adler32 and crc32
-- renamed deflateOptions as deflateInit2, call one or the other but not both
-- added the method parameter for deflateInit2.
-- added inflateInit2
-- simplied considerably deflateInit and inflateInit by not supporting
- user-provided history buffer. This is supported only in deflateInit2
- and inflateInit2.
-
-Changes in 0.3:
-- prefix all macro names with Z_
-- use Z_FINISH instead of deflateEnd to finish compression.
-- added Z_HUFFMAN_ONLY
-- added gzerror()
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/FAQ b/contrib/vmap_extractor_v2/stormlib/zlib/FAQ
deleted file mode 100644
index 47a7d60c6de..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/FAQ
+++ /dev/null
@@ -1,100 +0,0 @@
-
- Frequently Asked Questions about zlib
-
-
-If your question is not there, please check the zlib home page
-http://www.zlib.org which may have more recent information.
-The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
-
-
- 1. Is zlib Y2K-compliant?
-
- Yes. zlib doesn't handle dates.
-
- 2. Where can I get a Windows DLL version?
-
- The zlib sources can be compiled without change to produce a DLL. If you
- want a precompiled DLL, see http://www.winimage.com/zLibDll/ . Questions
- about the zlib DLL should be sent to Gilles Vollant (info@winimage.com).
-
- 3. Where can I get a Visual Basic interface to zlib?
-
- See
- * http://www.winimage.com/zLibDll/cmp-z-it.zip
- * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
- * contrib/visual-basic.txt in the zlib distribution
-
- 4. compress() returns Z_BUF_ERROR
-
- Make sure that before the call of compress, the length of the compressed
- buffer is equal to the total size of the compressed buffer and not
- zero. For Visual Basic, check that this parameter is passed by reference
- ("as any"), not by value ("as long").
-
- 5. deflate() or inflate() returns Z_BUF_ERROR
-
- Before making the call, make sure that avail_in and avail_out are not
- zero. When setting the parameter flush equal to Z_FINISH, also make sure
- that avail_out is big enough to allow processing all pending input.
-
- 6. Where's the zlib documentation (man pages, etc.)?
-
- It's in zlib.h for the moment, and Francis S. Lin has converted it to a
- web page zlib.html. Volunteers to transform this to Unix-style man pages,
- please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage
- are in the files example.c and minigzip.c.
-
- 7. Why don't you use GNU autoconf or libtool or ...?
-
- Because we would like to keep zlib as a very small and simple
- package. zlib is rather portable and doesn't need much configuration.
-
- 8. I found a bug in zlib.
-
- Most of the time, such problems are due to an incorrect usage of
- zlib. Please try to reproduce the problem with a small program and send
- the corresponding source to us at zlib@gzip.org . Do not send
- multi-megabyte data files without prior agreement.
-
- 9. Why do I get "undefined reference to gzputc"?
-
- If "make test" produces something like
-
- example.o(.text+0x154): undefined reference to `gzputc'
-
- check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
- /usr/X11R6/lib. Remove any old versions, then do "make install".
-
-10. I need a Delphi interface to zlib.
-
- See the directories contrib/delphi and contrib/delphi2 in the zlib
- distribution.
-
-11. Can zlib handle .zip archives?
-
- See the directory contrib/minizip in the zlib distribution.
-
-12. Can zlib handle .Z files?
-
- No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
- the code of uncompress on your own.
-
-13. How can I make a Unix shared library?
-
- make clean
- ./configure -s
- make
-
-14. Why does "make test" fail on Mac OS X?
-
- Mac OS X already includes zlib as a shared library, and so -lz links the
- shared library instead of the one that the "make" compiled. For zlib
- 1.1.3, the two are incompatible due to different compile-time
- options. Simply change the -lz in the Makefile to libz.a, and it will use
- the compiled library instead of the shared one and the "make test" will
- succeed.
-
-15. I have a question about OttoPDF
-
- We are not the authors of OttoPDF. The real author is on the OttoPDF web
- site Joel Hainley jhainley@myndkryme.com.
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/INDEX b/contrib/vmap_extractor_v2/stormlib/zlib/INDEX
deleted file mode 100644
index 8a245766402..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/INDEX
+++ /dev/null
@@ -1,86 +0,0 @@
-ChangeLog history of changes
-INDEX this file
-FAQ Frequently Asked Questions about zlib
-Make_vms.com script for Vax/VMS
-Makefile makefile for Unix (generated by configure)
-Makefile.in makefile for Unix (template for configure)
-Makefile.riscos makefile for RISCOS
-README guess what
-algorithm.txt description of the (de)compression algorithm
-configure configure script for Unix
-descrip.mms makefile for Vax/VMS
-zlib.3 mini man page for zlib (volunteers to write full
- man pages from zlib.h welcome. write to jloup@gzip.org)
-
-amiga/Makefile.sas makefile for Amiga SAS/C
-amiga/Makefile.pup makefile for Amiga powerUP SAS/C PPC
-
-msdos/Makefile.w32 makefile for Microsoft Visual C++ 32-bit
-msdos/Makefile.b32 makefile for Borland C++ 32-bit
-msdos/Makefile.bor makefile for Borland C/C++ 16-bit
-msdos/Makefile.dj2 makefile for DJGPP 2.x
-msdos/Makefile.emx makefile for EMX 0.9c (32-bit DOS/OS2)
-msdos/Makefile.msc makefile for Microsoft C 16-bit
-msdos/Makefile.tc makefile for Turbo C
-msdos/Makefile.wat makefile for Watcom C
-msdos/zlib.def definition file for Windows DLL
-msdos/zlib.rc definition file for Windows DLL
-
-nt/Makefile.nt makefile for Windows NT
-nt/zlib.dnt definition file for Windows NT DLL
-nt/Makefile.emx makefile for EMX 0.9c/RSXNT 1.41 (Win32 Intel)
-nt/Makefile.gcc makefile for Windows NT using GCC (mingw32)
-
-
- zlib public header files (must be kept):
-zconf.h
-zlib.h
-
- private source files used to build the zlib library:
-adler32.c
-compress.c
-crc32.c
-deflate.c
-deflate.h
-gzio.c
-infblock.c
-infblock.h
-infcodes.c
-infcodes.h
-inffast.c
-inffast.h
-inflate.c
-inftrees.c
-inftrees.h
-infutil.c
-infutil.h
-maketree.c
-trees.c
-uncompr.c
-zutil.c
-zutil.h
-
- source files for sample programs:
-example.c
-minigzip.c
-
- unsupported contribution by third parties
-
-contrib/asm386/ by Gilles Vollant <info@winimage.com>
- 386 asm code replacing longest_match().
-
-contrib/minizip/ by Gilles Vollant <info@winimage.com>
- Mini zip and unzip based on zlib
- See http://www.winimage.com/zLibDll/unzip.html
-
-contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
- A C++ I/O streams interface to the zlib gz* functions
-
-contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
- Another C++ I/O streams interface
-
-contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
- A very simple tar.gz extractor using zlib
-
-contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
- How to use compress(), uncompress() and the gz* functions from VB.
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/Makefile.riscos b/contrib/vmap_extractor_v2/stormlib/zlib/Makefile.riscos
deleted file mode 100644
index d97f4492370..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/Makefile.riscos
+++ /dev/null
@@ -1,151 +0,0 @@
-# Project: zlib_1_03
-# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
-# test works out-of-the-box, installs `somewhere' on demand
-
-# Toolflags:
-CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah
-C++flags = -c -depend !Depend -IC: -throwback
-Linkflags = -aif -c++ -o $@
-ObjAsmflags = -throwback -NoCache -depend !Depend
-CMHGflags =
-LibFileflags = -c -l -o $@
-Squeezeflags = -o $@
-
-# change the line below to where _you_ want the library installed.
-libdest = lib:zlib
-
-# Final targets:
-@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
- @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
- @.o.uncompr @.o.zutil
- LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
- @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
- @.o.trees @.o.uncompr @.o.zutil
-test: @.minigzip @.example @.lib
- @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV
- @echo running tests: hang on.
- @/@.minigzip -f -9 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -f -1 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -h -9 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -h -1 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -9 libc
- @/@.minigzip -d libc-gz
- @/@.minigzip -1 libc
- @/@.minigzip -d libc-gz
- @diff @.lib @.libc
- @echo that should have reported '@.lib and @.libc identical' if you have diff.
- @/@.example @.fred @.fred
- @echo that will have given lots of hello!'s.
-
-@.minigzip: @.o.minigzip @.lib C:o.Stubs
- Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
-@.example: @.o.example @.lib C:o.Stubs
- Link $(Linkflags) @.o.example @.lib C:o.Stubs
-
-install: @.lib
- cdir $(libdest)
- cdir $(libdest).h
- @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
- @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
- @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV
- @echo okay, installed zlib in $(libdest)
-
-clean:; remove @.minigzip
- remove @.example
- remove @.libc
- -wipe @.o.* F~r~cV
- remove @.fred
-
-# User-editable dependencies:
-.c.o:
- cc $(ccflags) -o $@ $<
-
-# Static dependencies:
-
-# Dynamic dependencies:
-o.example: c.example
-o.example: h.zlib
-o.example: h.zconf
-o.minigzip: c.minigzip
-o.minigzip: h.zlib
-o.minigzip: h.zconf
-o.adler32: c.adler32
-o.adler32: h.zlib
-o.adler32: h.zconf
-o.compress: c.compress
-o.compress: h.zlib
-o.compress: h.zconf
-o.crc32: c.crc32
-o.crc32: h.zlib
-o.crc32: h.zconf
-o.deflate: c.deflate
-o.deflate: h.deflate
-o.deflate: h.zutil
-o.deflate: h.zlib
-o.deflate: h.zconf
-o.gzio: c.gzio
-o.gzio: h.zutil
-o.gzio: h.zlib
-o.gzio: h.zconf
-o.infblock: c.infblock
-o.infblock: h.zutil
-o.infblock: h.zlib
-o.infblock: h.zconf
-o.infblock: h.infblock
-o.infblock: h.inftrees
-o.infblock: h.infcodes
-o.infblock: h.infutil
-o.infcodes: c.infcodes
-o.infcodes: h.zutil
-o.infcodes: h.zlib
-o.infcodes: h.zconf
-o.infcodes: h.inftrees
-o.infcodes: h.infblock
-o.infcodes: h.infcodes
-o.infcodes: h.infutil
-o.infcodes: h.inffast
-o.inffast: c.inffast
-o.inffast: h.zutil
-o.inffast: h.zlib
-o.inffast: h.zconf
-o.inffast: h.inftrees
-o.inffast: h.infblock
-o.inffast: h.infcodes
-o.inffast: h.infutil
-o.inffast: h.inffast
-o.inflate: c.inflate
-o.inflate: h.zutil
-o.inflate: h.zlib
-o.inflate: h.zconf
-o.inflate: h.infblock
-o.inftrees: c.inftrees
-o.inftrees: h.zutil
-o.inftrees: h.zlib
-o.inftrees: h.zconf
-o.inftrees: h.inftrees
-o.inftrees: h.inffixed
-o.infutil: c.infutil
-o.infutil: h.zutil
-o.infutil: h.zlib
-o.infutil: h.zconf
-o.infutil: h.infblock
-o.infutil: h.inftrees
-o.infutil: h.infcodes
-o.infutil: h.infutil
-o.trees: c.trees
-o.trees: h.deflate
-o.trees: h.zutil
-o.trees: h.zlib
-o.trees: h.zconf
-o.trees: h.trees
-o.uncompr: c.uncompr
-o.uncompr: h.zlib
-o.uncompr: h.zconf
-o.zutil: c.zutil
-o.zutil: h.zutil
-o.zutil: h.zlib
-o.zutil: h.zconf
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/README b/contrib/vmap_extractor_v2/stormlib/zlib/README
deleted file mode 100644
index 29d67146a9b..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/README
+++ /dev/null
@@ -1,147 +0,0 @@
-zlib 1.1.4 is a general purpose data compression library. All the code
-is thread safe. 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). These documents are also available in
-other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
-
-All functions of the compression library are documented in the file zlib.h
-(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
-example of the library is given in the file example.c which also tests that
-the library is working correctly. Another example is given in the file
-minigzip.c. The compression library itself is composed of all source files
-except example.c and minigzip.c.
-
-To compile all files and run the test program, follow the instructions
-given at the top of Makefile. In short "make test; make install"
-should work for most machines. For Unix: "./configure; make test; make install"
-For MSDOS, use one of the special makefiles such as Makefile.msc.
-For VMS, use Make_vms.com or descrip.mms.
-
-Questions about zlib should be sent to <zlib@gzip.org>, or to
-Gilles Vollant <info@winimage.com> for the Windows DLL version.
-The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
-Before reporting a problem, please check this site to verify that
-you have the latest version of zlib; otherwise get the latest version and
-check whether the problem still exists or not.
-
-PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
-before asking for help.
-
-Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
-issue of Dr. Dobb's Journal; a copy of the article is available in
-http://dogma.net/markn/articles/zlibtool/zlibtool.htm
-
-The changes made in version 1.1.4 are documented in the file ChangeLog.
-The only changes made since 1.1.3 are bug corrections:
-
-- ZFREE was repeated on same allocation on some error conditions.
- This creates a security problem described in
- http://www.zlib.org/advisory-2002-03-11.txt
-- Returned incorrect error (Z_MEM_ERROR) on some invalid data
-- Avoid accesses before window for invalid distances with inflate window
- less than 32K.
-- force windowBits > 8 to avoid a bug in the encoder for a window size
- of 256 bytes. (A complete fix will be available in 1.1.5).
-
-The beta version 1.1.5beta includes many more changes. A new official
-version 1.1.5 will be released as soon as extensive testing has been
-completed on it.
-
-
-Unsupported third party contributions are provided in directory "contrib".
-
-A Java implementation of zlib is available in the Java Development Kit
-http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
-See the zlib home page http://www.zlib.org for details.
-
-A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
-is in the CPAN (Comprehensive Perl Archive Network) sites
-http://www.cpan.org/modules/by-module/Compress/
-
-A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
-is available in Python 1.5 and later versions, see
-http://www.python.org/doc/lib/module-zlib.html
-
-A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
-is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
-
-An experimental package to read and write files in .zip format,
-written on top of zlib by Gilles Vollant <info@winimage.com>, is
-available at http://www.winimage.com/zLibDll/unzip.html
-and also in the contrib/minizip directory of zlib.
-
-
-Notes for some targets:
-
-- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
- and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
- The zlib DLL support was initially done by Alessandro Iacopetti and is
- now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
- home page at http://www.winimage.com/zLibDll
-
- From Visual Basic, you can call the DLL functions which do not take
- a structure as argument: compress, uncompress and all gz* functions.
- See contrib/visual-basic.txt for more information, or get
- http://www.tcfb.com/dowseware/cmp-z-it.zip
-
-- For 64-bit Irix, deflate.c must be compiled without any optimization.
- With -O, one libpng test fails. The test works in 32 bit mode (with
- the -n32 compiler flag). The compiler bug has been reported to SGI.
-
-- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
- it works when compiled with cc.
-
-- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
- is necessary to get gzprintf working correctly. This is done by configure.
-
-- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
- with other compilers. Use "make test" to check your compiler.
-
-- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
-
-- For Turbo C the small model is supported only with reduced performance to
- avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-
-- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
- Per Harald Myrvang <perm@stud.cs.uit.no>
-
-
-Acknowledgments:
-
- The deflate format used by zlib was defined by Phil Katz. The deflate
- and zlib specifications were written by L. Peter Deutsch. Thanks to all the
- people who reported problems and suggested various improvements in zlib;
- they are too numerous to cite here.
-
-Copyright notice:
-
- (C) 1995-2002 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
-
-If you use the zlib library in a product, we would appreciate *not*
-receiving lengthy legal documents to sign. The sources are provided
-for free but without warranty of any kind. The library has been
-entirely written by Jean-loup Gailly and Mark Adler; it does not
-include third-party code.
-
-If you redistribute modified sources, we would appreciate that you include
-in the file ChangeLog history information documenting your changes.
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/adler32.c b/contrib/vmap_extractor_v2/stormlib/zlib/adler32.c
deleted file mode 100644
index fae88b65593..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/adler32.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == Z_NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- buf += 16;
- k -= 16;
- }
- if (k != 0) do {
- s1 += *buf++;
- s2 += s1;
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/algorithm.txt b/contrib/vmap_extractor_v2/stormlib/zlib/algorithm.txt
deleted file mode 100644
index cdc830b5deb..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/algorithm.txt
+++ /dev/null
@@ -1,213 +0,0 @@
-1. Compression algorithm (deflate)
-
-The deflation algorithm used by gzip (also zip and zlib) is a variation of
-LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
-the input data. The second occurrence of a string is replaced by a
-pointer to the previous string, in the form of a pair (distance,
-length). Distances are limited to 32K bytes, and lengths are limited
-to 258 bytes. When a string does not occur anywhere in the previous
-32K bytes, it is emitted as a sequence of literal bytes. (In this
-description, `string' must be taken as an arbitrary sequence of bytes,
-and is not restricted to printable characters.)
-
-Literals or match lengths are compressed with one Huffman tree, and
-match distances are compressed with another tree. The trees are stored
-in a compact form at the start of each block. The blocks can have any
-size (except that the compressed data for one block must fit in
-available memory). A block is terminated when deflate() determines that
-it would be useful to start another block with fresh trees. (This is
-somewhat similar to the behavior of LZW-based _compress_.)
-
-Duplicated strings are found using a hash table. All input strings of
-length 3 are inserted in the hash table. A hash index is computed for
-the next 3 bytes. If the hash chain for this index is not empty, all
-strings in the chain are compared with the current input string, and
-the longest match is selected.
-
-The hash chains are searched starting with the most recent strings, to
-favor small distances and thus take advantage of the Huffman encoding.
-The hash chains are singly linked. There are no deletions from the
-hash chains, the algorithm simply discards matches that are too old.
-
-To avoid a worst-case situation, very long hash chains are arbitrarily
-truncated at a certain length, determined by a runtime option (level
-parameter of deflateInit). So deflate() does not always find the longest
-possible match but generally finds a match which is long enough.
-
-deflate() also defers the selection of matches with a lazy evaluation
-mechanism. After a match of length N has been found, deflate() searches for
-a longer match at the next input byte. If a longer match is found, the
-previous match is truncated to a length of one (thus producing a single
-literal byte) and the process of lazy evaluation begins again. Otherwise,
-the original match is kept, and the next match search is attempted only N
-steps later.
-
-The lazy match evaluation is also subject to a runtime parameter. If
-the current match is long enough, deflate() reduces the search for a longer
-match, thus speeding up the whole process. If compression ratio is more
-important than speed, deflate() attempts a complete second search even if
-the first match is already long enough.
-
-The lazy match evaluation is not performed for the fastest compression
-modes (level parameter 1 to 3). For these fast modes, new strings
-are inserted in the hash table only when no match was found, or
-when the match is not too long. This degrades the compression ratio
-but saves time since there are both fewer insertions and fewer searches.
-
-
-2. Decompression algorithm (inflate)
-
-2.1 Introduction
-
-The real question is, given a Huffman tree, how to decode fast. The most
-important realization is that shorter codes are much more common than
-longer codes, so pay attention to decoding the short codes fast, and let
-the long codes take longer to decode.
-
-inflate() sets up a first level table that covers some number of bits of
-input less than the length of longest code. It gets that many bits from the
-stream, and looks it up in the table. The table will tell if the next
-code is that many bits or less and how many, and if it is, it will tell
-the value, else it will point to the next level table for which inflate()
-grabs more bits and tries to decode a longer code.
-
-How many bits to make the first lookup is a tradeoff between the time it
-takes to decode and the time it takes to build the table. If building the
-table took no time (and if you had infinite memory), then there would only
-be a first level table to cover all the way to the longest code. However,
-building the table ends up taking a lot longer for more bits since short
-codes are replicated many times in such a table. What inflate() does is
-simply to make the number of bits in the first table a variable, and set it
-for the maximum speed.
-
-inflate() sends new trees relatively often, so it is possibly set for a
-smaller first level table than an application that has only one tree for
-all the data. For inflate, which has 286 possible codes for the
-literal/length tree, the size of the first table is nine bits. Also the
-distance trees have 30 possible values, and the size of the first table is
-six bits. Note that for each of those cases, the table ended up one bit
-longer than the ``average'' code length, i.e. the code length of an
-approximately flat code which would be a little more than eight bits for
-286 symbols and a little less than five bits for 30 symbols. It would be
-interesting to see if optimizing the first level table for other
-applications gave values within a bit or two of the flat code size.
-
-
-2.2 More details on the inflate table lookup
-
-Ok, you want to know what this cleverly obfuscated inflate tree actually
-looks like. You are correct that it's not a Huffman tree. It is simply a
-lookup table for the first, let's say, nine bits of a Huffman symbol. The
-symbol could be as short as one bit or as long as 15 bits. If a particular
-symbol is shorter than nine bits, then that symbol's translation is duplicated
-in all those entries that start with that symbol's bits. For example, if the
-symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
-symbol is nine bits long, it appears in the table once.
-
-If the symbol is longer than nine bits, then that entry in the table points
-to another similar table for the remaining bits. Again, there are duplicated
-entries as needed. The idea is that most of the time the symbol will be short
-and there will only be one table look up. (That's whole idea behind data
-compression in the first place.) For the less frequent long symbols, there
-will be two lookups. If you had a compression method with really long
-symbols, you could have as many levels of lookups as is efficient. For
-inflate, two is enough.
-
-So a table entry either points to another table (in which case nine bits in
-the above example are gobbled), or it contains the translation for the symbol
-and the number of bits to gobble. Then you start again with the next
-ungobbled bit.
-
-You may wonder: why not just have one lookup table for how ever many bits the
-longest symbol is? The reason is that if you do that, you end up spending
-more time filling in duplicate symbol entries than you do actually decoding.
-At least for deflate's output that generates new trees every several 10's of
-kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
-would take too long if you're only decoding several thousand symbols. At the
-other extreme, you could make a new table for every bit in the code. In fact,
-that's essentially a Huffman tree. But then you spend two much time
-traversing the tree while decoding, even for short symbols.
-
-So the number of bits for the first lookup table is a trade of the time to
-fill out the table vs. the time spent looking at the second level and above of
-the table.
-
-Here is an example, scaled down:
-
-The code being decoded, with 10 symbols, from 1 to 6 bits long:
-
-A: 0
-B: 10
-C: 1100
-D: 11010
-E: 11011
-F: 11100
-G: 11101
-H: 11110
-I: 111110
-J: 111111
-
-Let's make the first table three bits long (eight entries):
-
-000: A,1
-001: A,1
-010: A,1
-011: A,1
-100: B,2
-101: B,2
-110: -> table X (gobble 3 bits)
-111: -> table Y (gobble 3 bits)
-
-Each entry is what the bits decode to and how many bits that is, i.e. how
-many bits to gobble. Or the entry points to another table, with the number of
-bits to gobble implicit in the size of the table.
-
-Table X is two bits long since the longest code starting with 110 is five bits
-long:
-
-00: C,1
-01: C,1
-10: D,2
-11: E,2
-
-Table Y is three bits long since the longest code starting with 111 is six
-bits long:
-
-000: F,2
-001: F,2
-010: G,2
-011: G,2
-100: H,2
-101: H,2
-110: I,3
-111: J,3
-
-So what we have here are three tables with a total of 20 entries that had to
-be constructed. That's compared to 64 entries for a single table. Or
-compared to 16 entries for a Huffman tree (six two entry tables and one four
-entry table). Assuming that the code ideally represents the probability of
-the symbols, it takes on the average 1.25 lookups per symbol. That's compared
-to one lookup for the single table, or 1.66 lookups per symbol for the
-Huffman tree.
-
-There, I think that gives you a picture of what's going on. For inflate, the
-meaning of a particular symbol is often more than just a letter. It can be a
-byte (a "literal"), or it can be either a length or a distance which
-indicates a base value and a number of bits to fetch after the code that is
-added to the base value. Or it might be the special end-of-block code. The
-data structures created in inftrees.c try to encode all that information
-compactly in the tables.
-
-
-Jean-loup Gailly Mark Adler
-jloup@gzip.org madler@alumni.caltech.edu
-
-
-References:
-
-[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
-Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
-pp. 337-343.
-
-``DEFLATE Compressed Data Format Specification'' available in
-ftp://ds.internic.net/rfc/rfc1951.txt
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.pup b/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.pup
deleted file mode 100644
index 6cfad1dc04a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.pup
+++ /dev/null
@@ -1,66 +0,0 @@
-# Amiga powerUP (TM) Makefile
-# makefile for libpng and SAS C V6.58/7.00 PPC compiler
-# Copyright (C) 1998 by Andreas R. Kleinert
-
-CC = scppc
-CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
- OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8
-LIBNAME = libzip.a
-AR = ppc-amigaos-ar
-AR_FLAGS = cr
-RANLIB = ppc-amigaos-ranlib
-LDFLAGS = -r -o
-LDLIBS = LIB:scppc.a
-LN = ppc-amigaos-ld
-RM = delete quiet
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example minigzip
-
-test: all
- example
- echo hello world | minigzip | minigzip -d
-
-$(LIBNAME): $(OBJS)
- $(AR) $(AR_FLAGS) $@ $(OBJS)
- $(RANLIB) $@
-
-example: example.o $(LIBNAME)
- $(LN) $(LDFLAGS) example LIB:c_ppc.o example.o $(LIBNAME) $(LDLIBS) LIB:end.o
-
-minigzip: minigzip.o $(LIBNAME)
- $(LN) $(LDFLAGS) minigzip LIB:c_ppc.o minigzip.o $(LIBNAME) $(LDLIBS) LIB:end.o
-
-clean:
- $(RM) *.o example minigzip $(LIBNAME) foo.gz
-
-zip:
- zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
- descrip.mms *.[ch]
-
-tgz:
- cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
- zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zutil.h zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: zutil.h zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h infblock.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.sas b/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.sas
deleted file mode 100644
index 5323e821708..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/amiga/Makefile.sas
+++ /dev/null
@@ -1,64 +0,0 @@
-# SMakefile for zlib
-# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
-# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
-# Amiga, SAS/C 6.56 & Smake
-
-CC=sc
-CFLAGS=OPT
-#CFLAGS=OPT CPU=68030
-#CFLAGS=DEBUG=LINE
-LDFLAGS=LIB z.lib
-
-SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
- NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: SCOPTIONS example minigzip
-
-test: all
- `cd`/example
- echo hello world | minigzip | minigzip -d
-
-install: z.lib
- copy zlib.h zconf.h INCLUDE: clone
- copy z.lib LIB: clone
-
-z.lib: $(OBJS)
- oml z.lib r $(OBJS)
-
-example: example.o z.lib
- $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
-
-minigzip: minigzip.o z.lib
- $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
-
-clean:
- -delete force quiet *.o example minigzip z.lib foo.gz *.lnk SCOPTIONS
-
-SCOPTIONS: Smakefile
- copy to $@ <from <
-$(SCOPTIONS)
-<
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zutil.h zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: zutil.h zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h infblock.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/compress.c b/contrib/vmap_extractor_v2/stormlib/zlib/compress.c
deleted file mode 100644
index 814bd9d6061..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/compress.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-
-/* ===========================================================================
- 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 0.1% larger than sourceLen plus
- 12 bytes. 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.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/README.contrib b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/README.contrib
deleted file mode 100644
index 7ad191cf598..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/README.contrib
+++ /dev/null
@@ -1,34 +0,0 @@
-All files under this contrib directory are UNSUPPORTED. There were
-provided by users of zlib and were not tested by the authors of zlib.
-Use at your own risk. Please contact the authors of the contributions
-for help about these, not the zlib authors. Thanks.
-
-
-asm386/ by Gilles Vollant <info@winimage.com>
- 386 asm code replacing longest_match(), for Visual C++ 4.2 and ML 6.11c
-
-asm586/ and asm686/ by Brian Raiter <breadbox@muppetlabs.com>
- asm code for Pentium and Pentium Pro
- See http://www.muppetlabs.com/~breadbox/software/assembly.html
-
-delphi/ by Bob Dellaca <bobdl@xtra.co.nz>
- Support for Delphi
-
-delphi2/ by Davide Moretti <dave@rimini.com>
- Another support for C++Builder and Delphi
-
-minizip/ by Gilles Vollant <info@winimage.com>
- Mini zip and unzip based on zlib
- See http://www.winimage.com/zLibDll/unzip.html
-
-iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
- A C++ I/O streams interface to the zlib gz* functions
-
-iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
- Another C++ I/O streams interface
-
-untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
- A very simple tar.gz file extractor using zlib
-
-visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
- How to use compress(), uncompress() and the gz* functions from VB.
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32.asm b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32.asm
deleted file mode 100644
index 28d527f47f8..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32.asm
+++ /dev/null
@@ -1,559 +0,0 @@
-;
-; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86
-; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
-; File written by Gilles Vollant, by modifiying the longest_match
-; from Jean-loup Gailly in deflate.c
-; It need wmask == 0x7fff
-; (assembly code is faster with a fixed wmask)
-;
-; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK)
-; I compile with : "ml /coff /Zi /c gvmat32.asm"
-;
-
-;uInt longest_match_7fff(s, cur_match)
-; deflate_state *s;
-; IPos cur_match; /* current match */
-
- NbStack equ 76
- cur_match equ dword ptr[esp+NbStack-0]
- str_s equ dword ptr[esp+NbStack-4]
-; 5 dword on top (ret,ebp,esi,edi,ebx)
- adrret equ dword ptr[esp+NbStack-8]
- pushebp equ dword ptr[esp+NbStack-12]
- pushedi equ dword ptr[esp+NbStack-16]
- pushesi equ dword ptr[esp+NbStack-20]
- pushebx equ dword ptr[esp+NbStack-24]
-
- chain_length equ dword ptr [esp+NbStack-28]
- limit equ dword ptr [esp+NbStack-32]
- best_len equ dword ptr [esp+NbStack-36]
- window equ dword ptr [esp+NbStack-40]
- prev equ dword ptr [esp+NbStack-44]
- scan_start equ word ptr [esp+NbStack-48]
- wmask equ dword ptr [esp+NbStack-52]
- match_start_ptr equ dword ptr [esp+NbStack-56]
- nice_match equ dword ptr [esp+NbStack-60]
- scan equ dword ptr [esp+NbStack-64]
-
- windowlen equ dword ptr [esp+NbStack-68]
- match_start equ dword ptr [esp+NbStack-72]
- strend equ dword ptr [esp+NbStack-76]
- NbStackAdd equ (NbStack-24)
-
- .386p
-
- name gvmatch
- .MODEL FLAT
-
-
-
-; all the +4 offsets are due to the addition of pending_buf_size (in zlib
-; in the deflate_state structure since the asm code was first written
-; (if you compile with zlib 1.0.4 or older, remove the +4).
-; Note : these value are good with a 8 bytes boundary pack structure
- dep_chain_length equ 70h+4
- dep_window equ 2ch+4
- dep_strstart equ 60h+4
- dep_prev_length equ 6ch+4
- dep_nice_match equ 84h+4
- dep_w_size equ 20h+4
- dep_prev equ 34h+4
- dep_w_mask equ 28h+4
- dep_good_match equ 80h+4
- dep_match_start equ 64h+4
- dep_lookahead equ 68h+4
-
-
-_TEXT segment
-
-IFDEF NOUNDERLINE
- public longest_match_7fff
-; public match_init
-ELSE
- public _longest_match_7fff
-; public _match_init
-ENDIF
-
- MAX_MATCH equ 258
- MIN_MATCH equ 3
- MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
-
-
-
-IFDEF NOUNDERLINE
-;match_init proc near
-; ret
-;match_init endp
-ELSE
-;_match_init proc near
-; ret
-;_match_init endp
-ENDIF
-
-
-IFDEF NOUNDERLINE
-longest_match_7fff proc near
-ELSE
-_longest_match_7fff proc near
-ENDIF
-
- mov edx,[esp+4]
-
-
-
- push ebp
- push edi
- push esi
- push ebx
-
- sub esp,NbStackAdd
-
-; initialize or check the variables used in match.asm.
- mov ebp,edx
-
-; chain_length = s->max_chain_length
-; if (prev_length>=good_match) chain_length >>= 2
- mov edx,[ebp+dep_chain_length]
- mov ebx,[ebp+dep_prev_length]
- cmp [ebp+dep_good_match],ebx
- ja noshr
- shr edx,2
-noshr:
-; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop
- inc edx
- mov edi,[ebp+dep_nice_match]
- mov chain_length,edx
- mov eax,[ebp+dep_lookahead]
- cmp eax,edi
-; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
- jae nolookaheadnicematch
- mov edi,eax
-nolookaheadnicematch:
-; best_len = s->prev_length
- mov best_len,ebx
-
-; window = s->window
- mov esi,[ebp+dep_window]
- mov ecx,[ebp+dep_strstart]
- mov window,esi
-
- mov nice_match,edi
-; scan = window + strstart
- add esi,ecx
- mov scan,esi
-; dx = *window
- mov dx,word ptr [esi]
-; bx = *(window+best_len-1)
- mov bx,word ptr [esi+ebx-1]
- add esi,MAX_MATCH-1
-; scan_start = *scan
- mov scan_start,dx
-; strend = scan + MAX_MATCH-1
- mov strend,esi
-; bx = scan_end = *(window+best_len-1)
-
-; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-; s->strstart - (IPos)MAX_DIST(s) : NIL;
-
- mov esi,[ebp+dep_w_size]
- sub esi,MIN_LOOKAHEAD
-; here esi = MAX_DIST(s)
- sub ecx,esi
- ja nodist
- xor ecx,ecx
-nodist:
- mov limit,ecx
-
-; prev = s->prev
- mov edx,[ebp+dep_prev]
- mov prev,edx
-
-;
- mov edx,dword ptr [ebp+dep_match_start]
- mov bp,scan_start
- mov eax,cur_match
- mov match_start,edx
-
- mov edx,window
- mov edi,edx
- add edi,best_len
- mov esi,prev
- dec edi
-; windowlen = window + best_len -1
- mov windowlen,edi
-
- jmp beginloop2
- align 4
-
-; here, in the loop
-; eax = ax = cur_match
-; ecx = limit
-; bx = scan_end
-; bp = scan_start
-; edi = windowlen (window + best_len -1)
-; esi = prev
-
-
-;// here; chain_length <=16
-normalbeg0add16:
- add chain_length,16
- jz exitloop
-normalbeg0:
- cmp word ptr[edi+eax],bx
- je normalbeg2noroll
-rcontlabnoroll:
-; cur_match = prev[cur_match & wmask]
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
- cmp ecx,eax
- jnb exitloop
-; if --chain_length != 0, go to exitloop
- dec chain_length
- jnz normalbeg0
- jmp exitloop
-
-normalbeg2noroll:
-; if (scan_start==*(cur_match+window)) goto normalbeg2
- cmp bp,word ptr[edx+eax]
- jne rcontlabnoroll
- jmp normalbeg2
-
-contloop3:
- mov edi,windowlen
-
-; cur_match = prev[cur_match & wmask]
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
- cmp ecx,eax
-jnbexitloopshort1:
- jnb exitloop
-; if --chain_length != 0, go to exitloop
-
-
-; begin the main loop
-beginloop2:
- sub chain_length,16+1
-; if chain_length <=16, don't use the unrolled loop
- jna normalbeg0add16
-
-do16:
- cmp word ptr[edi+eax],bx
- je normalbeg2dc0
-
-maccn MACRO lab
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
- cmp ecx,eax
- jnb exitloop
- cmp word ptr[edi+eax],bx
- je lab
- ENDM
-
-rcontloop0:
- maccn normalbeg2dc1
-
-rcontloop1:
- maccn normalbeg2dc2
-
-rcontloop2:
- maccn normalbeg2dc3
-
-rcontloop3:
- maccn normalbeg2dc4
-
-rcontloop4:
- maccn normalbeg2dc5
-
-rcontloop5:
- maccn normalbeg2dc6
-
-rcontloop6:
- maccn normalbeg2dc7
-
-rcontloop7:
- maccn normalbeg2dc8
-
-rcontloop8:
- maccn normalbeg2dc9
-
-rcontloop9:
- maccn normalbeg2dc10
-
-rcontloop10:
- maccn short normalbeg2dc11
-
-rcontloop11:
- maccn short normalbeg2dc12
-
-rcontloop12:
- maccn short normalbeg2dc13
-
-rcontloop13:
- maccn short normalbeg2dc14
-
-rcontloop14:
- maccn short normalbeg2dc15
-
-rcontloop15:
- and eax,7fffh
- mov ax,word ptr[esi+eax*2]
- cmp ecx,eax
- jnb exitloop
-
- sub chain_length,16
- ja do16
- jmp normalbeg0add16
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-normbeg MACRO rcontlab,valsub
-; if we are here, we know that *(match+best_len-1) == scan_end
- cmp bp,word ptr[edx+eax]
-; if (match != scan_start) goto rcontlab
- jne rcontlab
-; calculate the good chain_length, and we'll compare scan and match string
- add chain_length,16-valsub
- jmp iseq
- ENDM
-
-
-normalbeg2dc11:
- normbeg rcontloop11,11
-
-normalbeg2dc12:
- normbeg short rcontloop12,12
-
-normalbeg2dc13:
- normbeg short rcontloop13,13
-
-normalbeg2dc14:
- normbeg short rcontloop14,14
-
-normalbeg2dc15:
- normbeg short rcontloop15,15
-
-normalbeg2dc10:
- normbeg rcontloop10,10
-
-normalbeg2dc9:
- normbeg rcontloop9,9
-
-normalbeg2dc8:
- normbeg rcontloop8,8
-
-normalbeg2dc7:
- normbeg rcontloop7,7
-
-normalbeg2dc6:
- normbeg rcontloop6,6
-
-normalbeg2dc5:
- normbeg rcontloop5,5
-
-normalbeg2dc4:
- normbeg rcontloop4,4
-
-normalbeg2dc3:
- normbeg rcontloop3,3
-
-normalbeg2dc2:
- normbeg rcontloop2,2
-
-normalbeg2dc1:
- normbeg rcontloop1,1
-
-normalbeg2dc0:
- normbeg rcontloop0,0
-
-
-; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end
-
-normalbeg2:
- mov edi,window
-
- cmp bp,word ptr[edi+eax]
- jne contloop3 ; if *(ushf*)match != scan_start, continue
-
-iseq:
-; if we are here, we know that *(match+best_len-1) == scan_end
-; and (match == scan_start)
-
- mov edi,edx
- mov esi,scan ; esi = scan
- add edi,eax ; edi = window + cur_match = match
-
- mov edx,[esi+3] ; compare manually dword at match+3
- xor edx,[edi+3] ; and scan +3
-
- jz begincompare ; if equal, go to long compare
-
-; we will determine the unmatch byte and calculate len (in esi)
- or dl,dl
- je eq1rr
- mov esi,3
- jmp trfinval
-eq1rr:
- or dx,dx
- je eq1
-
- mov esi,4
- jmp trfinval
-eq1:
- and edx,0ffffffh
- jz eq11
- mov esi,5
- jmp trfinval
-eq11:
- mov esi,6
- jmp trfinval
-
-begincompare:
- ; here we now scan and match begin same
- add edi,6
- add esi,6
- mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes
- repe cmpsd ; loop until mismatch
-
- je trfin ; go to trfin if not unmatch
-; we determine the unmatch byte
- sub esi,4
- mov edx,[edi-4]
- xor edx,[esi]
-
- or dl,dl
- jnz trfin
- inc esi
-
- or dx,dx
- jnz trfin
- inc esi
-
- and edx,0ffffffh
- jnz trfin
- inc esi
-
-trfin:
- sub esi,scan ; esi = len
-trfinval:
-; here we have finised compare, and esi contain len of equal string
- cmp esi,best_len ; if len > best_len, go newbestlen
- ja short newbestlen
-; now we restore edx, ecx and esi, for the big loop
- mov esi,prev
- mov ecx,limit
- mov edx,window
- jmp contloop3
-
-newbestlen:
- mov best_len,esi ; len become best_len
-
- mov match_start,eax ; save new position as match_start
- cmp esi,nice_match ; if best_len >= nice_match, exit
- jae exitloop
- mov ecx,scan
- mov edx,window ; restore edx=window
- add ecx,esi
- add esi,edx
-
- dec esi
- mov windowlen,esi ; windowlen = window + best_len-1
- mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end
-
-; now we restore ecx and esi, for the big loop :
- mov esi,prev
- mov ecx,limit
- jmp contloop3
-
-exitloop:
-; exit : s->match_start=match_start
- mov ebx,match_start
- mov ebp,str_s
- mov ecx,best_len
- mov dword ptr [ebp+dep_match_start],ebx
- mov eax,dword ptr [ebp+dep_lookahead]
- cmp ecx,eax
- ja minexlo
- mov eax,ecx
-minexlo:
-; return min(best_len,s->lookahead)
-
-; restore stack and register ebx,esi,edi,ebp
- add esp,NbStackAdd
-
- pop ebx
- pop esi
- pop edi
- pop ebp
- ret
-InfoAuthor:
-; please don't remove this string !
-; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!
- db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah
-
-
-
-IFDEF NOUNDERLINE
-longest_match_7fff endp
-ELSE
-_longest_match_7fff endp
-ENDIF
-
-
-IFDEF NOUNDERLINE
-cpudetect32 proc near
-ELSE
-_cpudetect32 proc near
-ENDIF
-
-
- pushfd ; push original EFLAGS
- pop eax ; get original EFLAGS
- mov ecx, eax ; save original EFLAGS
- xor eax, 40000h ; flip AC bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- xor eax, ecx ; can’t toggle AC bit, processor=80386
- jz end_cpu_is_386 ; jump if 80386 processor
- push ecx
- popfd ; restore AC bit in EFLAGS first
-
- pushfd
- pushfd
- pop ecx
-
- mov eax, ecx ; get original EFLAGS
- xor eax, 200000h ; flip ID bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- popfd ; restore original EFLAGS
- xor eax, ecx ; can’t toggle ID bit,
- je is_old_486 ; processor=old
-
- mov eax,1
- db 0fh,0a2h ;CPUID
-
-exitcpudetect:
- ret
-
-end_cpu_is_386:
- mov eax,0300h
- jmp exitcpudetect
-
-is_old_486:
- mov eax,0400h
- jmp exitcpudetect
-
-IFDEF NOUNDERLINE
-cpudetect32 endp
-ELSE
-_cpudetect32 endp
-ENDIF
-
-_TEXT ends
-end
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32c.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32c.c
deleted file mode 100644
index d853bb7ce8a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/gvmat32c.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
- * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
- * File written by Gilles Vollant, by modifiying the longest_match
- * from Jean-loup Gailly in deflate.c
- * it prepare all parameters and call the assembly longest_match_gvasm
- * longest_match execute standard C code is wmask != 0x7fff
- * (assembly code is faster with a fixed wmask)
- *
- */
-
-#include "deflate.h"
-
-#undef FAR
-#include <windows.h>
-
-#ifdef ASMV
-#define NIL 0
-
-#define UNALIGNED_OK
-
-
-/* if your C compiler don't add underline before function name,
- define ADD_UNDERLINE_ASMFUNC */
-#ifdef ADD_UNDERLINE_ASMFUNC
-#define longest_match_7fff _longest_match_7fff
-#endif
-
-
-
-void match_init()
-{
-}
-
-unsigned long cpudetect32();
-
-uInt longest_match_c(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-
-uInt longest_match_7fff(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-uInt longest_match(
- deflate_state *s,
- IPos cur_match) /* current match */
-{
- static uInt iIsPPro=2;
-
- if ((s->w_mask == 0x7fff) && (iIsPPro==0))
- return longest_match_7fff(s,cur_match);
-
- if (iIsPPro==2)
- iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
-
- return longest_match_c(s,cur_match);
-}
-
-
-
-uInt longest_match_c(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#endif /* ASMV */
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/mkgvmt32.bat b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/mkgvmt32.bat
deleted file mode 100644
index 6c5ffd7a024..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/mkgvmt32.bat
+++ /dev/null
@@ -1 +0,0 @@
-c:\masm611\bin\ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.def
deleted file mode 100644
index 7e9d60d55d9..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.def
+++ /dev/null
@@ -1,74 +0,0 @@
-LIBRARY "zlib"
-
-DESCRIPTION '"""zlib data compression library"""'
-
-
-VERSION 1.11
-
-
-HEAPSIZE 1048576,8192
-
-EXPORTS
- adler32 @1
- compress @2
- crc32 @3
- deflate @4
- deflateCopy @5
- deflateEnd @6
- deflateInit2_ @7
- deflateInit_ @8
- deflateParams @9
- deflateReset @10
- deflateSetDictionary @11
- gzclose @12
- gzdopen @13
- gzerror @14
- gzflush @15
- gzopen @16
- gzread @17
- gzwrite @18
- inflate @19
- inflateEnd @20
- inflateInit2_ @21
- inflateInit_ @22
- inflateReset @23
- inflateSetDictionary @24
- inflateSync @25
- uncompress @26
- zlibVersion @27
- gzprintf @28
- gzputc @29
- gzgetc @30
- gzseek @31
- gzrewind @32
- gztell @33
- gzeof @34
- gzsetparams @35
- zError @36
- inflateSyncPoint @37
- get_crc_table @38
- compress2 @39
- gzputs @40
- gzgets @41
-
- unzOpen @61
- unzClose @62
- unzGetGlobalInfo @63
- unzGetCurrentFileInfo @64
- unzGoToFirstFile @65
- unzGoToNextFile @66
- unzOpenCurrentFile @67
- unzReadCurrentFile @68
- unztell @70
- unzeof @71
- unzCloseCurrentFile @72
- unzGetGlobalComment @73
- unzStringFileNameCompare @74
- unzLocateFile @75
- unzGetLocalExtrafield @76
-
- zipOpen @80
- zipOpenNewFileInZip @81
- zipWriteInFileInZip @82
- zipCloseFileInZip @83
- zipClose @84
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsp
deleted file mode 100644
index a70d4d4a6b0..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsp
+++ /dev/null
@@ -1,651 +0,0 @@
-# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 5.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602
-
-CFG=zlibvc - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "zlibvc.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\
- "Win32 (ALPHA) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\
- "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\
- "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\Release"
-# PROP BASE Intermediate_Dir ".\Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\Release"
-# PROP Intermediate_Dir ".\Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\Debug"
-# PROP BASE Intermediate_Dir ".\Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\Debug"
-# PROP Intermediate_Dir ".\Debug"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "_DEBUG"
-# ADD RSC /l 0x40c /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlibvc__"
-# PROP BASE Intermediate_Dir "zlibvc__"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "zlibvc__"
-# PROP Intermediate_Dir "zlibvc__"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
-# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlibvc_0"
-# PROP BASE Intermediate_Dir "zlibvc_0"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "zlibvc_0"
-# PROP Intermediate_Dir "zlibvc_0"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlibvc_1"
-# PROP BASE Intermediate_Dir "zlibvc_1"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "zlibvc_1"
-# PROP Intermediate_Dir "zlibvc_1"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ENDIF
-
-# Begin Target
-
-# Name "zlibvc - Win32 Release"
-# Name "zlibvc - Win32 Debug"
-# Name "zlibvc - Win32 ReleaseAxp"
-# Name "zlibvc - Win32 ReleaseWithoutAsm"
-# Name "zlibvc - Win32 ReleaseWithoutCrtdll"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
-# Begin Source File
-
-SOURCE=.\adler32.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_ADLER=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\compress.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_COMPR=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\crc32.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_CRC32=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\deflate.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_DEFLA=\
- ".\deflate.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\gvmat32c.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\gzio.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_GZIO_=\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\infblock.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFBL=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\infcodes.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFCO=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inffast.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\inffast.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFFA=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inffast.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\inflate.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFLA=\
- ".\infblock.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\inftrees.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFTR=\
- ".\inftrees.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\infutil.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFUT=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\trees.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_TREES=\
- ".\deflate.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\uncompr.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_UNCOM=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\unzip.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\zip.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\zlib.rc
-# End Source File
-# Begin Source File
-
-SOURCE=.\zlibvc.def
-# End Source File
-# Begin Source File
-
-SOURCE=.\zutil.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_ZUTIL=\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
-# Begin Source File
-
-SOURCE=.\deflate.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\infblock.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\infcodes.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\inffast.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\inftrees.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\infutil.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\zlib.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\zutil.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsw b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsw
deleted file mode 100644
index 493cd870365..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm386/zlibvc.dsw
+++ /dev/null
@@ -1,41 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 5.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/README.586 b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/README.586
deleted file mode 100644
index 6bb78f32069..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/README.586
+++ /dev/null
@@ -1,43 +0,0 @@
-This is a patched version of zlib modified to use
-Pentium-optimized assembly code in the deflation algorithm. The files
-changed/added by this patch are:
-
-README.586
-match.S
-
-The effectiveness of these modifications is a bit marginal, as the the
-program's bottleneck seems to be mostly L1-cache contention, for which
-there is no real way to work around without rewriting the basic
-algorithm. The speedup on average is around 5-10% (which is generally
-less than the amount of variance between subsequent executions).
-However, when used at level 9 compression, the cache contention can
-drop enough for the assembly version to achieve 10-20% speedup (and
-sometimes more, depending on the amount of overall redundancy in the
-files). Even here, though, cache contention can still be the limiting
-factor, depending on the nature of the program using the zlib library.
-This may also mean that better improvements will be seen on a Pentium
-with MMX, which suffers much less from L1-cache contention, but I have
-not yet verified this.
-
-Note that this code has been tailored for the Pentium in particular,
-and will not perform well on the Pentium Pro (due to the use of a
-partial register in the inner loop).
-
-If you are using an assembler other than GNU as, you will have to
-translate match.S to use your assembler's syntax. (Have fun.)
-
-Brian Raiter
-breadbox@muppetlabs.com
-April, 1998
-
-
-Added for zlib 1.1.3:
-
-The patches come from
-http://www.muppetlabs.com/~breadbox/software/assembly.html
-
-To compile zlib with this asm file, copy match.S to the zlib directory
-then do:
-
-CFLAGS="-O3 -DASMV" ./configure
-make OBJA=match.o
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/match.S b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/match.S
deleted file mode 100644
index 8f1614078f8..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm586/match.S
+++ /dev/null
@@ -1,354 +0,0 @@
-/* match.s -- Pentium-optimized version of longest_match()
- * Written for zlib 1.1.2
- * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License.
- */
-
-#ifndef NO_UNDERLINE
-#define match_init _match_init
-#define longest_match _longest_match
-#endif
-
-#define MAX_MATCH (258)
-#define MIN_MATCH (3)
-#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-
-/* stack frame offsets */
-
-#define wmask 0 /* local copy of s->wmask */
-#define window 4 /* local copy of s->window */
-#define windowbestlen 8 /* s->window + bestlen */
-#define chainlenscanend 12 /* high word: current chain len */
- /* low word: last bytes sought */
-#define scanstart 16 /* first two bytes of string */
-#define scanalign 20 /* dword-misalignment of string */
-#define nicematch 24 /* a good enough match size */
-#define bestlen 28 /* size of best match so far */
-#define scan 32 /* ptr to string wanting match */
-
-#define LocalVarsSize (36)
-/* saved ebx 36 */
-/* saved edi 40 */
-/* saved esi 44 */
-/* saved ebp 48 */
-/* return address 52 */
-#define deflatestate 56 /* the function arguments */
-#define curmatch 60
-
-/* Offsets for fields in the deflate_state structure. These numbers
- * are calculated from the definition of deflate_state, with the
- * assumption that the compiler will dword-align the fields. (Thus,
- * changing the definition of deflate_state could easily cause this
- * program to crash horribly, without so much as a warning at
- * compile time. Sigh.)
- */
-#define dsWSize 36
-#define dsWMask 44
-#define dsWindow 48
-#define dsPrev 56
-#define dsMatchLen 88
-#define dsPrevMatch 92
-#define dsStrStart 100
-#define dsMatchStart 104
-#define dsLookahead 108
-#define dsPrevLen 112
-#define dsMaxChainLen 116
-#define dsGoodMatch 132
-#define dsNiceMatch 136
-
-
-.file "match.S"
-
-.globl match_init, longest_match
-
-.text
-
-/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-
-longest_match:
-
-/* Save registers that the compiler may be using, and adjust %esp to */
-/* make room for our stack frame. */
-
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- subl $LocalVarsSize, %esp
-
-/* Retrieve the function arguments. %ecx will hold cur_match */
-/* throughout the entire function. %edx will hold the pointer to the */
-/* deflate_state structure during the function's setup (before */
-/* entering the main loop). */
-
- movl deflatestate(%esp), %edx
- movl curmatch(%esp), %ecx
-
-/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-
- movl dsNiceMatch(%edx), %eax
- movl dsLookahead(%edx), %ebx
- cmpl %eax, %ebx
- jl LookaheadLess
- movl %eax, %ebx
-LookaheadLess: movl %ebx, nicematch(%esp)
-
-/* register Bytef *scan = s->window + s->strstart; */
-
- movl dsWindow(%edx), %esi
- movl %esi, window(%esp)
- movl dsStrStart(%edx), %ebp
- lea (%esi,%ebp), %edi
- movl %edi, scan(%esp)
-
-/* Determine how many bytes the scan ptr is off from being */
-/* dword-aligned. */
-
- movl %edi, %eax
- negl %eax
- andl $3, %eax
- movl %eax, scanalign(%esp)
-
-/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-
- movl dsWSize(%edx), %eax
- subl $MIN_LOOKAHEAD, %eax
- subl %eax, %ebp
- jg LimitPositive
- xorl %ebp, %ebp
-LimitPositive:
-
-/* unsigned chain_length = s->max_chain_length; */
-/* if (s->prev_length >= s->good_match) { */
-/* chain_length >>= 2; */
-/* } */
-
- movl dsPrevLen(%edx), %eax
- movl dsGoodMatch(%edx), %ebx
- cmpl %ebx, %eax
- movl dsMaxChainLen(%edx), %ebx
- jl LastMatchGood
- shrl $2, %ebx
-LastMatchGood:
-
-/* chainlen is decremented once beforehand so that the function can */
-/* use the sign flag instead of the zero flag for the exit test. */
-/* It is then shifted into the high word, to make room for the scanend */
-/* scanend value, which it will always accompany. */
-
- decl %ebx
- shll $16, %ebx
-
-/* int best_len = s->prev_length; */
-
- movl dsPrevLen(%edx), %eax
- movl %eax, bestlen(%esp)
-
-/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
-
-/* register ush scan_start = *(ushf*)scan; */
-/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-
- movw (%edi), %bx
- movw %bx, scanstart(%esp)
- movw -1(%edi,%eax), %bx
- movl %ebx, chainlenscanend(%esp)
-
-/* Posf *prev = s->prev; */
-/* uInt wmask = s->w_mask; */
-
- movl dsPrev(%edx), %edi
- movl dsWMask(%edx), %edx
- mov %edx, wmask(%esp)
-
-/* Jump into the main loop. */
-
- jmp LoopEntry
-
-.balign 16
-
-/* do {
- * match = s->window + cur_match;
- * if (*(ushf*)(match+best_len-1) != scan_end ||
- * *(ushf*)match != scan_start) continue;
- * [...]
- * } while ((cur_match = prev[cur_match & wmask]) > limit
- * && --chain_length != 0);
- *
- * Here is the inner loop of the function. The function will spend the
- * majority of its time in this loop, and majority of that time will
- * be spent in the first ten instructions.
- *
- * Within this loop:
- * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
- * %ecx = curmatch
- * %edx = curmatch & wmask
- * %esi = windowbestlen - i.e., (window + bestlen)
- * %edi = prev
- * %ebp = limit
- *
- * Two optimization notes on the choice of instructions:
- *
- * The first instruction uses a 16-bit address, which costs an extra,
- * unpairable cycle. This is cheaper than doing a 32-bit access and
- * zeroing the high word, due to the 3-cycle misalignment penalty which
- * would occur half the time. This also turns out to be cheaper than
- * doing two separate 8-bit accesses, as the memory is so rarely in the
- * L1 cache.
- *
- * The window buffer, however, apparently spends a lot of time in the
- * cache, and so it is faster to retrieve the word at the end of the
- * match string with two 8-bit loads. The instructions that test the
- * word at the beginning of the match string, however, are executed
- * much less frequently, and there it was cheaper to use 16-bit
- * instructions, which avoided the necessity of saving off and
- * subsequently reloading one of the other registers.
- */
-LookupLoop:
- /* 1 U & V */
- movw (%edi,%edx,2), %cx /* 2 U pipe */
- movl wmask(%esp), %edx /* 2 V pipe */
- cmpl %ebp, %ecx /* 3 U pipe */
- jbe LeaveNow /* 3 V pipe */
- subl $0x00010000, %ebx /* 4 U pipe */
- js LeaveNow /* 4 V pipe */
-LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
- andl %ecx, %edx /* 5 V pipe */
- cmpb %bl, %al /* 6 U pipe */
- jnz LookupLoop /* 6 V pipe */
- movb (%esi,%ecx), %ah
- cmpb %bh, %ah
- jnz LookupLoop
- movl window(%esp), %eax
- movw (%eax,%ecx), %ax
- cmpw scanstart(%esp), %ax
- jnz LookupLoop
-
-/* Store the current value of chainlen. */
-
- movl %ebx, chainlenscanend(%esp)
-
-/* Point %edi to the string under scrutiny, and %esi to the string we */
-/* are hoping to match it up with. In actuality, %esi and %edi are */
-/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-/* initialized to -(MAX_MATCH_8 - scanalign). */
-
- movl window(%esp), %esi
- movl scan(%esp), %edi
- addl %ecx, %esi
- movl scanalign(%esp), %eax
- movl $(-MAX_MATCH_8), %edx
- lea MAX_MATCH_8(%edi,%eax), %edi
- lea MAX_MATCH_8(%esi,%eax), %esi
-
-/* Test the strings for equality, 8 bytes at a time. At the end,
- * adjust %edx so that it is offset to the exact byte that mismatched.
- *
- * We already know at this point that the first three bytes of the
- * strings match each other, and they can be safely passed over before
- * starting the compare loop. So what this code does is skip over 0-3
- * bytes, as much as necessary in order to dword-align the %edi
- * pointer. (%esi will still be misaligned three times out of four.)
- *
- * It should be confessed that this loop usually does not represent
- * much of the total running time. Replacing it with a more
- * straightforward "rep cmpsb" would not drastically degrade
- * performance.
- */
-LoopCmps:
- movl (%esi,%edx), %eax
- movl (%edi,%edx), %ebx
- xorl %ebx, %eax
- jnz LeaveLoopCmps
- movl 4(%esi,%edx), %eax
- movl 4(%edi,%edx), %ebx
- xorl %ebx, %eax
- jnz LeaveLoopCmps4
- addl $8, %edx
- jnz LoopCmps
- jmp LenMaximum
-LeaveLoopCmps4: addl $4, %edx
-LeaveLoopCmps: testl $0x0000FFFF, %eax
- jnz LenLower
- addl $2, %edx
- shrl $16, %eax
-LenLower: subb $1, %al
- adcl $0, %edx
-
-/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-/* then automatically accept it as the best possible match and leave. */
-
- lea (%edi,%edx), %eax
- movl scan(%esp), %edi
- subl %edi, %eax
- cmpl $MAX_MATCH, %eax
- jge LenMaximum
-
-/* If the length of the match is not longer than the best match we */
-/* have so far, then forget it and return to the lookup loop. */
-
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- cmpl %ebx, %eax
- jg LongerMatch
- movl chainlenscanend(%esp), %ebx
- movl windowbestlen(%esp), %esi
- movl dsPrev(%edx), %edi
- movl wmask(%esp), %edx
- andl %ecx, %edx
- jmp LookupLoop
-
-/* s->match_start = cur_match; */
-/* best_len = len; */
-/* if (len >= nice_match) break; */
-/* scan_end = *(ushf*)(scan+best_len-1); */
-
-LongerMatch: movl nicematch(%esp), %ebx
- movl %eax, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
- cmpl %ebx, %eax
- jge LeaveNow
- movl window(%esp), %esi
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
- movl chainlenscanend(%esp), %ebx
- movw -1(%edi,%eax), %bx
- movl dsPrev(%edx), %edi
- movl %ebx, chainlenscanend(%esp)
- movl wmask(%esp), %edx
- andl %ecx, %edx
- jmp LookupLoop
-
-/* Accept the current string, with the maximum possible length. */
-
-LenMaximum: movl deflatestate(%esp), %edx
- movl $MAX_MATCH, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
-
-/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-/* return s->lookahead; */
-
-LeaveNow:
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- movl dsLookahead(%edx), %eax
- cmpl %eax, %ebx
- jg LookaheadRet
- movl %ebx, %eax
-LookaheadRet:
-
-/* Restore the stack and return from whence we came. */
-
- addl $LocalVarsSize, %esp
- popl %ebx
- popl %esi
- popl %edi
- popl %ebp
-match_init: ret
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/README.686 b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/README.686
deleted file mode 100644
index a593f23afd6..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/README.686
+++ /dev/null
@@ -1,34 +0,0 @@
-This is a patched version of zlib, modified to use
-Pentium-Pro-optimized assembly code in the deflation algorithm. The
-files changed/added by this patch are:
-
-README.686
-match.S
-
-The speedup that this patch provides varies, depending on whether the
-compiler used to build the original version of zlib falls afoul of the
-PPro's speed traps. My own tests show a speedup of around 10-20% at
-the default compression level, and 20-30% using -9, against a version
-compiled using gcc 2.7.2.3. Your mileage may vary.
-
-Note that this code has been tailored for the PPro/PII in particular,
-and will not perform particuarly well on a Pentium.
-
-If you are using an assembler other than GNU as, you will have to
-translate match.S to use your assembler's syntax. (Have fun.)
-
-Brian Raiter
-breadbox@muppetlabs.com
-April, 1998
-
-
-Added for zlib 1.1.3:
-
-The patches come from
-http://www.muppetlabs.com/~breadbox/software/assembly.html
-
-To compile zlib with this asm file, copy match.S to the zlib directory
-then do:
-
-CFLAGS="-O3 -DASMV" ./configure
-make OBJA=match.o
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/match.S b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/match.S
deleted file mode 100644
index 8e86c33c288..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/asm686/match.S
+++ /dev/null
@@ -1,327 +0,0 @@
-/* match.s -- Pentium-Pro-optimized version of longest_match()
- * Written for zlib 1.1.2
- * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License.
- */
-
-#ifndef NO_UNDERLINE
-#define match_init _match_init
-#define longest_match _longest_match
-#endif
-
-#define MAX_MATCH (258)
-#define MIN_MATCH (3)
-#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-
-/* stack frame offsets */
-
-#define chainlenwmask 0 /* high word: current chain len */
- /* low word: s->wmask */
-#define window 4 /* local copy of s->window */
-#define windowbestlen 8 /* s->window + bestlen */
-#define scanstart 16 /* first two bytes of string */
-#define scanend 12 /* last two bytes of string */
-#define scanalign 20 /* dword-misalignment of string */
-#define nicematch 24 /* a good enough match size */
-#define bestlen 28 /* size of best match so far */
-#define scan 32 /* ptr to string wanting match */
-
-#define LocalVarsSize (36)
-/* saved ebx 36 */
-/* saved edi 40 */
-/* saved esi 44 */
-/* saved ebp 48 */
-/* return address 52 */
-#define deflatestate 56 /* the function arguments */
-#define curmatch 60
-
-/* Offsets for fields in the deflate_state structure. These numbers
- * are calculated from the definition of deflate_state, with the
- * assumption that the compiler will dword-align the fields. (Thus,
- * changing the definition of deflate_state could easily cause this
- * program to crash horribly, without so much as a warning at
- * compile time. Sigh.)
- */
-#define dsWSize 36
-#define dsWMask 44
-#define dsWindow 48
-#define dsPrev 56
-#define dsMatchLen 88
-#define dsPrevMatch 92
-#define dsStrStart 100
-#define dsMatchStart 104
-#define dsLookahead 108
-#define dsPrevLen 112
-#define dsMaxChainLen 116
-#define dsGoodMatch 132
-#define dsNiceMatch 136
-
-
-.file "match.S"
-
-.globl match_init, longest_match
-
-.text
-
-/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-
-longest_match:
-
-/* Save registers that the compiler may be using, and adjust %esp to */
-/* make room for our stack frame. */
-
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- subl $LocalVarsSize, %esp
-
-/* Retrieve the function arguments. %ecx will hold cur_match */
-/* throughout the entire function. %edx will hold the pointer to the */
-/* deflate_state structure during the function's setup (before */
-/* entering the main loop). */
-
- movl deflatestate(%esp), %edx
- movl curmatch(%esp), %ecx
-
-/* uInt wmask = s->w_mask; */
-/* unsigned chain_length = s->max_chain_length; */
-/* if (s->prev_length >= s->good_match) { */
-/* chain_length >>= 2; */
-/* } */
-
- movl dsPrevLen(%edx), %eax
- movl dsGoodMatch(%edx), %ebx
- cmpl %ebx, %eax
- movl dsWMask(%edx), %eax
- movl dsMaxChainLen(%edx), %ebx
- jl LastMatchGood
- shrl $2, %ebx
-LastMatchGood:
-
-/* chainlen is decremented once beforehand so that the function can */
-/* use the sign flag instead of the zero flag for the exit test. */
-/* It is then shifted into the high word, to make room for the wmask */
-/* value, which it will always accompany. */
-
- decl %ebx
- shll $16, %ebx
- orl %eax, %ebx
- movl %ebx, chainlenwmask(%esp)
-
-/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-
- movl dsNiceMatch(%edx), %eax
- movl dsLookahead(%edx), %ebx
- cmpl %eax, %ebx
- jl LookaheadLess
- movl %eax, %ebx
-LookaheadLess: movl %ebx, nicematch(%esp)
-
-/* register Bytef *scan = s->window + s->strstart; */
-
- movl dsWindow(%edx), %esi
- movl %esi, window(%esp)
- movl dsStrStart(%edx), %ebp
- lea (%esi,%ebp), %edi
- movl %edi, scan(%esp)
-
-/* Determine how many bytes the scan ptr is off from being */
-/* dword-aligned. */
-
- movl %edi, %eax
- negl %eax
- andl $3, %eax
- movl %eax, scanalign(%esp)
-
-/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-
- movl dsWSize(%edx), %eax
- subl $MIN_LOOKAHEAD, %eax
- subl %eax, %ebp
- jg LimitPositive
- xorl %ebp, %ebp
-LimitPositive:
-
-/* int best_len = s->prev_length; */
-
- movl dsPrevLen(%edx), %eax
- movl %eax, bestlen(%esp)
-
-/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
-
-/* register ush scan_start = *(ushf*)scan; */
-/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-/* Posf *prev = s->prev; */
-
- movzwl (%edi), %ebx
- movl %ebx, scanstart(%esp)
- movzwl -1(%edi,%eax), %ebx
- movl %ebx, scanend(%esp)
- movl dsPrev(%edx), %edi
-
-/* Jump into the main loop. */
-
- movl chainlenwmask(%esp), %edx
- jmp LoopEntry
-
-.balign 16
-
-/* do {
- * match = s->window + cur_match;
- * if (*(ushf*)(match+best_len-1) != scan_end ||
- * *(ushf*)match != scan_start) continue;
- * [...]
- * } while ((cur_match = prev[cur_match & wmask]) > limit
- * && --chain_length != 0);
- *
- * Here is the inner loop of the function. The function will spend the
- * majority of its time in this loop, and majority of that time will
- * be spent in the first ten instructions.
- *
- * Within this loop:
- * %ebx = scanend
- * %ecx = curmatch
- * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
- * %esi = windowbestlen - i.e., (window + bestlen)
- * %edi = prev
- * %ebp = limit
- */
-LookupLoop:
- andl %edx, %ecx
- movzwl (%edi,%ecx,2), %ecx
- cmpl %ebp, %ecx
- jbe LeaveNow
- subl $0x00010000, %edx
- js LeaveNow
-LoopEntry: movzwl -1(%esi,%ecx), %eax
- cmpl %ebx, %eax
- jnz LookupLoop
- movl window(%esp), %eax
- movzwl (%eax,%ecx), %eax
- cmpl scanstart(%esp), %eax
- jnz LookupLoop
-
-/* Store the current value of chainlen. */
-
- movl %edx, chainlenwmask(%esp)
-
-/* Point %edi to the string under scrutiny, and %esi to the string we */
-/* are hoping to match it up with. In actuality, %esi and %edi are */
-/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-/* initialized to -(MAX_MATCH_8 - scanalign). */
-
- movl window(%esp), %esi
- movl scan(%esp), %edi
- addl %ecx, %esi
- movl scanalign(%esp), %eax
- movl $(-MAX_MATCH_8), %edx
- lea MAX_MATCH_8(%edi,%eax), %edi
- lea MAX_MATCH_8(%esi,%eax), %esi
-
-/* Test the strings for equality, 8 bytes at a time. At the end,
- * adjust %edx so that it is offset to the exact byte that mismatched.
- *
- * We already know at this point that the first three bytes of the
- * strings match each other, and they can be safely passed over before
- * starting the compare loop. So what this code does is skip over 0-3
- * bytes, as much as necessary in order to dword-align the %edi
- * pointer. (%esi will still be misaligned three times out of four.)
- *
- * It should be confessed that this loop usually does not represent
- * much of the total running time. Replacing it with a more
- * straightforward "rep cmpsb" would not drastically degrade
- * performance.
- */
-LoopCmps:
- movl (%esi,%edx), %eax
- xorl (%edi,%edx), %eax
- jnz LeaveLoopCmps
- movl 4(%esi,%edx), %eax
- xorl 4(%edi,%edx), %eax
- jnz LeaveLoopCmps4
- addl $8, %edx
- jnz LoopCmps
- jmp LenMaximum
-LeaveLoopCmps4: addl $4, %edx
-LeaveLoopCmps: testl $0x0000FFFF, %eax
- jnz LenLower
- addl $2, %edx
- shrl $16, %eax
-LenLower: subb $1, %al
- adcl $0, %edx
-
-/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-/* then automatically accept it as the best possible match and leave. */
-
- lea (%edi,%edx), %eax
- movl scan(%esp), %edi
- subl %edi, %eax
- cmpl $MAX_MATCH, %eax
- jge LenMaximum
-
-/* If the length of the match is not longer than the best match we */
-/* have so far, then forget it and return to the lookup loop. */
-
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- cmpl %ebx, %eax
- jg LongerMatch
- movl windowbestlen(%esp), %esi
- movl dsPrev(%edx), %edi
- movl scanend(%esp), %ebx
- movl chainlenwmask(%esp), %edx
- jmp LookupLoop
-
-/* s->match_start = cur_match; */
-/* best_len = len; */
-/* if (len >= nice_match) break; */
-/* scan_end = *(ushf*)(scan+best_len-1); */
-
-LongerMatch: movl nicematch(%esp), %ebx
- movl %eax, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
- cmpl %ebx, %eax
- jge LeaveNow
- movl window(%esp), %esi
- addl %eax, %esi
- movl %esi, windowbestlen(%esp)
- movzwl -1(%edi,%eax), %ebx
- movl dsPrev(%edx), %edi
- movl %ebx, scanend(%esp)
- movl chainlenwmask(%esp), %edx
- jmp LookupLoop
-
-/* Accept the current string, with the maximum possible length. */
-
-LenMaximum: movl deflatestate(%esp), %edx
- movl $MAX_MATCH, bestlen(%esp)
- movl %ecx, dsMatchStart(%edx)
-
-/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-/* return s->lookahead; */
-
-LeaveNow:
- movl deflatestate(%esp), %edx
- movl bestlen(%esp), %ebx
- movl dsLookahead(%edx), %eax
- cmpl %eax, %ebx
- jg LookaheadRet
- movl %ebx, %eax
-LookaheadRet:
-
-/* Restore the stack and return from whence we came. */
-
- addl $LocalVarsSize, %esp
- popl %ebx
- popl %esi
- popl %edi
- popl %ebp
-match_init: ret
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlib.mak b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlib.mak
deleted file mode 100644
index ba557e2b977..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlib.mak
+++ /dev/null
@@ -1,36 +0,0 @@
-# Makefile for zlib32bd.lib
-# ------------- Borland C++ 4.5 -------------
-
-# The (32-bit) zlib32bd.lib made with this makefile is intended for use
-# in making the (32-bit) DLL, png32bd.dll. It uses the "stdcall" calling
-# convention.
-
-CFLAGS= -ps -O2 -C -K -N- -k- -d -3 -r- -w-par -w-aus -WDE
-CC=f:\bc45\bin\bcc32
-LIBFLAGS= /C
-LIB=f:\bc45\bin\tlib
-ZLIB=zlib32bd.lib
-
-.autodepend
-.c.obj:
- $(CC) -c $(CFLAGS) $<
-
-OBJ1=adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj
-OBJ2=infcodes.obj inflate.obj inftrees.obj infutil.obj inffast.obj
-OBJ3=trees.obj uncompr.obj zutil.obj
-pOBJ1=+adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infblock.obj
-pOBJ2=+infcodes.obj+inflate.obj+inftrees.obj+infutil.obj+inffast.obj
-pOBJ3=+trees.obj+uncompr.obj+zutil.obj
-
-all: $(ZLIB)
-
-$(ZLIB): $(OBJ1) $(OBJ2) $(OBJ3)
- @if exist $@ del $@
- $(LIB) @&&|
-$@ $(LIBFLAGS) &
-$(pOBJ1) &
-$(pOBJ2) &
-$(pOBJ3)
-|
-
-# End of makefile for zlib32bd.lib
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlibdef.pas b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlibdef.pas
deleted file mode 100644
index 4f96b7d2c50..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi/zlibdef.pas
+++ /dev/null
@@ -1,169 +0,0 @@
-unit zlibdef;
-
-interface
-
-uses
- Windows;
-
-const
- ZLIB_VERSION = '1.1.3';
-
-type
- voidpf = Pointer;
- int = Integer;
- uInt = Cardinal;
- pBytef = PChar;
- uLong = Cardinal;
-
- alloc_func = function(opaque: voidpf; items, size: uInt): voidpf;
- stdcall;
- free_func = procedure(opaque, address: voidpf);
- stdcall;
-
- internal_state = Pointer;
-
- z_streamp = ^z_stream;
- z_stream = packed record
- next_in: pBytef; // next input byte
- avail_in: uInt; // number of bytes available at next_in
- total_in: uLong; // total nb of input bytes read so far
-
- next_out: pBytef; // next output byte should be put there
- avail_out: uInt; // remaining free space at next_out
- total_out: uLong; // total nb of bytes output so far
-
- msg: PChar; // last error message, NULL if no error
- state: internal_state; // not visible by applications
-
- zalloc: alloc_func; // used to allocate the internal state
- zfree: free_func; // used to free the internal state
- opaque: voidpf; // private data object passed to zalloc and zfree
-
- data_type: int; // best guess about the data type: ascii or binary
- adler: uLong; // adler32 value of the uncompressed data
- reserved: uLong; // reserved for future use
- end;
-
-const
- Z_NO_FLUSH = 0;
- Z_SYNC_FLUSH = 2;
- Z_FULL_FLUSH = 3;
- Z_FINISH = 4;
-
- Z_OK = 0;
- Z_STREAM_END = 1;
-
- Z_NO_COMPRESSION = 0;
- Z_BEST_SPEED = 1;
- Z_BEST_COMPRESSION = 9;
- Z_DEFAULT_COMPRESSION = -1;
-
- Z_FILTERED = 1;
- Z_HUFFMAN_ONLY = 2;
- Z_DEFAULT_STRATEGY = 0;
-
- Z_BINARY = 0;
- Z_ASCII = 1;
- Z_UNKNOWN = 2;
-
- Z_DEFLATED = 8;
-
- MAX_MEM_LEVEL = 9;
-
-function adler32(adler: uLong; const buf: pBytef; len: uInt): uLong;
- stdcall;
-function crc32(crc: uLong; const buf: pBytef; len: uInt): uLong;
- stdcall;
-function deflate(strm: z_streamp; flush: int): int;
- stdcall;
-function deflateCopy(dest, source: z_streamp): int;
- stdcall;
-function deflateEnd(strm: z_streamp): int;
- stdcall;
-function deflateInit2_(strm: z_streamp; level, method,
- windowBits, memLevel, strategy: int;
- const version: PChar; stream_size: int): int;
- stdcall;
-function deflateInit_(strm: z_streamp; level: int;
- const version: PChar; stream_size: int): int;
- stdcall;
-function deflateParams(strm: z_streamp; level, strategy: int): int;
- stdcall;
-function deflateReset(strm: z_streamp): int;
- stdcall;
-function deflateSetDictionary(strm: z_streamp;
- const dictionary: pBytef;
- dictLength: uInt): int;
- stdcall;
-function inflate(strm: z_streamp; flush: int): int;
- stdcall;
-function inflateEnd(strm: z_streamp): int;
- stdcall;
-function inflateInit2_(strm: z_streamp; windowBits: int;
- const version: PChar; stream_size: int): int;
- stdcall;
-function inflateInit_(strm: z_streamp; const version: PChar;
- stream_size: int): int;
- stdcall;
-function inflateReset(strm: z_streamp): int;
- stdcall;
-function inflateSetDictionary(strm: z_streamp;
- const dictionary: pBytef;
- dictLength: uInt): int;
- stdcall;
-function inflateSync(strm: z_streamp): int;
- stdcall;
-
-function deflateInit(strm: z_streamp; level: int): int;
-function deflateInit2(strm: z_streamp; level, method, windowBits,
- memLevel, strategy: int): int;
-function inflateInit(strm: z_streamp): int;
-function inflateInit2(strm: z_streamp; windowBits: int): int;
-
-implementation
-
-function deflateInit(strm: z_streamp; level: int): int;
-begin
- Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function deflateInit2(strm: z_streamp; level, method, windowBits,
- memLevel, strategy: int): int;
-begin
- Result := deflateInit2_(strm, level, method, windowBits, memLevel,
- strategy, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function inflateInit(strm: z_streamp): int;
-begin
- Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function inflateInit2(strm: z_streamp; windowBits: int): int;
-begin
- Result := inflateInit2_(strm, windowBits, ZLIB_VERSION,
- sizeof(z_stream));
-end;
-
-const
- zlibDLL = 'png32bd.dll';
-
-function adler32; external zlibDLL;
-function crc32; external zlibDLL;
-function deflate; external zlibDLL;
-function deflateCopy; external zlibDLL;
-function deflateEnd; external zlibDLL;
-function deflateInit2_; external zlibDLL;
-function deflateInit_; external zlibDLL;
-function deflateParams; external zlibDLL;
-function deflateReset; external zlibDLL;
-function deflateSetDictionary; external zlibDLL;
-function inflate; external zlibDLL;
-function inflateEnd; external zlibDLL;
-function inflateInit2_; external zlibDLL;
-function inflateInit_; external zlibDLL;
-function inflateReset; external zlibDLL;
-function inflateSetDictionary; external zlibDLL;
-function inflateSync; external zlibDLL;
-
-end.
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.bpr b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.bpr
deleted file mode 100644
index 78bb254088a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.bpr
+++ /dev/null
@@ -1,224 +0,0 @@
-# ---------------------------------------------------------------------------
-!if !$d(BCB)
-BCB = $(MAKEDIR)\..
-!endif
-
-# ---------------------------------------------------------------------------
-# IDE SECTION
-# ---------------------------------------------------------------------------
-# The following section of the project makefile is managed by the BCB IDE.
-# It is recommended to use the IDE to change any of the values in this
-# section.
-# ---------------------------------------------------------------------------
-
-VERSION = BCB.03
-# ---------------------------------------------------------------------------
-PROJECT = d_zlib.lib
-OBJFILES = d_zlib.obj adler32.obj deflate.obj infblock.obj infcodes.obj inffast.obj \
- inflate.obj inftrees.obj infutil.obj trees.obj
-RESFILES =
-RESDEPEN = $(RESFILES)
-LIBFILES =
-LIBRARIES = VCL35.lib
-SPARELIBS = VCL35.lib
-DEFFILE =
-PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \
- dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \
- NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi
-# ---------------------------------------------------------------------------
-PATHCPP = .;
-PATHASM = .;
-PATHPAS = .;
-PATHRC = .;
-DEBUGLIBPATH = $(BCB)\lib\debug
-RELEASELIBPATH = $(BCB)\lib\release
-# ---------------------------------------------------------------------------
-CFLAG1 = -O2 -Ve -d -k- -vi
-CFLAG2 = -I$(BCB)\include;$(BCB)\include\vcl -H=$(BCB)\lib\vcl35.csm
-CFLAG3 = -ff -pr -5
-PFLAGS = -U;$(DEBUGLIBPATH) -I$(BCB)\include;$(BCB)\include\vcl -H -W -$I- -v -JPHN -M
-RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl
-AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zn
-LFLAGS =
-IFLAGS = -g -Gn
-# ---------------------------------------------------------------------------
-ALLOBJ = c0w32.obj $(OBJFILES)
-ALLRES = $(RESFILES)
-ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib
-# ---------------------------------------------------------------------------
-!!ifdef IDEOPTIONS
-
-[Version Info]
-IncludeVerInfo=0
-AutoIncBuild=0
-MajorVer=1
-MinorVer=0
-Release=0
-Build=0
-Debug=0
-PreRelease=0
-Special=0
-Private=0
-DLL=0
-Locale=1040
-CodePage=1252
-
-[Version Info Keys]
-CompanyName=
-FileDescription=
-FileVersion=1.0.0.0
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=1.0.0.0
-Comments=
-
-[HistoryLists\hlIncludePath]
-Count=2
-Item0=$(BCB)\include
-Item1=$(BCB)\include;$(BCB)\include\vcl
-
-[HistoryLists\hlLibraryPath]
-Count=1
-Item0=$(BCB)\lib\obj;$(BCB)\lib
-
-[HistoryLists\hlDebugSourcePath]
-Count=1
-Item0=$(BCB)\source\vcl
-
-[Debugging]
-DebugSourceDirs=
-
-[Parameters]
-RunParams=
-HostApplication=
-
-!endif
-
- ---------------------------------------------------------------------------
-# MAKE SECTION
-# ---------------------------------------------------------------------------
-# This section of the project file is not used by the BCB IDE. It is for
-# the benefit of building from the command-line using the MAKE utility.
-# ---------------------------------------------------------------------------
-
-.autodepend
-# ---------------------------------------------------------------------------
-!if !$d(BCC32)
-BCC32 = bcc32
-!endif
-
-!if !$d(DCC32)
-DCC32 = dcc32
-!endif
-
-!if !$d(TASM32)
-TASM32 = tasm32
-!endif
-
-!if !$d(LINKER)
-LINKER = TLib
-!endif
-
-!if !$d(BRCC32)
-BRCC32 = brcc32
-!endif
-# ---------------------------------------------------------------------------
-!if $d(PATHCPP)
-.PATH.CPP = $(PATHCPP)
-.PATH.C = $(PATHCPP)
-!endif
-
-!if $d(PATHPAS)
-.PATH.PAS = $(PATHPAS)
-!endif
-
-!if $d(PATHASM)
-.PATH.ASM = $(PATHASM)
-!endif
-
-!if $d(PATHRC)
-.PATH.RC = $(PATHRC)
-!endif
-# ---------------------------------------------------------------------------
-!ifdef IDEOPTIONS
-
-[Version Info]
-IncludeVerInfo=0
-AutoIncBuild=0
-MajorVer=1
-MinorVer=0
-Release=0
-Build=0
-Debug=0
-PreRelease=0
-Special=0
-Private=0
-DLL=0
-Locale=1040
-CodePage=1252
-
-[Version Info Keys]
-CompanyName=
-FileDescription=
-FileVersion=1.0.0.0
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=1.0.0.0
-Comments=
-
-[HistoryLists\hlIncludePath]
-Count=2
-Item0=$(BCB)\include;$(BCB)\include\vcl
-Item1=$(BCB)\include
-
-[HistoryLists\hlLibraryPath]
-Count=1
-Item0=$(BCB)\lib\obj;$(BCB)\lib
-
-[HistoryLists\hlDebugSourcePath]
-Count=1
-Item0=$(BCB)\source\vcl
-
-[Debugging]
-DebugSourceDirs=
-
-[Parameters]
-RunParams=
-HostApplication=
-
-!endif
-
-$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE)
- $(BCB)\BIN\$(LINKER) @&&!
- $(LFLAGS) $(IFLAGS) +
- $(ALLOBJ), +
- $(PROJECT),, +
- $(ALLLIB), +
- $(DEFFILE), +
- $(ALLRES)
-!
-# ---------------------------------------------------------------------------
-.pas.hpp:
- $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
-
-.pas.obj:
- $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
-
-.cpp.obj:
- $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< }
-
-.c.obj:
- $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< }
-
-.asm.obj:
- $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@
-
-.rc.res:
- $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $<
-# ---------------------------------------------------------------------------
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.cpp
deleted file mode 100644
index f5dea59b762..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/d_zlib.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <condefs.h>
-#pragma hdrstop
-//---------------------------------------------------------------------------
-USEUNIT("adler32.c");
-USEUNIT("deflate.c");
-USEUNIT("infblock.c");
-USEUNIT("infcodes.c");
-USEUNIT("inffast.c");
-USEUNIT("inflate.c");
-USEUNIT("inftrees.c");
-USEUNIT("infutil.c");
-USEUNIT("trees.c");
-//---------------------------------------------------------------------------
-#define Library
-
-// To add a file to the library use the Project menu 'Add to Project'.
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/readme.txt b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/readme.txt
deleted file mode 100644
index cbd31620d87..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/readme.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-These are files used to compile zlib under Borland C++ Builder 3.
-
-zlib.bpg is the main project group that can be loaded in the BCB IDE and
-loads all other *.bpr projects
-
-zlib.bpr is a project used to create a static zlib.lib library with C calling
-convention for functions.
-
-zlib32.bpr creates a zlib32.dll dynamic link library with Windows standard
-calling convention.
-
-d_zlib.bpr creates a set of .obj files with register calling convention.
-These files are used by zlib.pas to create a Delphi unit containing zlib.
-The d_zlib.lib file generated isn't useful and can be deleted.
-
-zlib.cpp, zlib32.cpp and d_zlib.cpp are used by the above projects.
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpg b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpg
deleted file mode 100644
index b6c9acdf8c9..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpg
+++ /dev/null
@@ -1,26 +0,0 @@
-#------------------------------------------------------------------------------
-VERSION = BWS.01
-#------------------------------------------------------------------------------
-!ifndef ROOT
-ROOT = $(MAKEDIR)\..
-!endif
-#------------------------------------------------------------------------------
-MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**
-DCC = $(ROOT)\bin\dcc32.exe $**
-BRCC = $(ROOT)\bin\brcc32.exe $**
-#------------------------------------------------------------------------------
-PROJECTS = zlib zlib32 d_zlib
-#------------------------------------------------------------------------------
-default: $(PROJECTS)
-#------------------------------------------------------------------------------
-
-zlib: zlib.bpr
- $(MAKE)
-
-zlib32: zlib32.bpr
- $(MAKE)
-
-d_zlib: d_zlib.bpr
- $(MAKE)
-
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpr b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpr
deleted file mode 100644
index cf3945b2523..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.bpr
+++ /dev/null
@@ -1,225 +0,0 @@
-# ---------------------------------------------------------------------------
-!if !$d(BCB)
-BCB = $(MAKEDIR)\..
-!endif
-
-# ---------------------------------------------------------------------------
-# IDE SECTION
-# ---------------------------------------------------------------------------
-# The following section of the project makefile is managed by the BCB IDE.
-# It is recommended to use the IDE to change any of the values in this
-# section.
-# ---------------------------------------------------------------------------
-
-VERSION = BCB.03
-# ---------------------------------------------------------------------------
-PROJECT = zlib.lib
-OBJFILES = zlib.obj adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj \
- infcodes.obj inffast.obj inflate.obj inftrees.obj infutil.obj trees.obj \
- uncompr.obj zutil.obj
-RESFILES =
-RESDEPEN = $(RESFILES)
-LIBFILES =
-LIBRARIES = VCL35.lib
-SPARELIBS = VCL35.lib
-DEFFILE =
-PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \
- dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \
- NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi
-# ---------------------------------------------------------------------------
-PATHCPP = .;
-PATHASM = .;
-PATHPAS = .;
-PATHRC = .;
-DEBUGLIBPATH = $(BCB)\lib\debug
-RELEASELIBPATH = $(BCB)\lib\release
-# ---------------------------------------------------------------------------
-CFLAG1 = -O2 -Ve -d -k- -vi
-CFLAG2 = -I$(BCB)\include;$(BCB)\include\vcl -H=$(BCB)\lib\vcl35.csm
-CFLAG3 = -ff -5
-PFLAGS = -U;$(DEBUGLIBPATH) -I$(BCB)\include;$(BCB)\include\vcl -H -W -$I- -v -JPHN -M
-RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl
-AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zn
-LFLAGS =
-IFLAGS = -g -Gn
-# ---------------------------------------------------------------------------
-ALLOBJ = c0w32.obj $(OBJFILES)
-ALLRES = $(RESFILES)
-ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib
-# ---------------------------------------------------------------------------
-!!ifdef IDEOPTIONS
-
-[Version Info]
-IncludeVerInfo=0
-AutoIncBuild=0
-MajorVer=1
-MinorVer=0
-Release=0
-Build=0
-Debug=0
-PreRelease=0
-Special=0
-Private=0
-DLL=0
-Locale=1040
-CodePage=1252
-
-[Version Info Keys]
-CompanyName=
-FileDescription=
-FileVersion=1.0.0.0
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=1.0.0.0
-Comments=
-
-[HistoryLists\hlIncludePath]
-Count=2
-Item0=$(BCB)\include
-Item1=$(BCB)\include;$(BCB)\include\vcl
-
-[HistoryLists\hlLibraryPath]
-Count=1
-Item0=$(BCB)\lib\obj;$(BCB)\lib
-
-[HistoryLists\hlDebugSourcePath]
-Count=1
-Item0=$(BCB)\source\vcl
-
-[Debugging]
-DebugSourceDirs=
-
-[Parameters]
-RunParams=
-HostApplication=
-
-!endif
-
- ---------------------------------------------------------------------------
-# MAKE SECTION
-# ---------------------------------------------------------------------------
-# This section of the project file is not used by the BCB IDE. It is for
-# the benefit of building from the command-line using the MAKE utility.
-# ---------------------------------------------------------------------------
-
-.autodepend
-# ---------------------------------------------------------------------------
-!if !$d(BCC32)
-BCC32 = bcc32
-!endif
-
-!if !$d(DCC32)
-DCC32 = dcc32
-!endif
-
-!if !$d(TASM32)
-TASM32 = tasm32
-!endif
-
-!if !$d(LINKER)
-LINKER = TLib
-!endif
-
-!if !$d(BRCC32)
-BRCC32 = brcc32
-!endif
-# ---------------------------------------------------------------------------
-!if $d(PATHCPP)
-.PATH.CPP = $(PATHCPP)
-.PATH.C = $(PATHCPP)
-!endif
-
-!if $d(PATHPAS)
-.PATH.PAS = $(PATHPAS)
-!endif
-
-!if $d(PATHASM)
-.PATH.ASM = $(PATHASM)
-!endif
-
-!if $d(PATHRC)
-.PATH.RC = $(PATHRC)
-!endif
-# ---------------------------------------------------------------------------
-!ifdef IDEOPTIONS
-
-[Version Info]
-IncludeVerInfo=0
-AutoIncBuild=0
-MajorVer=1
-MinorVer=0
-Release=0
-Build=0
-Debug=0
-PreRelease=0
-Special=0
-Private=0
-DLL=0
-Locale=1040
-CodePage=1252
-
-[Version Info Keys]
-CompanyName=
-FileDescription=
-FileVersion=1.0.0.0
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=1.0.0.0
-Comments=
-
-[HistoryLists\hlIncludePath]
-Count=2
-Item0=$(BCB)\include;$(BCB)\include\vcl
-Item1=$(BCB)\include
-
-[HistoryLists\hlLibraryPath]
-Count=1
-Item0=$(BCB)\lib\obj;$(BCB)\lib
-
-[HistoryLists\hlDebugSourcePath]
-Count=1
-Item0=$(BCB)\source\vcl
-
-[Debugging]
-DebugSourceDirs=
-
-[Parameters]
-RunParams=
-HostApplication=
-
-!endif
-
-$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE)
- $(BCB)\BIN\$(LINKER) @&&!
- $(LFLAGS) $(IFLAGS) +
- $(ALLOBJ), +
- $(PROJECT),, +
- $(ALLLIB), +
- $(DEFFILE), +
- $(ALLRES)
-!
-# ---------------------------------------------------------------------------
-.pas.hpp:
- $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
-
-.pas.obj:
- $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
-
-.cpp.obj:
- $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< }
-
-.c.obj:
- $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< }
-
-.asm.obj:
- $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@
-
-.rc.res:
- $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $<
-# ---------------------------------------------------------------------------
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.cpp
deleted file mode 100644
index bf6953ba198..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <condefs.h>
-#pragma hdrstop
-//---------------------------------------------------------------------------
-USEUNIT("adler32.c");
-USEUNIT("compress.c");
-USEUNIT("crc32.c");
-USEUNIT("deflate.c");
-USEUNIT("gzio.c");
-USEUNIT("infblock.c");
-USEUNIT("infcodes.c");
-USEUNIT("inffast.c");
-USEUNIT("inflate.c");
-USEUNIT("inftrees.c");
-USEUNIT("infutil.c");
-USEUNIT("trees.c");
-USEUNIT("uncompr.c");
-USEUNIT("zutil.c");
-//---------------------------------------------------------------------------
-#define Library
-
-// To add a file to the library use the Project menu 'Add to Project'.
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.pas b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.pas
deleted file mode 100644
index 10ae4cae256..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib.pas
+++ /dev/null
@@ -1,534 +0,0 @@
-{*******************************************************}
-{ }
-{ Delphi Supplemental Components }
-{ ZLIB Data Compression Interface Unit }
-{ }
-{ Copyright (c) 1997 Borland International }
-{ }
-{*******************************************************}
-
-{ Modified for zlib 1.1.3 by Davide Moretti <dave@rimini.com }
-
-unit zlib;
-
-interface
-
-uses Sysutils, Classes;
-
-type
- TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer;
- TFree = procedure (AppData, Block: Pointer);
-
- // Internal structure. Ignore.
- TZStreamRec = packed record
- next_in: PChar; // next input byte
- avail_in: Integer; // number of bytes available at next_in
- total_in: Integer; // total nb of input bytes read so far
-
- next_out: PChar; // next output byte should be put here
- avail_out: Integer; // remaining free space at next_out
- total_out: Integer; // total nb of bytes output so far
-
- msg: PChar; // last error message, NULL if no error
- internal: Pointer; // not visible by applications
-
- zalloc: TAlloc; // used to allocate the internal state
- zfree: TFree; // used to free the internal state
- AppData: Pointer; // private data object passed to zalloc and zfree
-
- data_type: Integer; // best guess about the data type: ascii or binary
- adler: Integer; // adler32 value of the uncompressed data
- reserved: Integer; // reserved for future use
- end;
-
- // Abstract ancestor class
- TCustomZlibStream = class(TStream)
- private
- FStrm: TStream;
- FStrmPos: Integer;
- FOnProgress: TNotifyEvent;
- FZRec: TZStreamRec;
- FBuffer: array [Word] of Char;
- protected
- procedure Progress(Sender: TObject); dynamic;
- property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
- constructor Create(Strm: TStream);
- end;
-
-{ TCompressionStream compresses data on the fly as data is written to it, and
- stores the compressed data to another stream.
-
- TCompressionStream is write-only and strictly sequential. Reading from the
- stream will raise an exception. Using Seek to move the stream pointer
- will raise an exception.
-
- Output data is cached internally, written to the output stream only when
- the internal output buffer is full. All pending output data is flushed
- when the stream is destroyed.
-
- The Position property returns the number of uncompressed bytes of
- data that have been written to the stream so far.
-
- CompressionRate returns the on-the-fly percentage by which the original
- data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100
- If raw data size = 100 and compressed data size = 25, the CompressionRate
- is 75%
-
- The OnProgress event is called each time the output buffer is filled and
- written to the output stream. This is useful for updating a progress
- indicator when you are writing a large chunk of data to the compression
- stream in a single call.}
-
-
- TCompressionLevel = (clNone, clFastest, clDefault, clMax);
-
- TCompressionStream = class(TCustomZlibStream)
- private
- function GetCompressionRate: Single;
- public
- constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
- destructor Destroy; override;
- function Read(var Buffer; Count: Longint): Longint; override;
- function Write(const Buffer; Count: Longint): Longint; override;
- function Seek(Offset: Longint; Origin: Word): Longint; override;
- property CompressionRate: Single read GetCompressionRate;
- property OnProgress;
- end;
-
-{ TDecompressionStream decompresses data on the fly as data is read from it.
-
- Compressed data comes from a separate source stream. TDecompressionStream
- is read-only and unidirectional; you can seek forward in the stream, but not
- backwards. The special case of setting the stream position to zero is
- allowed. Seeking forward decompresses data until the requested position in
- the uncompressed data has been reached. Seeking backwards, seeking relative
- to the end of the stream, requesting the size of the stream, and writing to
- the stream will raise an exception.
-
- The Position property returns the number of bytes of uncompressed data that
- have been read from the stream so far.
-
- The OnProgress event is called each time the internal input buffer of
- compressed data is exhausted and the next block is read from the input stream.
- This is useful for updating a progress indicator when you are reading a
- large chunk of data from the decompression stream in a single call.}
-
- TDecompressionStream = class(TCustomZlibStream)
- public
- constructor Create(Source: TStream);
- destructor Destroy; override;
- function Read(var Buffer; Count: Longint): Longint; override;
- function Write(const Buffer; Count: Longint): Longint; override;
- function Seek(Offset: Longint; Origin: Word): Longint; override;
- property OnProgress;
- end;
-
-
-
-{ CompressBuf compresses data, buffer to buffer, in one call.
- In: InBuf = ptr to compressed data
- InBytes = number of bytes in InBuf
- Out: OutBuf = ptr to newly allocated buffer containing decompressed data
- OutBytes = number of bytes in OutBuf }
-procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
- out OutBuf: Pointer; out OutBytes: Integer);
-
-
-{ DecompressBuf decompresses data, buffer to buffer, in one call.
- In: InBuf = ptr to compressed data
- InBytes = number of bytes in InBuf
- OutEstimate = zero, or est. size of the decompressed data
- Out: OutBuf = ptr to newly allocated buffer containing decompressed data
- OutBytes = number of bytes in OutBuf }
-procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
- OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
-
-const
- zlib_version = '1.1.3';
-
-type
- EZlibError = class(Exception);
- ECompressionError = class(EZlibError);
- EDecompressionError = class(EZlibError);
-
-function adler32(adler: Integer; buf: PChar; len: Integer): Integer;
-
-implementation
-
-const
- Z_NO_FLUSH = 0;
- Z_PARTIAL_FLUSH = 1;
- Z_SYNC_FLUSH = 2;
- Z_FULL_FLUSH = 3;
- Z_FINISH = 4;
-
- Z_OK = 0;
- Z_STREAM_END = 1;
- Z_NEED_DICT = 2;
- Z_ERRNO = (-1);
- Z_STREAM_ERROR = (-2);
- Z_DATA_ERROR = (-3);
- Z_MEM_ERROR = (-4);
- Z_BUF_ERROR = (-5);
- Z_VERSION_ERROR = (-6);
-
- Z_NO_COMPRESSION = 0;
- Z_BEST_SPEED = 1;
- Z_BEST_COMPRESSION = 9;
- Z_DEFAULT_COMPRESSION = (-1);
-
- Z_FILTERED = 1;
- Z_HUFFMAN_ONLY = 2;
- Z_DEFAULT_STRATEGY = 0;
-
- Z_BINARY = 0;
- Z_ASCII = 1;
- Z_UNKNOWN = 2;
-
- Z_DEFLATED = 8;
-
- _z_errmsg: array[0..9] of PChar = (
- 'need dictionary', // Z_NEED_DICT (2)
- 'stream end', // Z_STREAM_END (1)
- '', // Z_OK (0)
- 'file error', // Z_ERRNO (-1)
- 'stream error', // Z_STREAM_ERROR (-2)
- 'data error', // Z_DATA_ERROR (-3)
- 'insufficient memory', // Z_MEM_ERROR (-4)
- 'buffer error', // Z_BUF_ERROR (-5)
- 'incompatible version', // Z_VERSION_ERROR (-6)
- ''
- );
-
-{$L deflate.obj}
-{$L inflate.obj}
-{$L inftrees.obj}
-{$L trees.obj}
-{$L adler32.obj}
-{$L infblock.obj}
-{$L infcodes.obj}
-{$L infutil.obj}
-{$L inffast.obj}
-
-procedure _tr_init; external;
-procedure _tr_tally; external;
-procedure _tr_flush_block; external;
-procedure _tr_align; external;
-procedure _tr_stored_block; external;
-function adler32; external;
-procedure inflate_blocks_new; external;
-procedure inflate_blocks; external;
-procedure inflate_blocks_reset; external;
-procedure inflate_blocks_free; external;
-procedure inflate_set_dictionary; external;
-procedure inflate_trees_bits; external;
-procedure inflate_trees_dynamic; external;
-procedure inflate_trees_fixed; external;
-procedure inflate_codes_new; external;
-procedure inflate_codes; external;
-procedure inflate_codes_free; external;
-procedure _inflate_mask; external;
-procedure inflate_flush; external;
-procedure inflate_fast; external;
-
-procedure _memset(P: Pointer; B: Byte; count: Integer);cdecl;
-begin
- FillChar(P^, count, B);
-end;
-
-procedure _memcpy(dest, source: Pointer; count: Integer);cdecl;
-begin
- Move(source^, dest^, count);
-end;
-
-
-
-// deflate compresses data
-function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
- recsize: Integer): Integer; external;
-function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
-function deflateEnd(var strm: TZStreamRec): Integer; external;
-
-// inflate decompresses data
-function inflateInit_(var strm: TZStreamRec; version: PChar;
- recsize: Integer): Integer; external;
-function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
-function inflateEnd(var strm: TZStreamRec): Integer; external;
-function inflateReset(var strm: TZStreamRec): Integer; external;
-
-
-function zcalloc(AppData: Pointer; Items, Size: Integer): Pointer;
-begin
- GetMem(Result, Items*Size);
-end;
-
-procedure zcfree(AppData, Block: Pointer);
-begin
- FreeMem(Block);
-end;
-
-function zlibCheck(code: Integer): Integer;
-begin
- Result := code;
- if code < 0 then
- raise EZlibError.Create('error'); //!!
-end;
-
-function CCheck(code: Integer): Integer;
-begin
- Result := code;
- if code < 0 then
- raise ECompressionError.Create('error'); //!!
-end;
-
-function DCheck(code: Integer): Integer;
-begin
- Result := code;
- if code < 0 then
- raise EDecompressionError.Create('error'); //!!
-end;
-
-procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
- out OutBuf: Pointer; out OutBytes: Integer);
-var
- strm: TZStreamRec;
- P: Pointer;
-begin
- FillChar(strm, sizeof(strm), 0);
- OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
- GetMem(OutBuf, OutBytes);
- try
- strm.next_in := InBuf;
- strm.avail_in := InBytes;
- strm.next_out := OutBuf;
- strm.avail_out := OutBytes;
- CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));
- try
- while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
- begin
- P := OutBuf;
- Inc(OutBytes, 256);
- ReallocMem(OutBuf, OutBytes);
- strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
- strm.avail_out := 256;
- end;
- finally
- CCheck(deflateEnd(strm));
- end;
- ReallocMem(OutBuf, strm.total_out);
- OutBytes := strm.total_out;
- except
- FreeMem(OutBuf);
- raise
- end;
-end;
-
-
-procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
- OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
-var
- strm: TZStreamRec;
- P: Pointer;
- BufInc: Integer;
-begin
- FillChar(strm, sizeof(strm), 0);
- BufInc := (InBytes + 255) and not 255;
- if OutEstimate = 0 then
- OutBytes := BufInc
- else
- OutBytes := OutEstimate;
- GetMem(OutBuf, OutBytes);
- try
- strm.next_in := InBuf;
- strm.avail_in := InBytes;
- strm.next_out := OutBuf;
- strm.avail_out := OutBytes;
- DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
- try
- while DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do
- begin
- P := OutBuf;
- Inc(OutBytes, BufInc);
- ReallocMem(OutBuf, OutBytes);
- strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
- strm.avail_out := BufInc;
- end;
- finally
- DCheck(inflateEnd(strm));
- end;
- ReallocMem(OutBuf, strm.total_out);
- OutBytes := strm.total_out;
- except
- FreeMem(OutBuf);
- raise
- end;
-end;
-
-
-// TCustomZlibStream
-
-constructor TCustomZLibStream.Create(Strm: TStream);
-begin
- inherited Create;
- FStrm := Strm;
- FStrmPos := Strm.Position;
-end;
-
-procedure TCustomZLibStream.Progress(Sender: TObject);
-begin
- if Assigned(FOnProgress) then FOnProgress(Sender);
-end;
-
-
-// TCompressionStream
-
-constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
- Dest: TStream);
-const
- Levels: array [TCompressionLevel] of ShortInt =
- (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
-begin
- inherited Create(Dest);
- FZRec.next_out := FBuffer;
- FZRec.avail_out := sizeof(FBuffer);
- CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
-end;
-
-destructor TCompressionStream.Destroy;
-begin
- FZRec.next_in := nil;
- FZRec.avail_in := 0;
- try
- if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
- while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
- and (FZRec.avail_out = 0) do
- begin
- FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
- FZRec.next_out := FBuffer;
- FZRec.avail_out := sizeof(FBuffer);
- end;
- if FZRec.avail_out < sizeof(FBuffer) then
- FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
- finally
- deflateEnd(FZRec);
- end;
- inherited Destroy;
-end;
-
-function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
-begin
- raise ECompressionError.Create('Invalid stream operation');
-end;
-
-function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
-begin
- FZRec.next_in := @Buffer;
- FZRec.avail_in := Count;
- if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
- while (FZRec.avail_in > 0) do
- begin
- CCheck(deflate(FZRec, 0));
- if FZRec.avail_out = 0 then
- begin
- FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
- FZRec.next_out := FBuffer;
- FZRec.avail_out := sizeof(FBuffer);
- FStrmPos := FStrm.Position;
- Progress(Self);
- end;
- end;
- Result := Count;
-end;
-
-function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
-begin
- if (Offset = 0) and (Origin = soFromCurrent) then
- Result := FZRec.total_in
- else
- raise ECompressionError.Create('Invalid stream operation');
-end;
-
-function TCompressionStream.GetCompressionRate: Single;
-begin
- if FZRec.total_in = 0 then
- Result := 0
- else
- Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
-end;
-
-
-// TDecompressionStream
-
-constructor TDecompressionStream.Create(Source: TStream);
-begin
- inherited Create(Source);
- FZRec.next_in := FBuffer;
- FZRec.avail_in := 0;
- DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
-end;
-
-destructor TDecompressionStream.Destroy;
-begin
- inflateEnd(FZRec);
- inherited Destroy;
-end;
-
-function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
-begin
- FZRec.next_out := @Buffer;
- FZRec.avail_out := Count;
- if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
- while (FZRec.avail_out > 0) do
- begin
- if FZRec.avail_in = 0 then
- begin
- FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
- if FZRec.avail_in = 0 then
- begin
- Result := Count - FZRec.avail_out;
- Exit;
- end;
- FZRec.next_in := FBuffer;
- FStrmPos := FStrm.Position;
- Progress(Self);
- end;
- DCheck(inflate(FZRec, 0));
- end;
- Result := Count;
-end;
-
-function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
-begin
- raise EDecompressionError.Create('Invalid stream operation');
-end;
-
-function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
-var
- I: Integer;
- Buf: array [0..4095] of Char;
-begin
- if (Offset = 0) and (Origin = soFromBeginning) then
- begin
- DCheck(inflateReset(FZRec));
- FZRec.next_in := FBuffer;
- FZRec.avail_in := 0;
- FStrm.Position := 0;
- FStrmPos := 0;
- end
- else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
- ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
- begin
- if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
- if Offset > 0 then
- begin
- for I := 1 to Offset div sizeof(Buf) do
- ReadBuffer(Buf, sizeof(Buf));
- ReadBuffer(Buf, Offset mod sizeof(Buf));
- end;
- end
- else
- raise EDecompressionError.Create('Invalid stream operation');
- Result := FZRec.total_out;
-end;
-
-end.
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.bpr b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.bpr
deleted file mode 100644
index cabcec44947..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.bpr
+++ /dev/null
@@ -1,174 +0,0 @@
-# ---------------------------------------------------------------------------
-!if !$d(BCB)
-BCB = $(MAKEDIR)\..
-!endif
-
-# ---------------------------------------------------------------------------
-# IDE SECTION
-# ---------------------------------------------------------------------------
-# The following section of the project makefile is managed by the BCB IDE.
-# It is recommended to use the IDE to change any of the values in this
-# section.
-# ---------------------------------------------------------------------------
-
-VERSION = BCB.03
-# ---------------------------------------------------------------------------
-PROJECT = zlib32.dll
-OBJFILES = zlib32.obj adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj \
- infcodes.obj inffast.obj inflate.obj inftrees.obj infutil.obj trees.obj \
- uncompr.obj zutil.obj
-RESFILES =
-RESDEPEN = $(RESFILES)
-LIBFILES =
-LIBRARIES =
-SPARELIBS =
-DEFFILE =
-PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \
- dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \
- NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi
-# ---------------------------------------------------------------------------
-PATHCPP = .;
-PATHASM = .;
-PATHPAS = .;
-PATHRC = .;
-DEBUGLIBPATH = $(BCB)\lib\debug
-RELEASELIBPATH = $(BCB)\lib\release
-# ---------------------------------------------------------------------------
-CFLAG1 = -WD -O2 -Ve -d -k- -vi -c -tWD
-CFLAG2 = -D_NO_VCL;ZLIB_DLL -I$(BCB)\include
-CFLAG3 = -ff -5
-PFLAGS = -D_NO_VCL;ZLIB_DLL -U$(BCB)\lib;$(RELEASELIBPATH) -I$(BCB)\include -$I- -v \
- -JPHN -M
-RFLAGS = -D_NO_VCL;ZLIB_DLL -i$(BCB)\include
-AFLAGS = /i$(BCB)\include /d_NO_VCL /dZLIB_DLL /mx /w2 /zn
-LFLAGS = -L$(BCB)\lib;$(RELEASELIBPATH) -aa -Tpd -x -Gi
-IFLAGS = -Gn -g
-# ---------------------------------------------------------------------------
-ALLOBJ = c0d32.obj $(OBJFILES)
-ALLRES = $(RESFILES)
-ALLLIB = $(LIBFILES) import32.lib cw32mt.lib
-# ---------------------------------------------------------------------------
-!ifdef IDEOPTIONS
-
-[Version Info]
-IncludeVerInfo=0
-AutoIncBuild=0
-MajorVer=1
-MinorVer=0
-Release=0
-Build=0
-Debug=0
-PreRelease=0
-Special=0
-Private=0
-DLL=1
-Locale=1040
-CodePage=1252
-
-[Version Info Keys]
-CompanyName=
-FileDescription=DLL (GUI)
-FileVersion=1.0.0.0
-InternalName=
-LegalCopyright=
-LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=1.0.0.0
-Comments=
-
-[HistoryLists\hlIncludePath]
-Count=1
-Item0=$(BCB)\include
-
-[HistoryLists\hlLibraryPath]
-Count=1
-Item0=$(BCB)\lib
-
-[HistoryLists\hlConditionals]
-Count=1
-Item0=_NO_VCL;ZLIB_DLL
-
-[Debugging]
-DebugSourceDirs=
-
-[Parameters]
-RunParams=
-HostApplication=
-
-!endif
-
-# ---------------------------------------------------------------------------
-# MAKE SECTION
-# ---------------------------------------------------------------------------
-# This section of the project file is not used by the BCB IDE. It is for
-# the benefit of building from the command-line using the MAKE utility.
-# ---------------------------------------------------------------------------
-
-.autodepend
-# ---------------------------------------------------------------------------
-!if !$d(BCC32)
-BCC32 = bcc32
-!endif
-
-!if !$d(DCC32)
-DCC32 = dcc32
-!endif
-
-!if !$d(TASM32)
-TASM32 = tasm32
-!endif
-
-!if !$d(LINKER)
-LINKER = ilink32
-!endif
-
-!if !$d(BRCC32)
-BRCC32 = brcc32
-!endif
-# ---------------------------------------------------------------------------
-!if $d(PATHCPP)
-.PATH.CPP = $(PATHCPP)
-.PATH.C = $(PATHCPP)
-!endif
-
-!if $d(PATHPAS)
-.PATH.PAS = $(PATHPAS)
-!endif
-
-!if $d(PATHASM)
-.PATH.ASM = $(PATHASM)
-!endif
-
-!if $d(PATHRC)
-.PATH.RC = $(PATHRC)
-!endif
-# ---------------------------------------------------------------------------
-$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE)
- $(BCB)\BIN\$(LINKER) @&&!
- $(LFLAGS) $(IFLAGS) +
- $(ALLOBJ), +
- $(PROJECT),, +
- $(ALLLIB), +
- $(DEFFILE), +
- $(ALLRES)
-!
-# ---------------------------------------------------------------------------
-.pas.hpp:
- $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
-
-.pas.obj:
- $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
-
-.cpp.obj:
- $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< }
-
-.c.obj:
- $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< }
-
-.asm.obj:
- $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@
-
-.rc.res:
- $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $<
-# ---------------------------------------------------------------------------
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.cpp
deleted file mode 100644
index 7372f6b985f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/delphi2/zlib32.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-
-#include <windows.h>
-#pragma hdrstop
-#include <condefs.h>
-
-
-//---------------------------------------------------------------------------
-// Important note about DLL memory management in a VCL DLL:
-//
-//
-//
-// If your DLL uses VCL and exports any functions that pass VCL String objects
-// (or structs/classes containing nested Strings) as parameter or function
-// results, you will need to build both your DLL project and any EXE projects
-// that use your DLL with the dynamic RTL (the RTL DLL). This will change your
-// DLL and its calling EXE's to use BORLNDMM.DLL as their memory manager. In
-// these cases, the file BORLNDMM.DLL should be deployed along with your DLL
-// and the RTL DLL (CP3240MT.DLL). To avoid the requiring BORLNDMM.DLL in
-// these situations, pass string information using "char *" or ShortString
-// parameters and then link with the static RTL.
-//
-//---------------------------------------------------------------------------
-USEUNIT("adler32.c");
-USEUNIT("compress.c");
-USEUNIT("crc32.c");
-USEUNIT("deflate.c");
-USEUNIT("gzio.c");
-USEUNIT("infblock.c");
-USEUNIT("infcodes.c");
-USEUNIT("inffast.c");
-USEUNIT("inflate.c");
-USEUNIT("inftrees.c");
-USEUNIT("infutil.c");
-USEUNIT("trees.c");
-USEUNIT("uncompr.c");
-USEUNIT("zutil.c");
-//---------------------------------------------------------------------------
-#pragma argsused
-int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
-{
- return 1;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/test.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/test.cpp
deleted file mode 100644
index 7d265b3b5c0..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/test.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#include "zfstream.h"
-
-int main() {
-
- // Construct a stream object with this filebuffer. Anything sent
- // to this stream will go to standard out.
- gzofstream os( 1, ios::out );
-
- // This text is getting compressed and sent to stdout.
- // To prove this, run 'test | zcat'.
- os << "Hello, Mommy" << endl;
-
- os << setcompressionlevel( Z_NO_COMPRESSION );
- os << "hello, hello, hi, ho!" << endl;
-
- setcompressionlevel( os, Z_DEFAULT_COMPRESSION )
- << "I'm compressing again" << endl;
-
- os.close();
-
- return 0;
-
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.cpp
deleted file mode 100644
index a690bbefceb..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-
-#include <memory.h>
-#include "zfstream.h"
-
-gzfilebuf::gzfilebuf() :
- file(NULL),
- mode(0),
- own_file_descriptor(0)
-{ }
-
-gzfilebuf::~gzfilebuf() {
-
- sync();
- if ( own_file_descriptor )
- close();
-
-}
-
-gzfilebuf *gzfilebuf::open( const char *name,
- int io_mode ) {
-
- if ( is_open() )
- return NULL;
-
- char char_mode[10];
- char *p;
- memset(char_mode,'\0',10);
- p = char_mode;
-
- if ( io_mode & ios::in ) {
- mode = ios::in;
- *p++ = 'r';
- } else if ( io_mode & ios::app ) {
- mode = ios::app;
- *p++ = 'a';
- } else {
- mode = ios::out;
- *p++ = 'w';
- }
-
- if ( io_mode & ios::binary ) {
- mode |= ios::binary;
- *p++ = 'b';
- }
-
- // Hard code the compression level
- if ( io_mode & (ios::out|ios::app )) {
- *p++ = '9';
- }
-
- if ( (file = gzopen(name, char_mode)) == NULL )
- return NULL;
-
- own_file_descriptor = 1;
-
- return this;
-
-}
-
-gzfilebuf *gzfilebuf::attach( int file_descriptor,
- int io_mode ) {
-
- if ( is_open() )
- return NULL;
-
- char char_mode[10];
- char *p;
- memset(char_mode,'\0',10);
- p = char_mode;
-
- if ( io_mode & ios::in ) {
- mode = ios::in;
- *p++ = 'r';
- } else if ( io_mode & ios::app ) {
- mode = ios::app;
- *p++ = 'a';
- } else {
- mode = ios::out;
- *p++ = 'w';
- }
-
- if ( io_mode & ios::binary ) {
- mode |= ios::binary;
- *p++ = 'b';
- }
-
- // Hard code the compression level
- if ( io_mode & (ios::out|ios::app )) {
- *p++ = '9';
- }
-
- if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
- return NULL;
-
- own_file_descriptor = 0;
-
- return this;
-
-}
-
-gzfilebuf *gzfilebuf::close() {
-
- if ( is_open() ) {
-
- sync();
- gzclose( file );
- file = NULL;
-
- }
-
- return this;
-
-}
-
-int gzfilebuf::setcompressionlevel( short comp_level ) {
-
- return gzsetparams(file, comp_level, -2);
-
-}
-
-int gzfilebuf::setcompressionstrategy( short comp_strategy ) {
-
- return gzsetparams(file, -2, comp_strategy);
-
-}
-
-
-streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
-
- return streampos(EOF);
-
-}
-
-int gzfilebuf::underflow() {
-
- // If the file hasn't been opened for reading, error.
- if ( !is_open() || !(mode & ios::in) )
- return EOF;
-
- // if a buffer doesn't exists, allocate one.
- if ( !base() ) {
-
- if ( (allocate()) == EOF )
- return EOF;
- setp(0,0);
-
- } else {
-
- if ( in_avail() )
- return (unsigned char) *gptr();
-
- if ( out_waiting() ) {
- if ( flushbuf() == EOF )
- return EOF;
- }
-
- }
-
- // Attempt to fill the buffer.
-
- int result = fillbuf();
- if ( result == EOF ) {
- // disable get area
- setg(0,0,0);
- return EOF;
- }
-
- return (unsigned char) *gptr();
-
-}
-
-int gzfilebuf::overflow( int c ) {
-
- if ( !is_open() || !(mode & ios::out) )
- return EOF;
-
- if ( !base() ) {
- if ( allocate() == EOF )
- return EOF;
- setg(0,0,0);
- } else {
- if (in_avail()) {
- return EOF;
- }
- if (out_waiting()) {
- if (flushbuf() == EOF)
- return EOF;
- }
- }
-
- int bl = blen();
- setp( base(), base() + bl);
-
- if ( c != EOF ) {
-
- *pptr() = c;
- pbump(1);
-
- }
-
- return 0;
-
-}
-
-int gzfilebuf::sync() {
-
- if ( !is_open() )
- return EOF;
-
- if ( out_waiting() )
- return flushbuf();
-
- return 0;
-
-}
-
-int gzfilebuf::flushbuf() {
-
- int n;
- char *q;
-
- q = pbase();
- n = pptr() - q;
-
- if ( gzwrite( file, q, n) < n )
- return EOF;
-
- setp(0,0);
-
- return 0;
-
-}
-
-int gzfilebuf::fillbuf() {
-
- int required;
- char *p;
-
- p = base();
-
- required = blen();
-
- int t = gzread( file, p, required );
-
- if ( t <= 0) return EOF;
-
- setg( base(), base(), base()+t);
-
- return t;
-
-}
-
-gzfilestream_common::gzfilestream_common() :
- ios( gzfilestream_common::rdbuf() )
-{ }
-
-gzfilestream_common::~gzfilestream_common()
-{ }
-
-void gzfilestream_common::attach( int fd, int io_mode ) {
-
- if ( !buffer.attach( fd, io_mode) )
- clear( ios::failbit | ios::badbit );
- else
- clear();
-
-}
-
-void gzfilestream_common::open( const char *name, int io_mode ) {
-
- if ( !buffer.open( name, io_mode ) )
- clear( ios::failbit | ios::badbit );
- else
- clear();
-
-}
-
-void gzfilestream_common::close() {
-
- if ( !buffer.close() )
- clear( ios::failbit | ios::badbit );
-
-}
-
-gzfilebuf *gzfilestream_common::rdbuf() {
-
- return &buffer;
-
-}
-
-gzifstream::gzifstream() :
- ios( gzfilestream_common::rdbuf() )
-{
- clear( ios::badbit );
-}
-
-gzifstream::gzifstream( const char *name, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::open( name, io_mode );
-}
-
-gzifstream::gzifstream( int fd, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::attach( fd, io_mode );
-}
-
-gzifstream::~gzifstream() { }
-
-gzofstream::gzofstream() :
- ios( gzfilestream_common::rdbuf() )
-{
- clear( ios::badbit );
-}
-
-gzofstream::gzofstream( const char *name, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::open( name, io_mode );
-}
-
-gzofstream::gzofstream( int fd, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
-{
- gzfilestream_common::attach( fd, io_mode );
-}
-
-gzofstream::~gzofstream() { }
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.h
deleted file mode 100644
index c87fa08e9d1..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream/zfstream.h
+++ /dev/null
@@ -1,142 +0,0 @@
-
-#ifndef _zfstream_h
-#define _zfstream_h
-
-#include <fstream.h>
-#include "zlib.h"
-
-class gzfilebuf : public streambuf {
-
-public:
-
- gzfilebuf( );
- virtual ~gzfilebuf();
-
- gzfilebuf *open( const char *name, int io_mode );
- gzfilebuf *attach( int file_descriptor, int io_mode );
- gzfilebuf *close();
-
- int setcompressionlevel( short comp_level );
- int setcompressionstrategy( short comp_strategy );
-
- inline int is_open() const { return (file !=NULL); }
-
- virtual streampos seekoff( streamoff, ios::seek_dir, int );
-
- virtual int sync();
-
-protected:
-
- virtual int underflow();
- virtual int overflow( int = EOF );
-
-private:
-
- gzFile file;
- short mode;
- short own_file_descriptor;
-
- int flushbuf();
- int fillbuf();
-
-};
-
-class gzfilestream_common : virtual public ios {
-
- friend class gzifstream;
- friend class gzofstream;
- friend gzofstream &setcompressionlevel( gzofstream &, int );
- friend gzofstream &setcompressionstrategy( gzofstream &, int );
-
-public:
- virtual ~gzfilestream_common();
-
- void attach( int fd, int io_mode );
- void open( const char *name, int io_mode );
- void close();
-
-protected:
- gzfilestream_common();
-
-private:
- gzfilebuf *rdbuf();
-
- gzfilebuf buffer;
-
-};
-
-class gzifstream : public gzfilestream_common, public istream {
-
-public:
-
- gzifstream();
- gzifstream( const char *name, int io_mode = ios::in );
- gzifstream( int fd, int io_mode = ios::in );
-
- virtual ~gzifstream();
-
-};
-
-class gzofstream : public gzfilestream_common, public ostream {
-
-public:
-
- gzofstream();
- gzofstream( const char *name, int io_mode = ios::out );
- gzofstream( int fd, int io_mode = ios::out );
-
- virtual ~gzofstream();
-
-};
-
-template<class T> class gzomanip {
- friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);
-public:
- gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
-private:
- gzofstream &(*func)(gzofstream &, T);
- T val;
-};
-
-template<class T> gzofstream &operator<<(gzofstream &s,
- const gzomanip<T> &m) {
- return (*m.func)(s, m.val);
-
-}
-
-inline gzofstream &setcompressionlevel( gzofstream &s, int l ) {
- (s.rdbuf())->setcompressionlevel(l);
- return s;
-}
-
-inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) {
- (s.rdbuf())->setcompressionstrategy(l);
- return s;
-}
-
-inline gzomanip<int> setcompressionlevel(int l)
-{
- return gzomanip<int>(&setcompressionlevel,l);
-}
-
-inline gzomanip<int> setcompressionstrategy(int l)
-{
- return gzomanip<int>(&setcompressionstrategy,l);
-}
-
-#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream.h
deleted file mode 100644
index 43d2332b79b..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *
- * Copyright (c) 1997
- * Christian Michelsen Research AS
- * Advanced Computing
- * Fantoftvegen 38, 5036 BERGEN, Norway
- * http://www.cmr.no
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Christian Michelsen Research AS makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-
-#ifndef ZSTREAM__H
-#define ZSTREAM__H
-
-/*
- * zstream.h - C++ interface to the 'zlib' general purpose compression library
- * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
- */
-
-#include <strstream.h>
-#include <string.h>
-#include <stdio.h>
-#include "zlib.h"
-
-#if defined(_WIN32)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-
-class zstringlen {
-public:
- zstringlen(class izstream&);
- zstringlen(class ozstream&, const char*);
- size_t value() const { return val.word; }
-private:
- struct Val { unsigned char byte; size_t word; } val;
-};
-
-// ----------------------------- izstream -----------------------------
-
-class izstream
-{
- public:
- izstream() : m_fp(0) {}
- izstream(FILE* fp) : m_fp(0) { open(fp); }
- izstream(const char* name) : m_fp(0) { open(name); }
- ~izstream() { close(); }
-
- /* Opens a gzip (.gz) file for reading.
- * open() can be used to read a file which is not in gzip format;
- * in this case read() will directly read from the file without
- * decompression. errno can be checked to distinguish two error
- * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
- */
- void open(const char* name) {
- if (m_fp) close();
- m_fp = ::gzopen(name, "rb");
- }
-
- void open(FILE* fp) {
- SET_BINARY_MODE(fp);
- if (m_fp) close();
- m_fp = ::gzdopen(fileno(fp), "rb");
- }
-
- /* Flushes all pending input if necessary, closes the compressed file
- * and deallocates all the (de)compression state. The return value is
- * the zlib error number (see function error() below).
- */
- int close() {
- int r = ::gzclose(m_fp);
- m_fp = 0; return r;
- }
-
- /* Binary read the given number of bytes from the compressed file.
- */
- int read(void* buf, size_t len) {
- return ::gzread(m_fp, buf, len);
- }
-
- /* 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.
- */
- const char* error(int* errnum) {
- return ::gzerror(m_fp, errnum);
- }
-
- gzFile fp() { return m_fp; }
-
- private:
- gzFile m_fp;
-};
-
-/*
- * Binary read the given (array of) object(s) from the compressed file.
- * If the input file was not in gzip format, read() copies the objects number
- * of bytes into the buffer.
- * returns the number of uncompressed bytes actually read
- * (0 for end of file, -1 for error).
- */
-template <class T, class Items>
-inline int read(izstream& zs, T* x, Items items) {
- return ::gzread(zs.fp(), x, items*sizeof(T));
-}
-
-/*
- * Binary input with the '>' operator.
- */
-template <class T>
-inline izstream& operator>(izstream& zs, T& x) {
- ::gzread(zs.fp(), &x, sizeof(T));
- return zs;
-}
-
-
-inline zstringlen::zstringlen(izstream& zs) {
- zs > val.byte;
- if (val.byte == 255) zs > val.word;
- else val.word = val.byte;
-}
-
-/*
- * Read length of string + the string with the '>' operator.
- */
-inline izstream& operator>(izstream& zs, char* x) {
- zstringlen len(zs);
- ::gzread(zs.fp(), x, len.value());
- x[len.value()] = '\0';
- return zs;
-}
-
-inline char* read_string(izstream& zs) {
- zstringlen len(zs);
- char* x = new char[len.value()+1];
- ::gzread(zs.fp(), x, len.value());
- x[len.value()] = '\0';
- return x;
-}
-
-// ----------------------------- ozstream -----------------------------
-
-class ozstream
-{
- public:
- ozstream() : m_fp(0), m_os(0) {
- }
- ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
- : m_fp(0), m_os(0) {
- open(fp, level);
- }
- ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
- : m_fp(0), m_os(0) {
- open(name, level);
- }
- ~ozstream() {
- close();
- }
-
- /* Opens a gzip (.gz) file for writing.
- * The compression level parameter should be in 0..9
- * errno can be checked to distinguish two error cases
- * (if errno is zero, the zlib error is Z_MEM_ERROR).
- */
- void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
- char mode[4] = "wb\0";
- if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
- if (m_fp) close();
- m_fp = ::gzopen(name, mode);
- }
-
- /* open from a FILE pointer.
- */
- void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
- SET_BINARY_MODE(fp);
- char mode[4] = "wb\0";
- if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
- if (m_fp) close();
- m_fp = ::gzdopen(fileno(fp), mode);
- }
-
- /* Flushes all pending output if necessary, closes the compressed file
- * and deallocates all the (de)compression state. The return value is
- * the zlib error number (see function error() below).
- */
- int close() {
- if (m_os) {
- ::gzwrite(m_fp, m_os->str(), m_os->pcount());
- delete[] m_os->str(); delete m_os; m_os = 0;
- }
- int r = ::gzclose(m_fp); m_fp = 0; return r;
- }
-
- /* Binary write the given number of bytes into the compressed file.
- */
- int write(const void* buf, size_t len) {
- return ::gzwrite(m_fp, (voidp) buf, len);
- }
-
- /* 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). flush() returns Z_OK if
- * the flush_ parameter is Z_FINISH and all output could be flushed.
- * flush() should be called only when strictly necessary because it can
- * degrade compression.
- */
- int flush(int _flush) {
- os_flush();
- return ::gzflush(m_fp, _flush);
- }
-
- /* 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.
- */
- const char* error(int* errnum) {
- return ::gzerror(m_fp, errnum);
- }
-
- gzFile fp() { return m_fp; }
-
- ostream& os() {
- if (m_os == 0) m_os = new ostrstream;
- return *m_os;
- }
-
- void os_flush() {
- if (m_os && m_os->pcount()>0) {
- ostrstream* oss = new ostrstream;
- oss->fill(m_os->fill());
- oss->flags(m_os->flags());
- oss->precision(m_os->precision());
- oss->width(m_os->width());
- ::gzwrite(m_fp, m_os->str(), m_os->pcount());
- delete[] m_os->str(); delete m_os; m_os = oss;
- }
- }
-
- private:
- gzFile m_fp;
- ostrstream* m_os;
-};
-
-/*
- * Binary write the given (array of) object(s) into the compressed file.
- * returns the number of uncompressed bytes actually written
- * (0 in case of error).
- */
-template <class T, class Items>
-inline int write(ozstream& zs, const T* x, Items items) {
- return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
-}
-
-/*
- * Binary output with the '<' operator.
- */
-template <class T>
-inline ozstream& operator<(ozstream& zs, const T& x) {
- ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
- return zs;
-}
-
-inline zstringlen::zstringlen(ozstream& zs, const char* x) {
- val.byte = 255; val.word = ::strlen(x);
- if (val.word < 255) zs < (val.byte = val.word);
- else zs < val;
-}
-
-/*
- * Write length of string + the string with the '<' operator.
- */
-inline ozstream& operator<(ozstream& zs, const char* x) {
- zstringlen len(zs, x);
- ::gzwrite(zs.fp(), (voidp) x, len.value());
- return zs;
-}
-
-#ifdef _MSC_VER
-inline ozstream& operator<(ozstream& zs, char* const& x) {
- return zs < (const char*) x;
-}
-#endif
-
-/*
- * Ascii write with the << operator;
- */
-template <class T>
-inline ostream& operator<<(ozstream& zs, const T& x) {
- zs.os_flush();
- return zs.os() << x;
-}
-
-#endif
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream_test.cpp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream_test.cpp
deleted file mode 100644
index 5bbd56c3ad8..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/iostream2/zstream_test.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "zstream.h"
-#include <math.h>
-#include <stdlib.h>
-#include <iomanip.h>
-
-void main() {
- char h[256] = "Hello";
- char* g = "Goodbye";
- ozstream out("temp.gz");
- out < "This works well" < h < g;
- out.close();
-
- izstream in("temp.gz"); // read it back
- char *x = read_string(in), *y = new char[256], z[256];
- in > y > z;
- in.close();
- cout << x << endl << y << endl << z << endl;
-
- out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results
- out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;
- out << z << endl << y << endl << x << endl;
- out << 1.1234567890123456789 << endl;
-
- delete[] x; delete[] y;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/ChangeLogUnzip b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/ChangeLogUnzip
deleted file mode 100644
index 9987c543cdc..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/ChangeLogUnzip
+++ /dev/null
@@ -1,38 +0,0 @@
-Change in 0.15: (19 Mar 98)
-- fix memory leak in minizip.c
-
-Change in 0.14: (10 Mar 98)
-- fix bugs in minizip.c sample for zipping big file
-- fix problem in month in date handling
-- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
- comment handling
-
-Change in 0.13: (6 Mar 98)
-- fix bugs in zip.c
-- add real minizip sample
-
-Change in 0.12: (4 Mar 98)
-- add zip.c and zip.h for creates .zip file
-- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
-- fix miniunz.c for file without specific record for directory
-
-Change in 0.11: (3 Mar 98)
-- fix bug in unzGetCurrentFileInfo for get extra field and comment
-- enhance miniunz sample, remove the bad unztst.c sample
-
-Change in 0.10: (2 Mar 98)
-- fix bug in unzReadCurrentFile
-- rename unzip* to unz* function and structure
-- remove Windows-like hungary notation variable name
-- modify some structure in unzip.h
-- add somes comment in source
-- remove unzipGetcCurrentFile function
-- replace ZUNZEXPORT by ZEXPORT
-- add unzGetLocalExtrafield for get the local extrafield info
-- add a new sample, miniunz.c
-
-Change in 0.4: (25 Feb 98)
-- suppress the type unzipFileInZip.
- Only on file in the zipfile can be open at the same time
-- fix somes typo in code
-- added tm_unz structure in unzip_file_info (date/time in readable format)
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/miniunz.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/miniunz.c
deleted file mode 100644
index f3b7832878f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/miniunz.c
+++ /dev/null
@@ -1,508 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef unix
-# include <unistd.h>
-# include <utime.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "unzip.h"
-
-#define CASESENSITIVITY (0)
-#define WRITEBUFFERSIZE (8192)
-
-/*
- mini unzip, demo of unzip package
-
- usage :
- Usage : miniunz [-exvlo] file.zip [file_to_extract]
-
- list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
- if it exists
-*/
-
-
-/* change_file_date : change the date/time of a file
- filename : the filename of the file where date/time must be modified
- dosdate : the new date at the MSDos format (4 bytes)
- tmu_date : the SAME new date at the tm_unz format */
-void change_file_date(filename,dosdate,tmu_date)
- const char *filename;
- uLong dosdate;
- tm_unz tmu_date;
-{
-#ifdef WIN32
- HANDLE hFile;
- FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
-
- hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
- 0,NULL,OPEN_EXISTING,0,NULL);
- GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
- DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
- LocalFileTimeToFileTime(&ftLocal,&ftm);
- SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
- CloseHandle(hFile);
-#else
-#ifdef unix
- struct utimbuf ut;
- struct tm newdate;
- newdate.tm_sec = tmu_date.tm_sec;
- newdate.tm_min=tmu_date.tm_min;
- newdate.tm_hour=tmu_date.tm_hour;
- newdate.tm_mday=tmu_date.tm_mday;
- newdate.tm_mon=tmu_date.tm_mon;
- if (tmu_date.tm_year > 1900)
- newdate.tm_year=tmu_date.tm_year - 1900;
- else
- newdate.tm_year=tmu_date.tm_year ;
- newdate.tm_isdst=-1;
-
- ut.actime=ut.modtime=mktime(&newdate);
- utime(filename,&ut);
-#endif
-#endif
-}
-
-
-/* mymkdir and change_file_date are not 100 % portable
- As I don't know well Unix, I wait feedback for the unix portion */
-
-int mymkdir(dirname)
- const char* dirname;
-{
- int ret=0;
-#ifdef WIN32
- ret = mkdir(dirname);
-#else
-#ifdef unix
- ret = mkdir (dirname,0775);
-#endif
-#endif
- return ret;
-}
-
-int makedir (newdir)
- char *newdir;
-{
- char *buffer ;
- char *p;
- int len = strlen(newdir);
-
- if (len <= 0)
- return 0;
-
- buffer = (char*)malloc(len+1);
- strcpy(buffer,newdir);
-
- if (buffer[len-1] == '/') {
- buffer[len-1] = '\0';
- }
- if (mymkdir(buffer) == 0)
- {
- free(buffer);
- return 1;
- }
-
- p = buffer+1;
- while (1)
- {
- char hold;
-
- while(*p && *p != '\\' && *p != '/')
- p++;
- hold = *p;
- *p = 0;
- if ((mymkdir(buffer) == -1) && (errno == ENOENT))
- {
- printf("couldn't create directory %s\n",buffer);
- free(buffer);
- return 0;
- }
- if (hold == 0)
- break;
- *p++ = hold;
- }
- free(buffer);
- return 1;
-}
-
-void do_banner()
-{
- printf("MiniUnz 0.15, demo of zLib + Unz package written by Gilles Vollant\n");
- printf("more info at http://wwww.winimage/zLibDll/unzip.htm\n\n");
-}
-
-void do_help()
-{
- printf("Usage : miniunz [-exvlo] file.zip [file_to_extract]\n\n") ;
-}
-
-
-int do_list(uf)
- unzFile uf;
-{
- uLong i;
- unz_global_info gi;
- int err;
-
- err = unzGetGlobalInfo (uf,&gi);
- if (err!=UNZ_OK)
- printf("error %d with zipfile in unzGetGlobalInfo \n",err);
- printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
- printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
- for (i=0;i<gi.number_entry;i++)
- {
- char filename_inzip[256];
- unz_file_info file_info;
- uLong ratio=0;
- const char *string_method;
- err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
- break;
- }
- if (file_info.uncompressed_size>0)
- ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
-
- if (file_info.compression_method==0)
- string_method="Stored";
- else
- if (file_info.compression_method==Z_DEFLATED)
- {
- uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
- if (iLevel==0)
- string_method="Defl:N";
- else if (iLevel==1)
- string_method="Defl:X";
- else if ((iLevel==2) || (iLevel==3))
- string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
- }
- else
- string_method="Unkn. ";
-
- printf("%7lu %6s %7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
- file_info.uncompressed_size,string_method,file_info.compressed_size,
- ratio,
- (uLong)file_info.tmu_date.tm_mon + 1,
- (uLong)file_info.tmu_date.tm_mday,
- (uLong)file_info.tmu_date.tm_year % 100,
- (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
- (uLong)file_info.crc,filename_inzip);
- if ((i+1)<gi.number_entry)
- {
- err = unzGoToNextFile(uf);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGoToNextFile\n",err);
- break;
- }
- }
- }
-
- return 0;
-}
-
-
-int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite)
- unzFile uf;
- const int* popt_extract_without_path;
- int* popt_overwrite;
-{
- char filename_inzip[256];
- char* filename_withoutpath;
- char* p;
- int err=UNZ_OK;
- FILE *fout=NULL;
- void* buf;
- uInt size_buf;
-
- unz_file_info file_info;
- uLong ratio=0;
- err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
- return err;
- }
-
- size_buf = WRITEBUFFERSIZE;
- buf = (void*)malloc(size_buf);
- if (buf==NULL)
- {
- printf("Error allocating memory\n");
- return UNZ_INTERNALERROR;
- }
-
- p = filename_withoutpath = filename_inzip;
- while ((*p) != '\0')
- {
- if (((*p)=='/') || ((*p)=='\\'))
- filename_withoutpath = p+1;
- p++;
- }
-
- if ((*filename_withoutpath)=='\0')
- {
- if ((*popt_extract_without_path)==0)
- {
- printf("creating directory: %s\n",filename_inzip);
- mymkdir(filename_inzip);
- }
- }
- else
- {
- const char* write_filename;
- int skip=0;
-
- if ((*popt_extract_without_path)==0)
- write_filename = filename_inzip;
- else
- write_filename = filename_withoutpath;
-
- err = unzOpenCurrentFile(uf);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzOpenCurrentFile\n",err);
- }
-
- if (((*popt_overwrite)==0) && (err==UNZ_OK))
- {
- char rep;
- FILE* ftestexist;
- ftestexist = fopen(write_filename,"rb");
- if (ftestexist!=NULL)
- {
- fclose(ftestexist);
- do
- {
- char answer[128];
- printf("The file %s exist. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
- scanf("%1s",answer);
- rep = answer[0] ;
- if ((rep>='a') && (rep<='z'))
- rep -= 0x20;
- }
- while ((rep!='Y') && (rep!='N') && (rep!='A'));
- }
-
- if (rep == 'N')
- skip = 1;
-
- if (rep == 'A')
- *popt_overwrite=1;
- }
-
- if ((skip==0) && (err==UNZ_OK))
- {
- fout=fopen(write_filename,"wb");
-
- /* some zipfile don't contain directory alone before file */
- if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
- (filename_withoutpath!=(char*)filename_inzip))
- {
- char c=*(filename_withoutpath-1);
- *(filename_withoutpath-1)='\0';
- makedir(write_filename);
- *(filename_withoutpath-1)=c;
- fout=fopen(write_filename,"wb");
- }
-
- if (fout==NULL)
- {
- printf("error opening %s\n",write_filename);
- }
- }
-
- if (fout!=NULL)
- {
- printf(" extracting: %s\n",write_filename);
-
- do
- {
- err = unzReadCurrentFile(uf,buf,size_buf);
- if (err<0)
- {
- printf("error %d with zipfile in unzReadCurrentFile\n",err);
- break;
- }
- if (err>0)
- if (fwrite(buf,err,1,fout)!=1)
- {
- printf("error in writing extracted file\n");
- err=UNZ_ERRNO;
- break;
- }
- }
- while (err>0);
- fclose(fout);
- if (err==0)
- change_file_date(write_filename,file_info.dosDate,
- file_info.tmu_date);
- }
-
- if (err==UNZ_OK)
- {
- err = unzCloseCurrentFile (uf);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzCloseCurrentFile\n",err);
- }
- }
- else
- unzCloseCurrentFile(uf); /* don't lose the error */
- }
-
- free(buf);
- return err;
-}
-
-
-int do_extract(uf,opt_extract_without_path,opt_overwrite)
- unzFile uf;
- int opt_extract_without_path;
- int opt_overwrite;
-{
- uLong i;
- unz_global_info gi;
- int err;
- FILE* fout=NULL;
-
- err = unzGetGlobalInfo (uf,&gi);
- if (err!=UNZ_OK)
- printf("error %d with zipfile in unzGetGlobalInfo \n",err);
-
- for (i=0;i<gi.number_entry;i++)
- {
- if (do_extract_currentfile(uf,&opt_extract_without_path,
- &opt_overwrite) != UNZ_OK)
- break;
-
- if ((i+1)<gi.number_entry)
- {
- err = unzGoToNextFile(uf);
- if (err!=UNZ_OK)
- {
- printf("error %d with zipfile in unzGoToNextFile\n",err);
- break;
- }
- }
- }
-
- return 0;
-}
-
-int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite)
- unzFile uf;
- const char* filename;
- int opt_extract_without_path;
- int opt_overwrite;
-{
- int err = UNZ_OK;
- if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
- {
- printf("file %s not found in the zipfile\n",filename);
- return 2;
- }
-
- if (do_extract_currentfile(uf,&opt_extract_without_path,
- &opt_overwrite) == UNZ_OK)
- return 0;
- else
- return 1;
-}
-
-
-int main(argc,argv)
- int argc;
- char *argv[];
-{
- const char *zipfilename=NULL;
- const char *filename_to_extract=NULL;
- int i;
- int opt_do_list=0;
- int opt_do_extract=1;
- int opt_do_extract_withoutpath=0;
- int opt_overwrite=0;
- char filename_try[512];
- unzFile uf=NULL;
-
- do_banner();
- if (argc==1)
- {
- do_help();
- exit(0);
- }
- else
- {
- for (i=1;i<argc;i++)
- {
- if ((*argv[i])=='-')
- {
- const char *p=argv[i]+1;
-
- while ((*p)!='\0')
- {
- char c=*(p++);;
- if ((c=='l') || (c=='L'))
- opt_do_list = 1;
- if ((c=='v') || (c=='V'))
- opt_do_list = 1;
- if ((c=='x') || (c=='X'))
- opt_do_extract = 1;
- if ((c=='e') || (c=='E'))
- opt_do_extract = opt_do_extract_withoutpath = 1;
- if ((c=='o') || (c=='O'))
- opt_overwrite=1;
- }
- }
- else
- {
- if (zipfilename == NULL)
- zipfilename = argv[i];
- else if (filename_to_extract==NULL)
- filename_to_extract = argv[i] ;
- }
- }
- }
-
- if (zipfilename!=NULL)
- {
- strcpy(filename_try,zipfilename);
- uf = unzOpen(zipfilename);
- if (uf==NULL)
- {
- strcat(filename_try,".zip");
- uf = unzOpen(filename_try);
- }
- }
-
- if (uf==NULL)
- {
- printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
- exit (1);
- }
- printf("%s opened\n",filename_try);
-
- if (opt_do_list==1)
- return do_list(uf);
- else if (opt_do_extract==1)
- {
- if (filename_to_extract == NULL)
- return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite);
- else
- return do_extract_onefile(uf,filename_to_extract,
- opt_do_extract_withoutpath,opt_overwrite);
- }
- unzCloseCurrentFile(uf);
-
- return 0; /* to avoid warning */
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/minizip.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/minizip.c
deleted file mode 100644
index 5e492d209b1..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/minizip.c
+++ /dev/null
@@ -1,302 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef unix
-# include <unistd.h>
-# include <utime.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "zip.h"
-
-
-#define WRITEBUFFERSIZE (16384)
-#define MAXFILENAME (256)
-
-#ifdef WIN32
-uLong filetime(f, tmzip, dt)
- char *f; /* name of file to get info on */
- tm_zip *tmzip; /* return value: access, modific. and creation times */
- uLong *dt; /* dostime */
-{
- int ret = 0;
- {
- FILETIME ftLocal;
- HANDLE hFind;
- WIN32_FIND_DATA ff32;
-
- hFind = FindFirstFile(f,&ff32);
- if (hFind != INVALID_HANDLE_VALUE)
- {
- FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
- FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
- FindClose(hFind);
- ret = 1;
- }
- }
- return ret;
-}
-#else
-#ifdef unix
-uLong filetime(f, tmzip, dt)
- char *f; /* name of file to get info on */
- tm_zip *tmzip; /* return value: access, modific. and creation times */
- uLong *dt; /* dostime */
-{
- int ret=0;
- struct stat s; /* results of stat() */
- struct tm* filedate;
- time_t tm_t=0;
-
- if (strcmp(f,"-")!=0)
- {
- char name[MAXFILENAME];
- int len = strlen(f);
- strcpy(name, f);
- if (name[len - 1] == '/')
- name[len - 1] = '\0';
- /* not all systems allow stat'ing a file with / appended */
- if (stat(name,&s)==0)
- {
- tm_t = s.st_mtime;
- ret = 1;
- }
- }
- filedate = localtime(&tm_t);
-
- tmzip->tm_sec = filedate->tm_sec;
- tmzip->tm_min = filedate->tm_min;
- tmzip->tm_hour = filedate->tm_hour;
- tmzip->tm_mday = filedate->tm_mday;
- tmzip->tm_mon = filedate->tm_mon ;
- tmzip->tm_year = filedate->tm_year;
-
- return ret;
-}
-#else
-uLong filetime(f, tmzip, dt)
- char *f; /* name of file to get info on */
- tm_zip *tmzip; /* return value: access, modific. and creation times */
- uLong *dt; /* dostime */
-{
- return 0;
-}
-#endif
-#endif
-
-
-
-
-int check_exist_file(filename)
- const char* filename;
-{
- FILE* ftestexist;
- int ret = 1;
- ftestexist = fopen(filename,"rb");
- if (ftestexist==NULL)
- ret = 0;
- else
- fclose(ftestexist);
- return ret;
-}
-
-void do_banner()
-{
- printf("MiniZip 0.15, demo of zLib + Zip package written by Gilles Vollant\n");
- printf("more info at http://wwww.winimage/zLibDll/unzip.htm\n\n");
-}
-
-void do_help()
-{
- printf("Usage : minizip [-o] file.zip [files_to_add]\n\n") ;
-}
-
-int main(argc,argv)
- int argc;
- char *argv[];
-{
- int i;
- int opt_overwrite=0;
- int opt_compress_level=Z_DEFAULT_COMPRESSION;
- int zipfilenamearg = 0;
- char filename_try[MAXFILENAME];
- int zipok;
- int err=0;
- int size_buf=0;
- void* buf=NULL,
-
-
- do_banner();
- if (argc==1)
- {
- do_help();
- exit(0);
- return 0;
- }
- else
- {
- for (i=1;i<argc;i++)
- {
- if ((*argv[i])=='-')
- {
- const char *p=argv[i]+1;
-
- while ((*p)!='\0')
- {
- char c=*(p++);;
- if ((c=='o') || (c=='O'))
- opt_overwrite = 1;
- if ((c>='0') && (c<='9'))
- opt_compress_level = c-'0';
- }
- }
- else
- if (zipfilenamearg == 0)
- zipfilenamearg = i ;
- }
- }
-
- size_buf = WRITEBUFFERSIZE;
- buf = (void*)malloc(size_buf);
- if (buf==NULL)
- {
- printf("Error allocating memory\n");
- return ZIP_INTERNALERROR;
- }
-
- if (zipfilenamearg==0)
- zipok=0;
- else
- {
- int i,len;
- int dot_found=0;
-
- zipok = 1 ;
- strcpy(filename_try,argv[zipfilenamearg]);
- len=strlen(filename_try);
- for (i=0;i<len;i++)
- if (filename_try[i]=='.')
- dot_found=1;
-
- if (dot_found==0)
- strcat(filename_try,".zip");
-
- if (opt_overwrite==0)
- if (check_exist_file(filename_try)!=0)
- {
- char rep;
- do
- {
- char answer[128];
- printf("The file %s exist. Overwrite ? [y]es, [n]o : ",filename_try);
- scanf("%1s",answer);
- rep = answer[0] ;
- if ((rep>='a') && (rep<='z'))
- rep -= 0x20;
- }
- while ((rep!='Y') && (rep!='N'));
- if (rep=='N')
- zipok = 0;
- }
- }
-
- if (zipok==1)
- {
- zipFile zf;
- int errclose;
- zf = zipOpen(filename_try,0);
- if (zf == NULL)
- {
- printf("error opening %s\n",filename_try);
- err= ZIP_ERRNO;
- }
- else
- printf("creating %s\n",filename_try);
-
- for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
- {
- if (((*(argv[i]))!='-') && ((*(argv[i]))!='/'))
- {
- FILE * fin;
- int size_read;
- const char* filenameinzip = argv[i];
- zip_fileinfo zi;
-
- zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
- zi.tmz_date.tm_mday = zi.tmz_date.tm_min = zi.tmz_date.tm_year = 0;
- zi.dosDate = 0;
- zi.internal_fa = 0;
- zi.external_fa = 0;
- filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
-
-
- err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
- NULL,0,NULL,0,NULL /* comment*/,
- (opt_compress_level != 0) ? Z_DEFLATED : 0,
- opt_compress_level);
-
- if (err != ZIP_OK)
- printf("error in opening %s in zipfile\n",filenameinzip);
- else
- {
- fin = fopen(filenameinzip,"rb");
- if (fin==NULL)
- {
- err=ZIP_ERRNO;
- printf("error in opening %s for reading\n",filenameinzip);
- }
- }
-
- if (err == ZIP_OK)
- do
- {
- err = ZIP_OK;
- size_read = fread(buf,1,size_buf,fin);
- if (size_read < size_buf)
- if (feof(fin)==0)
- {
- printf("error in reading %s\n",filenameinzip);
- err = ZIP_ERRNO;
- }
-
- if (size_read>0)
- {
- err = zipWriteInFileInZip (zf,buf,size_read);
- if (err<0)
- {
- printf("error in writing %s in the zipfile\n",
- filenameinzip);
- }
-
- }
- } while ((err == ZIP_OK) && (size_read>0));
-
- fclose(fin);
- if (err<0)
- err=ZIP_ERRNO;
- else
- {
- err = zipCloseFileInZip(zf);
- if (err!=ZIP_OK)
- printf("error in closing %s in the zipfile\n",
- filenameinzip);
- }
- }
- }
- errclose = zipClose(zf,NULL);
- if (errclose != ZIP_OK)
- printf("error in closing %s\n",filename_try);
- }
-
- free(buf);
- exit(0);
- return 0; /* to avoid warning */
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/readme.txt b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/readme.txt
deleted file mode 100644
index 1fc023c720b..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/readme.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-
-UnZip 0.15 additionnal library
-
-
- This unzip package allow extract file from .ZIP file, compatible with
-PKZip 2.04g, WinZip, InfoZip tools and compatible.
-
- Multi volume ZipFile (span) are not supported, and old compression used by old
-PKZip 1.x are not supported.
-
-See probdesc.zip from PKWare for specification of .ZIP format.
-
-What is Unzip
- The Zlib library support the deflate compression and the creation of gzip (.gz)
-file. Zlib is free and small.
- The .Zip format, which can contain several compressed files (.gz can containt
-only one file) is a very popular format. This is why I've written a package for reading file compressed in Zipfile.
-
-Using Unzip package
-
-You need source of Zlib (get zlib111.zip and read zlib.h).
-Get unzlb015.zip and read unzip.h (whith documentation of unzip functions)
-
-The Unzip package is only two file : unzip.h and unzip.c. But it use the Zlib
- files.
-unztst.c is a simple sample program, which list file in a zipfile and display
- README.TXT or FILE_ID.DIZ (if these files are found).
-miniunz.c is a mini unzip program.
-
-I'm also currenlyt writing a zipping portion (zip.h, zip.c and test with minizip.c)
-
-Please email me for feedback.
-I hope my source is compatible with Unix system, but I need your help for be sure
-
-Latest revision : Mar 04th, 1998
-
-Check http://www.winimage.com/zLibDll/unzip.html for up to date info.
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.c
deleted file mode 100644
index ff71a474da1..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.c
+++ /dev/null
@@ -1,1294 +0,0 @@
-/* unzip.c -- IO on .zip files using zlib
- Version 0.15 beta, Mar 19th, 1998,
-
- Read unzip.h for more info
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-
-#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
- !defined(CASESENSITIVITYDEFAULT_NO)
-#define CASESENSITIVITYDEFAULT_NO
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-const char unz_copyright[] =
- " unzip 0.15 Copyright 1998 Gilles Vollant ";
-
-/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info_internal_s
-{
- uLong offset_curfile;/* relative offset of local header 4 bytes */
-} unz_file_info_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
- when reading and decompress it */
-typedef struct
-{
- char *read_buffer; /* internal buffer for compressed data */
- z_stream stream; /* zLib stream structure for inflate */
-
- uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
- uLong stream_initialised; /* flag set if stream structure is initialised*/
-
- uLong offset_local_extrafield;/* offset of the local extra field */
- uInt size_local_extrafield;/* size of the local extra field */
- uLong pos_local_extrafield; /* position in the local extra field in read*/
-
- uLong crc32; /* crc32 of all data uncompressed */
- uLong crc32_wait; /* crc32 we must obtain after decompress all */
- uLong rest_read_compressed; /* number of byte to be decompressed */
- uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
- FILE* file; /* io structore of the zipfile */
- uLong compression_method; /* compression method (0==store) */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-} file_in_zip_read_info_s;
-
-
-/* unz_s contain internal information about the zipfile
-*/
-typedef struct
-{
- FILE* file; /* io structore of the zipfile */
- unz_global_info gi; /* public global information */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- uLong num_file; /* number of the current file in the zipfile*/
- uLong pos_in_central_dir; /* pos of the current file in the central dir*/
- uLong current_file_ok; /* flag about the usability of the current file*/
- uLong central_pos; /* position of the beginning of the central dir*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory with
- respect to the starting disk number */
-
- unz_file_info cur_file_info; /* public info about the current file in zip*/
- unz_file_info_internal cur_file_info_internal; /* private info about it*/
- file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
- file if we are decompressing it */
-} unz_s;
-
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unzlocal_getByte(fin,pi)
- FILE *fin;
- int *pi;
-{
- unsigned char c;
- int err = fread(&c, 1, 1, fin);
- if (err==1)
- {
- *pi = (int)c;
- return UNZ_OK;
- }
- else
- {
- if (ferror(fin))
- return UNZ_ERRNO;
- else
- return UNZ_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unzlocal_getShort (fin,pX)
- FILE* fin;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(fin,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(fin,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int unzlocal_getLong (fin,pX)
- FILE* fin;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(fin,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(fin,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(fin,&i);
- x += ((uLong)i)<<16;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(fin,&i);
- x += ((uLong)i)<<24;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (fileName1,fileName2)
- const char* fileName1;
- const char* fileName2;
-{
- for (;;)
- {
- char c1=*(fileName1++);
- char c2=*(fileName2++);
- if ((c1>='a') && (c1<='z'))
- c1 -= 0x20;
- if ((c2>='a') && (c2<='z'))
- c2 -= 0x20;
- if (c1=='\0')
- return ((c2=='\0') ? 0 : -1);
- if (c2=='\0')
- return 1;
- if (c1<c2)
- return -1;
- if (c1>c2)
- return 1;
- }
-}
-
-
-#ifdef CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
- const char* fileName1;
- const char* fileName2;
- int iCaseSensitivity;
-{
- if (iCaseSensitivity==0)
- iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
- if (iCaseSensitivity==1)
- return strcmp(fileName1,fileName2);
-
- return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#define BUFREADCOMMENT (0x400)
-
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong unzlocal_SearchCentralDir(fin)
- FILE *fin;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (fseek(fin,0,SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ftell( fin );
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (fseek(fin,uReadPos,SEEK_SET)!=0)
- break;
-
- if (fread(buf,(uInt)uReadSize,1,fin)!=1)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
- "zlib/zlib109.zip".
- If the zipfile cannot be opened (file don't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-extern unzFile ZEXPORT unzOpen (path)
- const char *path;
-{
- unz_s us;
- unz_s *s;
- uLong central_pos,uL;
- FILE * fin ;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
-
- int err=UNZ_OK;
-
- if (unz_copyright[0]!=' ')
- return NULL;
-
- fin=fopen(path,"rb");
- if (fin==NULL)
- return NULL;
-
- central_pos = unzlocal_SearchCentralDir(fin);
- if (central_pos==0)
- err=UNZ_ERRNO;
-
- if (fseek(fin,central_pos,SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
- /* the signature, already checked */
- if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of this disk */
- if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir */
- if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((number_entry_CD!=us.gi.number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=UNZ_BADZIPFILE;
-
- /* size of the central directory */
- if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* zipfile comment length */
- if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
- (err==UNZ_OK))
- err=UNZ_BADZIPFILE;
-
- if (err!=UNZ_OK)
- {
- fclose(fin);
- return NULL;
- }
-
- us.file=fin;
- us.byte_before_the_zipfile = central_pos -
- (us.offset_central_dir+us.size_central_dir);
- us.central_pos = central_pos;
- us.pfile_in_zip_read = NULL;
-
-
- s=(unz_s*)ALLOC(sizeof(unz_s));
- *s=us;
- unzGoToFirstFile((unzFile)s);
- return (unzFile)s;
-}
-
-
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (file)
- unzFile file;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- if (s->pfile_in_zip_read!=NULL)
- unzCloseCurrentFile(file);
-
- fclose(s->file);
- TRYFREE(s);
- return UNZ_OK;
-}
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
- unzFile file;
- unz_global_info *pglobal_info;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- *pglobal_info=s->gi;
- return UNZ_OK;
-}
-
-
-/*
- Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
- uLong ulDosDate;
- tm_unz* ptm;
-{
- uLong uDate;
- uDate = (uLong)(ulDosDate>>16);
- ptm->tm_mday = (uInt)(uDate&0x1f) ;
- ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
- ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
- ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
- ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
- ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
- Get Info about the current file in the zipfile, with internal only info
-*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
- unz_file_info *pfile_info,
- unz_file_info_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-
-local int unzlocal_GetCurrentFileInfoInternal (file,
- pfile_info,
- pfile_info_internal,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- unz_file_info_internal *pfile_info_internal;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- unz_s* s;
- unz_file_info file_info;
- unz_file_info_internal file_info_internal;
- int err=UNZ_OK;
- uLong uMagic;
- long lSeek=0;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
-
- /* we check the magic */
- if (err==UNZ_OK)
- if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x02014b50)
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
- err=UNZ_ERRNO;
-
- unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
- if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
- err=UNZ_ERRNO;
-
- lSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_filename<fileNameBufferSize)
- {
- *(szFileName+file_info.size_filename)='\0';
- uSizeRead = file_info.size_filename;
- }
- else
- uSizeRead = fileNameBufferSize;
-
- if ((file_info.size_filename>0) && (fileNameBufferSize>0))
- if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
- err=UNZ_ERRNO;
- lSeek -= uSizeRead;
- }
-
-
- if ((err==UNZ_OK) && (extraField!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_extra<extraFieldBufferSize)
- uSizeRead = file_info.size_file_extra;
- else
- uSizeRead = extraFieldBufferSize;
-
- if (lSeek!=0)
- if (fseek(s->file,lSeek,SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
- if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
- err=UNZ_ERRNO;
- lSeek += file_info.size_file_extra - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_extra;
-
-
- if ((err==UNZ_OK) && (szComment!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_comment<commentBufferSize)
- {
- *(szComment+file_info.size_file_comment)='\0';
- uSizeRead = file_info.size_file_comment;
- }
- else
- uSizeRead = commentBufferSize;
-
- if (lSeek!=0)
- if (fseek(s->file,lSeek,SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- if ((file_info.size_file_comment>0) && (commentBufferSize>0))
- if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
- err=UNZ_ERRNO;
- lSeek+=file_info.size_file_comment - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_comment;
-
- if ((err==UNZ_OK) && (pfile_info!=NULL))
- *pfile_info=file_info;
-
- if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
- *pfile_info_internal=file_info_internal;
-
- return err;
-}
-
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo (file,
- pfile_info,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
- szFileName,fileNameBufferSize,
- extraField,extraFieldBufferSize,
- szComment,commentBufferSize);
-}
-
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- s->pos_in_central_dir=s->offset_central_dir;
- s->num_file=0;
- err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (file)
- unzFile file;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
- if (s->num_file+1==s->gi.number_entry)
- return UNZ_END_OF_LIST_OF_FILE;
-
- s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
- s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
- s->num_file++;
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzipStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
- unzFile file;
- const char *szFileName;
- int iCaseSensitivity;
-{
- unz_s* s;
- int err;
-
-
- uLong num_fileSaved;
- uLong pos_in_central_dirSaved;
-
-
- if (file==NULL)
- return UNZ_PARAMERROR;
-
- if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
- return UNZ_PARAMERROR;
-
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- num_fileSaved = s->num_file;
- pos_in_central_dirSaved = s->pos_in_central_dir;
-
- err = unzGoToFirstFile(file);
-
- while (err == UNZ_OK)
- {
- char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
- unzGetCurrentFileInfo(file,NULL,
- szCurrentFileName,sizeof(szCurrentFileName)-1,
- NULL,0,NULL,0);
- if (unzStringFileNameCompare(szCurrentFileName,
- szFileName,iCaseSensitivity)==0)
- return UNZ_OK;
- err = unzGoToNextFile(file);
- }
-
- s->num_file = num_fileSaved ;
- s->pos_in_central_dir = pos_in_central_dirSaved ;
- return err;
-}
-
-
-/*
- Read the local header of the current zipfile
- Check the coherency of the local header and info in the end of central
- directory about this file
- store in *piSizeVar the size of extra info in local header
- (filename and size of extra field data)
-*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
- poffset_local_extrafield,
- psize_local_extrafield)
- unz_s* s;
- uInt* piSizeVar;
- uLong *poffset_local_extrafield;
- uInt *psize_local_extrafield;
-{
- uLong uMagic,uData,uFlags;
- uLong size_filename;
- uLong size_extra_field;
- int err=UNZ_OK;
-
- *piSizeVar = 0;
- *poffset_local_extrafield = 0;
- *psize_local_extrafield = 0;
-
- if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
- s->byte_before_the_zipfile,SEEK_SET)!=0)
- return UNZ_ERRNO;
-
-
- if (err==UNZ_OK)
- if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x04034b50)
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
-/*
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
- err=UNZ_BADZIPFILE;
-*/
- if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
- err=UNZ_BADZIPFILE;
-
- if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
-
- if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
- err=UNZ_BADZIPFILE;
-
- *piSizeVar += (uInt)size_filename;
-
- if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
- err=UNZ_ERRNO;
- *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
- SIZEZIPLOCALHEADER + size_filename;
- *psize_local_extrafield = (uInt)size_extra_field;
-
- *piSizeVar += (uInt)size_extra_field;
-
- return err;
-}
-
-/*
- Open for reading data the current file in the zipfile.
- If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
- int Store;
- uInt iSizeVar;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uLong offset_local_extrafield; /* offset of the local extra field */
- uInt size_local_extrafield; /* size of the local extra field */
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_PARAMERROR;
-
- if (s->pfile_in_zip_read != NULL)
- unzCloseCurrentFile(file);
-
- if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
- &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
- return UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info = (file_in_zip_read_info_s*)
- ALLOC(sizeof(file_in_zip_read_info_s));
- if (pfile_in_zip_read_info==NULL)
- return UNZ_INTERNALERROR;
-
- pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
- pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
- pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
- pfile_in_zip_read_info->pos_local_extrafield=0;
-
- if (pfile_in_zip_read_info->read_buffer==NULL)
- {
- TRYFREE(pfile_in_zip_read_info);
- return UNZ_INTERNALERROR;
- }
-
- pfile_in_zip_read_info->stream_initialised=0;
-
- if ((s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
- Store = s->cur_file_info.compression_method==0;
-
- pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
- pfile_in_zip_read_info->crc32=0;
- pfile_in_zip_read_info->compression_method =
- s->cur_file_info.compression_method;
- pfile_in_zip_read_info->file=s->file;
- pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
- pfile_in_zip_read_info->stream.total_out = 0;
-
- if (!Store)
- {
- pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
- pfile_in_zip_read_info->stream.zfree = (free_func)0;
- pfile_in_zip_read_info->stream.opaque = (voidpf)0;
-
- err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
- if (err == Z_OK)
- pfile_in_zip_read_info->stream_initialised=1;
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END.
- * In unzip, i don't wait absolutely Z_STREAM_END because I known the
- * size of both compressed and uncompressed data
- */
- }
- pfile_in_zip_read_info->rest_read_compressed =
- s->cur_file_info.compressed_size ;
- pfile_in_zip_read_info->rest_read_uncompressed =
- s->cur_file_info.uncompressed_size ;
-
-
- pfile_in_zip_read_info->pos_in_zipfile =
- s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
- iSizeVar;
-
- pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
-
- s->pfile_in_zip_read = pfile_in_zip_read_info;
- return UNZ_OK;
-}
-
-
-/*
- Read bytes from the current file.
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile (file, buf, len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- int err=UNZ_OK;
- uInt iRead = 0;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->read_buffer == NULL))
- return UNZ_END_OF_LIST_OF_FILE;
- if (len==0)
- return 0;
-
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
- pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
- if (len>pfile_in_zip_read_info->rest_read_uncompressed)
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
- while (pfile_in_zip_read_info->stream.avail_out>0)
- {
- if ((pfile_in_zip_read_info->stream.avail_in==0) &&
- (pfile_in_zip_read_info->rest_read_compressed>0))
- {
- uInt uReadThis = UNZ_BUFSIZE;
- if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
- uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
- if (uReadThis == 0)
- return UNZ_EOF;
- if (fseek(pfile_in_zip_read_info->file,
- pfile_in_zip_read_info->pos_in_zipfile +
- pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
- return UNZ_ERRNO;
- if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
- pfile_in_zip_read_info->file)!=1)
- return UNZ_ERRNO;
- pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
- pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
- pfile_in_zip_read_info->stream.next_in =
- (Bytef*)pfile_in_zip_read_info->read_buffer;
- pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
- }
-
- if (pfile_in_zip_read_info->compression_method==0)
- {
- uInt uDoCopy,i ;
- if (pfile_in_zip_read_info->stream.avail_out <
- pfile_in_zip_read_info->stream.avail_in)
- uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
- else
- uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
- for (i=0;i<uDoCopy;i++)
- *(pfile_in_zip_read_info->stream.next_out+i) =
- *(pfile_in_zip_read_info->stream.next_in+i);
-
- pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
- pfile_in_zip_read_info->stream.next_out,
- uDoCopy);
- pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
- pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
- pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
- pfile_in_zip_read_info->stream.next_out += uDoCopy;
- pfile_in_zip_read_info->stream.next_in += uDoCopy;
- pfile_in_zip_read_info->stream.total_out += uDoCopy;
- iRead += uDoCopy;
- }
- else
- {
- uLong uTotalOutBefore,uTotalOutAfter;
- const Bytef *bufBefore;
- uLong uOutThis;
- int flush=Z_SYNC_FLUSH;
-
- uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
- bufBefore = pfile_in_zip_read_info->stream.next_out;
-
- /*
- if ((pfile_in_zip_read_info->rest_read_uncompressed ==
- pfile_in_zip_read_info->stream.avail_out) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- flush = Z_FINISH;
- */
- err=inflate(&pfile_in_zip_read_info->stream,flush);
-
- uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
- uOutThis = uTotalOutAfter-uTotalOutBefore;
-
- pfile_in_zip_read_info->crc32 =
- crc32(pfile_in_zip_read_info->crc32,bufBefore,
- (uInt)(uOutThis));
-
- pfile_in_zip_read_info->rest_read_uncompressed -=
- uOutThis;
-
- iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
- if (err==Z_STREAM_END)
- return (iRead==0) ? UNZ_EOF : iRead;
- if (err!=Z_OK)
- break;
- }
- }
-
- if (err==Z_OK)
- return iRead;
- return err;
-}
-
-
-/*
- Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
- return 1;
- else
- return 0;
-}
-
-
-
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field that can be read
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uInt read_now;
- uLong size_to_read;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
- pfile_in_zip_read_info->pos_local_extrafield);
-
- if (buf==NULL)
- return (int)size_to_read;
-
- if (len>size_to_read)
- read_now = (uInt)size_to_read;
- else
- read_now = (uInt)len ;
-
- if (read_now==0)
- return 0;
-
- if (fseek(pfile_in_zip_read_info->file,
- pfile_in_zip_read_info->offset_local_extrafield +
- pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
- return UNZ_ERRNO;
-
- return (int)read_now;
-}
-
-/*
- Close the file in zip opened with unzipOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
-
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
- {
- if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
- err=UNZ_CRCERROR;
- }
-
-
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- pfile_in_zip_read_info->read_buffer = NULL;
- if (pfile_in_zip_read_info->stream_initialised)
- inflateEnd(&pfile_in_zip_read_info->stream);
-
- pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
-
- s->pfile_in_zip_read=NULL;
-
- return err;
-}
-
-
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
- unzFile file;
- char *szComment;
- uLong uSizeBuf;
-{
- int err=UNZ_OK;
- unz_s* s;
- uLong uReadThis ;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- uReadThis = uSizeBuf;
- if (uReadThis>s->gi.size_comment)
- uReadThis = s->gi.size_comment;
-
- if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (uReadThis>0)
- {
- *szComment='\0';
- if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
- return UNZ_ERRNO;
- }
-
- if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
- *(szComment+s->gi.size_comment)='\0';
- return (int)uReadThis;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.def
deleted file mode 100644
index f6ede89bc96..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.def
+++ /dev/null
@@ -1,15 +0,0 @@
- unzOpen @61
- unzClose @62
- unzGetGlobalInfo @63
- unzGetCurrentFileInfo @64
- unzGoToFirstFile @65
- unzGoToNextFile @66
- unzOpenCurrentFile @67
- unzReadCurrentFile @68
- unztell @70
- unzeof @71
- unzCloseCurrentFile @72
- unzGetGlobalComment @73
- unzStringFileNameCompare @74
- unzLocateFile @75
- unzGetLocalExtrafield @76
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.h
deleted file mode 100644
index 76692cb703c..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/unzip.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
- Version 0.15 beta, Mar 19th, 1998,
-
- Copyright (C) 1998 Gilles Vollant
-
- This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Encryption and multi volume ZipFile (span) are not supported.
- Old compressions used by old PKZip 1.x are not supported
-
- THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
- CAN CHANGE IN FUTURE VERSION !!
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
-
- Condition of use and distribution are the same than zlib :
-
- 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.
-
-
-*/
-/* for more info about .ZIP format, see
- ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip */
-
-#ifndef _unz_H
-#define _unz_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK (0)
-#define UNZ_END_OF_LIST_OF_FILE (-100)
-#define UNZ_ERRNO (Z_ERRNO)
-#define UNZ_EOF (0)
-#define UNZ_PARAMERROR (-102)
-#define UNZ_BADZIPFILE (-103)
-#define UNZ_INTERNALERROR (-104)
-#define UNZ_CRCERROR (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
- These data comes from the end of central dir */
-typedef struct unz_global_info_s
-{
- uLong number_entry; /* total number of entries in
- the central dir on this disk */
- uLong size_comment; /* size of the global comment of the zipfile */
-} unz_global_info;
-
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info_s
-{
- uLong version; /* version made by 2 bytes */
- uLong version_needed; /* version needed to extract 2 bytes */
- uLong flag; /* general purpose bit flag 2 bytes */
- uLong compression_method; /* compression method 2 bytes */
- uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
- uLong crc; /* crc-32 4 bytes */
- uLong compressed_size; /* compressed size 4 bytes */
- uLong uncompressed_size; /* uncompressed size 4 bytes */
- uLong size_filename; /* filename length 2 bytes */
- uLong size_file_extra; /* extra field length 2 bytes */
- uLong size_file_comment; /* file comment length 2 bytes */
-
- uLong disk_num_start; /* disk number start 2 bytes */
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-
- tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity));
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
- "zlib/zlib111.zip".
- If the zipfile cannot be opened (file don't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
- unz_global_info *pglobal_info));
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
- char *szComment,
- uLong uSizeBuf));
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
- const char *szFileName,
- int iCaseSensitivity));
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
- unz_file_info *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-/*
- Get Info about the current file
- if pfile_info!=NULL, the *pfile_info structure will contain somes info about
- the current file
- if szFileName!=NULL, the filemane string will be copied in szFileName
- (fileNameBufferSize is the size of the buffer)
- if extraField!=NULL, the extra field information will be copied in extraField
- (extraFieldBufferSize is the size of the buffer).
- This is the Central-header version of the extra field
- if szComment!=NULL, the comment string of the file will be copied in szComment
- (commentBufferSize is the size of the buffer)
-*/
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
- from it, and close it (you can close it before reading all the file)
- */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
- Open for reading data the current file in the zipfile.
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
- Close the file in zip opened with unzOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read bytes from the current file (opened by unzOpenCurrentFile)
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-/*
- Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _unz_H */
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.c
deleted file mode 100644
index 0cae64ab7b1..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/* zip.c -- IO on .zip files using zlib
- Version 0.15 beta, Mar 19th, 1998,
-
- Read zip.h for more info
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "zip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#ifndef VERSIONMADEBY
-# define VERSIONMADEBY (0x0) /* platform depedent */
-#endif
-
-#ifndef Z_BUFSIZE
-#define Z_BUFSIZE (16384)
-#endif
-
-#ifndef Z_MAXFILENAMEINZIP
-#define Z_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-/*
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-*/
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-const char zip_copyright[] =
- " zip 0.15 Copyright 1998 Gilles Vollant ";
-
-
-#define SIZEDATA_INDATABLOCK (4096-(4*4))
-
-#define LOCALHEADERMAGIC (0x04034b50)
-#define CENTRALHEADERMAGIC (0x02014b50)
-#define ENDHEADERMAGIC (0x06054b50)
-
-#define FLAG_LOCALHEADER_OFFSET (0x06)
-#define CRC_LOCALHEADER_OFFSET (0x0e)
-
-#define SIZECENTRALHEADER (0x2e) /* 46 */
-
-typedef struct linkedlist_datablock_internal_s
-{
- struct linkedlist_datablock_internal_s* next_datablock;
- uLong avail_in_this_block;
- uLong filled_in_this_block;
- uLong unused; /* for future use and alignement */
- unsigned char data[SIZEDATA_INDATABLOCK];
-} linkedlist_datablock_internal;
-
-typedef struct linkedlist_data_s
-{
- linkedlist_datablock_internal* first_block;
- linkedlist_datablock_internal* last_block;
-} linkedlist_data;
-
-
-typedef struct
-{
- z_stream stream; /* zLib stream structure for inflate */
- int stream_initialised; /* 1 is stream is initialised */
- uInt pos_in_buffered_data; /* last written byte in buffered_data */
-
- uLong pos_local_header; /* offset of the local header of the file
- currenty writing */
- char* central_header; /* central header data for the current file */
- uLong size_centralheader; /* size of the central header for cur file */
- uLong flag; /* flag of the file currently writing */
-
- int method; /* compression method of file currenty wr.*/
- Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
- uLong dosDate;
- uLong crc32;
-} curfile_info;
-
-typedef struct
-{
- FILE * filezip;
- linkedlist_data central_dir;/* datablock with central dir in construction*/
- int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
- curfile_info ci; /* info on the file curretly writing */
-
- uLong begin_pos; /* position of the beginning of the zipfile */
- uLong number_entry;
-} zip_internal;
-
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
- linkedlist_datablock_internal* ldi;
- ldi = (linkedlist_datablock_internal*)
- ALLOC(sizeof(linkedlist_datablock_internal));
- if (ldi!=NULL)
- {
- ldi->next_datablock = NULL ;
- ldi->filled_in_this_block = 0 ;
- ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
- }
- return ldi;
-}
-
-local void free_datablock(ldi)
- linkedlist_datablock_internal* ldi;
-{
- while (ldi!=NULL)
- {
- linkedlist_datablock_internal* ldinext = ldi->next_datablock;
- TRYFREE(ldi);
- ldi = ldinext;
- }
-}
-
-local void init_linkedlist(ll)
- linkedlist_data* ll;
-{
- ll->first_block = ll->last_block = NULL;
-}
-
-local void free_linkedlist(ll)
- linkedlist_data* ll;
-{
- free_datablock(ll->first_block);
- ll->first_block = ll->last_block = NULL;
-}
-
-
-local int add_data_in_datablock(ll,buf,len)
- linkedlist_data* ll;
- const void* buf;
- uLong len;
-{
- linkedlist_datablock_internal* ldi;
- const unsigned char* from_copy;
-
- if (ll==NULL)
- return ZIP_INTERNALERROR;
-
- if (ll->last_block == NULL)
- {
- ll->first_block = ll->last_block = allocate_new_datablock();
- if (ll->first_block == NULL)
- return ZIP_INTERNALERROR;
- }
-
- ldi = ll->last_block;
- from_copy = (unsigned char*)buf;
-
- while (len>0)
- {
- uInt copy_this;
- uInt i;
- unsigned char* to_copy;
-
- if (ldi->avail_in_this_block==0)
- {
- ldi->next_datablock = allocate_new_datablock();
- if (ldi->next_datablock == NULL)
- return ZIP_INTERNALERROR;
- ldi = ldi->next_datablock ;
- ll->last_block = ldi;
- }
-
- if (ldi->avail_in_this_block < len)
- copy_this = (uInt)ldi->avail_in_this_block;
- else
- copy_this = (uInt)len;
-
- to_copy = &(ldi->data[ldi->filled_in_this_block]);
-
- for (i=0;i<copy_this;i++)
- *(to_copy+i)=*(from_copy+i);
-
- ldi->filled_in_this_block += copy_this;
- ldi->avail_in_this_block -= copy_this;
- from_copy += copy_this ;
- len -= copy_this;
- }
- return ZIP_OK;
-}
-
-
-local int write_datablock(fout,ll)
- FILE * fout;
- linkedlist_data* ll;
-{
- linkedlist_datablock_internal* ldi;
- ldi = ll->first_block;
- while (ldi!=NULL)
- {
- if (ldi->filled_in_this_block > 0)
- if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,1,fout)!=1)
- return ZIP_ERRNO;
- ldi = ldi->next_datablock;
- }
- return ZIP_OK;
-}
-
-/****************************************************************************/
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
- nbByte == 1, 2 or 4 (byte, short or long)
-*/
-
-local int ziplocal_putValue OF((FILE *file, uLong x, int nbByte));
-local int ziplocal_putValue (file, x, nbByte)
- FILE *file;
- uLong x;
- int nbByte;
-{
- unsigned char buf[4];
- int n;
- for (n = 0; n < nbByte; n++) {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
- if (fwrite(buf,nbByte,1,file)!=1)
- return ZIP_ERRNO;
- else
- return ZIP_OK;
-}
-
-local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
-local void ziplocal_putValue_inmemory (dest, x, nbByte)
- void* dest;
- uLong x;
- int nbByte;
-{
- unsigned char* buf=(unsigned char*)dest;
- int n;
- for (n = 0; n < nbByte; n++) {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
-}
-/****************************************************************************/
-
-
-local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
- tm_zip* ptm;
- uLong dosDate;
-{
- uLong year = (uLong)ptm->tm_year;
- if (year>1980)
- year-=1980;
- else if (year>80)
- year-=80;
- return
- (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
- ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
-}
-
-
-/****************************************************************************/
-
-extern zipFile ZEXPORT zipOpen (pathname, append)
- const char *pathname;
- int append;
-{
- zip_internal ziinit;
- zip_internal* zi;
-
- ziinit.filezip = fopen(pathname,(append == 0) ? "wb" : "ab");
- if (ziinit.filezip == NULL)
- return NULL;
- ziinit.begin_pos = ftell(ziinit.filezip);
- ziinit.in_opened_file_inzip = 0;
- ziinit.ci.stream_initialised = 0;
- ziinit.number_entry = 0;
- init_linkedlist(&(ziinit.central_dir));
-
-
- zi = (zip_internal*)ALLOC(sizeof(zip_internal));
- if (zi==NULL)
- {
- fclose(ziinit.filezip);
- return NULL;
- }
-
- *zi = ziinit;
- return (zipFile)zi;
-}
-
-extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
-{
- zip_internal* zi;
- uInt size_filename;
- uInt size_comment;
- uInt i;
- int err = ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- if ((method!=0) && (method!=Z_DEFLATED))
- return ZIP_PARAMERROR;
-
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- if (err != ZIP_OK)
- return err;
- }
-
-
- if (filename==NULL)
- filename="-";
-
- if (comment==NULL)
- size_comment = 0;
- else
- size_comment = strlen(comment);
-
- size_filename = strlen(filename);
-
- if (zipfi == NULL)
- zi->ci.dosDate = 0;
- else
- {
- if (zipfi->dosDate != 0)
- zi->ci.dosDate = zipfi->dosDate;
- else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
- }
-
- zi->ci.flag = 0;
- if ((level==8) || (level==9))
- zi->ci.flag |= 2;
- if ((level==2))
- zi->ci.flag |= 4;
- if ((level==1))
- zi->ci.flag |= 6;
-
- zi->ci.crc32 = 0;
- zi->ci.method = method;
- zi->ci.stream_initialised = 0;
- zi->ci.pos_in_buffered_data = 0;
- zi->ci.pos_local_header = ftell(zi->filezip);
- zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
- size_extrafield_global + size_comment;
- zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
-
- ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
- /* version info */
- ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
- ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
-
- ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header,4);
-
- for (i=0;i<size_filename;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
-
- for (i=0;i<size_extrafield_global;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
- *(((const char*)extrafield_global)+i);
-
- for (i=0;i<size_comment;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
- size_extrafield_global+i) = *(filename+i);
- if (zi->ci.central_header == NULL)
- return ZIP_INTERNALERROR;
-
- /* write the local header */
- err = ziplocal_putValue(zi->filezip,(uLong)LOCALHEADERMAGIC,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)20,2);/* version needed to extract */
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.flag,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.method,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.dosDate,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* crc 32, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* compressed size, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* uncompressed size, unknown */
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)size_filename,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)size_extrafield_local,2);
-
- if ((err==ZIP_OK) && (size_filename>0))
- if (fwrite(filename,(uInt)size_filename,1,zi->filezip)!=1)
- err = ZIP_ERRNO;
-
- if ((err==ZIP_OK) && (size_extrafield_local>0))
- if (fwrite(extrafield_local,(uInt)size_extrafield_local,1,zi->filezip)
- !=1)
- err = ZIP_ERRNO;
-
- zi->ci.stream.avail_in = (uInt)0;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- zi->ci.stream.total_in = 0;
- zi->ci.stream.total_out = 0;
-
- if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED))
- {
- zi->ci.stream.zalloc = (alloc_func)0;
- zi->ci.stream.zfree = (free_func)0;
- zi->ci.stream.opaque = (voidpf)0;
-
- err = deflateInit2(&zi->ci.stream, level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
-
- if (err==Z_OK)
- zi->ci.stream_initialised = 1;
- }
-
-
- if (err==Z_OK)
- zi->in_opened_file_inzip = 1;
- return err;
-}
-
-extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
- zipFile file;
- const voidp buf;
- unsigned len;
-{
- zip_internal* zi;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
-
- zi->ci.stream.next_in = buf;
- zi->ci.stream.avail_in = len;
- zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
-
- while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
- {
- if (zi->ci.stream.avail_out == 0)
- {
- if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
- !=1)
- err = ZIP_ERRNO;
- zi->ci.pos_in_buffered_data = 0;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
-
- if (zi->ci.method == Z_DEFLATED)
- {
- uLong uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_NO_FLUSH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-
- }
- else
- {
- uInt copy_this,i;
- if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
- copy_this = zi->ci.stream.avail_in;
- else
- copy_this = zi->ci.stream.avail_out;
- for (i=0;i<copy_this;i++)
- *(((char*)zi->ci.stream.next_out)+i) =
- *(((const char*)zi->ci.stream.next_in)+i);
- {
- zi->ci.stream.avail_in -= copy_this;
- zi->ci.stream.avail_out-= copy_this;
- zi->ci.stream.next_in+= copy_this;
- zi->ci.stream.next_out+= copy_this;
- zi->ci.stream.total_in+= copy_this;
- zi->ci.stream.total_out+= copy_this;
- zi->ci.pos_in_buffered_data += copy_this;
- }
- }
- }
-
- return 0;
-}
-
-extern int ZEXPORT zipCloseFileInZip (file)
- zipFile file;
-{
- zip_internal* zi;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
- zi->ci.stream.avail_in = 0;
-
- if (zi->ci.method == Z_DEFLATED)
- while (err==ZIP_OK)
- {
- uLong uTotalOutBefore;
- if (zi->ci.stream.avail_out == 0)
- {
- if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
- !=1)
- err = ZIP_ERRNO;
- zi->ci.pos_in_buffered_data = 0;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
- uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_FINISH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
- }
-
- if (err==Z_STREAM_END)
- err=ZIP_OK; /* this is normal */
-
- if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
- if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
- !=1)
- err = ZIP_ERRNO;
-
- if ((zi->ci.method == Z_DEFLATED) && (err==ZIP_OK))
- {
- err=deflateEnd(&zi->ci.stream);
- zi->ci.stream_initialised = 0;
- }
-
- ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)zi->ci.crc32,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,
- (uLong)zi->ci.stream.total_out,4); /*compr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+24,
- (uLong)zi->ci.stream.total_in,4); /*uncompr size*/
-
- if (err==ZIP_OK)
- err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
- (uLong)zi->ci.size_centralheader);
- free(zi->ci.central_header);
-
- if (err==ZIP_OK)
- {
- long cur_pos_inzip = ftell(zi->filezip);
- if (fseek(zi->filezip,
- zi->ci.pos_local_header + 14,SEEK_SET)!=0)
- err = ZIP_ERRNO;
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.crc32,4); /* crc 32, unknown */
-
- if (err==ZIP_OK) /* compressed size, unknown */
- err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_out,4);
-
- if (err==ZIP_OK) /* uncompressed size, unknown */
- err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_in,4);
-
- if (fseek(zi->filezip,
- cur_pos_inzip,SEEK_SET)!=0)
- err = ZIP_ERRNO;
- }
-
- zi->number_entry ++;
- zi->in_opened_file_inzip = 0;
-
- return err;
-}
-
-extern int ZEXPORT zipClose (file, global_comment)
- zipFile file;
- const char* global_comment;
-{
- zip_internal* zi;
- int err = 0;
- uLong size_centraldir = 0;
- uLong centraldir_pos_inzip ;
- uInt size_global_comment;
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- }
-
- if (global_comment==NULL)
- size_global_comment = 0;
- else
- size_global_comment = strlen(global_comment);
-
-
- centraldir_pos_inzip = ftell(zi->filezip);
- if (err==ZIP_OK)
- {
- linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
- while (ldi!=NULL)
- {
- if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
- if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,
- 1,zi->filezip) !=1 )
- err = ZIP_ERRNO;
-
- size_centraldir += ldi->filled_in_this_block;
- ldi = ldi->next_datablock;
- }
- }
- free_datablock(zi->central_dir.first_block);
-
- if (err==ZIP_OK) /* Magic End */
- err = ziplocal_putValue(zi->filezip,(uLong)ENDHEADERMAGIC,4);
-
- if (err==ZIP_OK) /* number of this disk */
- err = ziplocal_putValue(zi->filezip,(uLong)0,2);
-
- if (err==ZIP_OK) /* number of the disk with the start of the central directory */
- err = ziplocal_putValue(zi->filezip,(uLong)0,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
- err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir */
- err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* size of the central directory */
- err = ziplocal_putValue(zi->filezip,(uLong)size_centraldir,4);
-
- if (err==ZIP_OK) /* offset of start of central directory with respect to the
- starting disk number */
- err = ziplocal_putValue(zi->filezip,(uLong)centraldir_pos_inzip ,4);
-
- if (err==ZIP_OK) /* zipfile comment length */
- err = ziplocal_putValue(zi->filezip,(uLong)size_global_comment,2);
-
- if ((err==ZIP_OK) && (size_global_comment>0))
- if (fwrite(global_comment,(uInt)size_global_comment,1,zi->filezip) !=1 )
- err = ZIP_ERRNO;
- fclose(zi->filezip);
- TRYFREE(zi);
-
- return err;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.def
deleted file mode 100644
index 5d5079fbcee..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.def
+++ /dev/null
@@ -1,5 +0,0 @@
- zipOpen @80
- zipOpenNewFileInZip @81
- zipWriteInFileInZip @82
- zipCloseFileInZip @83
- zipClose @84
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.h b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.h
deleted file mode 100644
index 678260b330b..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zip.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* zip.h -- IO for compress .zip files using zlib
- Version 0.15 alpha, Mar 19th, 1998,
-
- Copyright (C) 1998 Gilles Vollant
-
- This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Encryption and multi volume ZipFile (span) are not supported.
- Old compressions used by old PKZip 1.x are not supported
-
- For uncompress .zip file, look at unzip.h
-
- THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
- CAN CHANGE IN FUTURE VERSION !!
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/zip.htm for evolution
-
- Condition of use and distribution are the same than zlib :
-
- 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.
-
-
-*/
-
-/* for more info about .ZIP format, see
- ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _zip_H
-#define _zip_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK (0)
-#define ZIP_ERRNO (Z_ERRNO)
-#define ZIP_PARAMERROR (-102)
-#define ZIP_INTERNALERROR (-104)
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
- tm_zip tmz_date; /* date in understandable format */
- uLong dosDate; /* if dos_date == 0, tmu_date is used */
-/* uLong flag; */ /* general purpose bit flag 2 bytes */
-
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-} zip_fileinfo;
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-/*
- Create a zipfile.
- pathname contain on Windows NT a filename like "c:\\zlib\\zlib111.zip" or on
- an Unix computer "zlib/zlib111.zip".
- if the file pathname exist and append=1, the zip will be created at the end
- of the file. (useful if the file contain a self extractor code)
- If the zipfile cannot be opened, the return value is NULL.
- Else, the return value is a zipFile Handle, usable with other function
- of this zip package.
-
-
-*/
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level));
-/*
- Open a file in the ZIP for writing.
- filename : the filename in zip (if NULL, '-' without quote will be used
- *zipfi contain supplemental information
- if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
- contains the extrafield data the the local header
- if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
- contains the extrafield data the the local header
- if comment != NULL, comment contain the comment string
- method contain the compression method (0 for store, Z_DEFLATED for deflate)
- level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-*/
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
- const voidp buf,
- unsigned len));
-/*
- Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
- Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
- const char* global_comment));
-/*
- Close the zipfile
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip_H */
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.def b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.def
deleted file mode 100644
index 7e9d60d55d9..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.def
+++ /dev/null
@@ -1,74 +0,0 @@
-LIBRARY "zlib"
-
-DESCRIPTION '"""zlib data compression library"""'
-
-
-VERSION 1.11
-
-
-HEAPSIZE 1048576,8192
-
-EXPORTS
- adler32 @1
- compress @2
- crc32 @3
- deflate @4
- deflateCopy @5
- deflateEnd @6
- deflateInit2_ @7
- deflateInit_ @8
- deflateParams @9
- deflateReset @10
- deflateSetDictionary @11
- gzclose @12
- gzdopen @13
- gzerror @14
- gzflush @15
- gzopen @16
- gzread @17
- gzwrite @18
- inflate @19
- inflateEnd @20
- inflateInit2_ @21
- inflateInit_ @22
- inflateReset @23
- inflateSetDictionary @24
- inflateSync @25
- uncompress @26
- zlibVersion @27
- gzprintf @28
- gzputc @29
- gzgetc @30
- gzseek @31
- gzrewind @32
- gztell @33
- gzeof @34
- gzsetparams @35
- zError @36
- inflateSyncPoint @37
- get_crc_table @38
- compress2 @39
- gzputs @40
- gzgets @41
-
- unzOpen @61
- unzClose @62
- unzGetGlobalInfo @63
- unzGetCurrentFileInfo @64
- unzGoToFirstFile @65
- unzGoToNextFile @66
- unzOpenCurrentFile @67
- unzReadCurrentFile @68
- unztell @70
- unzeof @71
- unzCloseCurrentFile @72
- unzGetGlobalComment @73
- unzStringFileNameCompare @74
- unzLocateFile @75
- unzGetLocalExtrafield @76
-
- zipOpen @80
- zipOpenNewFileInZip @81
- zipWriteInFileInZip @82
- zipCloseFileInZip @83
- zipClose @84
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsp b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsp
deleted file mode 100644
index a70d4d4a6b0..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsp
+++ /dev/null
@@ -1,651 +0,0 @@
-# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 5.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602
-
-CFG=zlibvc - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "zlibvc.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\
- "Win32 (ALPHA) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\
- "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\
- "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\Release"
-# PROP BASE Intermediate_Dir ".\Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\Release"
-# PROP Intermediate_Dir ".\Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\Debug"
-# PROP BASE Intermediate_Dir ".\Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\Debug"
-# PROP Intermediate_Dir ".\Debug"
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "_DEBUG"
-# ADD RSC /l 0x40c /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlibvc__"
-# PROP BASE Intermediate_Dir "zlibvc__"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "zlibvc__"
-# PROP Intermediate_Dir "zlibvc__"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
-# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlibvc_0"
-# PROP BASE Intermediate_Dir "zlibvc_0"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "zlibvc_0"
-# PROP Intermediate_Dir "zlibvc_0"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "zlibvc_1"
-# PROP BASE Intermediate_Dir "zlibvc_1"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "zlibvc_1"
-# PROP Intermediate_Dir "zlibvc_1"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-CPP=cl.exe
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
-# SUBTRACT CPP /YX
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-# ADD BASE RSC /l 0x40c /d "NDEBUG"
-# ADD RSC /l 0x40c /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
-# SUBTRACT BASE LINK32 /pdb:none
-# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll"
-# SUBTRACT LINK32 /pdb:none
-
-!ENDIF
-
-# Begin Target
-
-# Name "zlibvc - Win32 Release"
-# Name "zlibvc - Win32 Debug"
-# Name "zlibvc - Win32 ReleaseAxp"
-# Name "zlibvc - Win32 ReleaseWithoutAsm"
-# Name "zlibvc - Win32 ReleaseWithoutCrtdll"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
-# Begin Source File
-
-SOURCE=.\adler32.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_ADLER=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\compress.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_COMPR=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\crc32.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_CRC32=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\deflate.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_DEFLA=\
- ".\deflate.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\gvmat32c.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\gzio.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_GZIO_=\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\infblock.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFBL=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\infcodes.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFCO=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inffast.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\inffast.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFFA=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inffast.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\inflate.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFLA=\
- ".\infblock.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\inftrees.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFTR=\
- ".\inftrees.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\infutil.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_INFUT=\
- ".\infblock.h"\
- ".\infcodes.h"\
- ".\inftrees.h"\
- ".\infutil.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\trees.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_TREES=\
- ".\deflate.h"\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\uncompr.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_UNCOM=\
- ".\zconf.h"\
- ".\zlib.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\unzip.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\zip.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\zlib.rc
-# End Source File
-# Begin Source File
-
-SOURCE=.\zlibvc.def
-# End Source File
-# Begin Source File
-
-SOURCE=.\zutil.c
-
-!IF "$(CFG)" == "zlibvc - Win32 Release"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
-
-DEP_CPP_ZUTIL=\
- ".\zconf.h"\
- ".\zlib.h"\
- ".\zutil.h"\
-
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
-
-!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-
-!ENDIF
-
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
-# Begin Source File
-
-SOURCE=.\deflate.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\infblock.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\infcodes.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\inffast.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\inftrees.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\infutil.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\zconf.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\zlib.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\zutil.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsw b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsw
deleted file mode 100644
index 493cd870365..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/minizip/zlibvc.dsw
+++ /dev/null
@@ -1,41 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 5.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/makefile.w32 b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/makefile.w32
deleted file mode 100644
index c99dc28cf55..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/makefile.w32
+++ /dev/null
@@ -1,63 +0,0 @@
-# Makefile for zlib. Modified for mingw32
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile,
-#
-# make -fmakefile.w32
-#
-
-CC=gcc
-
-# Generate dependencies (see end of the file)
-
-CPPFLAGS=-MMD
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is not found, replace with copy /Y .
-CP=cp -f
-
-# The default value of RM is "rm -f."
-# If "rm.exe" is not found, uncomment:
-# RM=del
-
-LD=gcc
-LDLIBS=-L. -lz
-LDFLAGS=-s
-
-
-INCL=zlib.h zconf.h
-LIBS=libz.a
-
-AR=ar rcs
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o \
- inffast.o
-
-TEST_OBJS = minigzip.o untgz.o
-
-all: minigzip.exe untgz.exe
-
-rebuild: clean all
-
-libz.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $(LDFLAGS) -o $@ $< $(LDLIBS)
-
-.PHONY : clean
-
-clean:
- $(RM) *.d *.o *.exe libz.a foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/untgz.c b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/untgz.c
deleted file mode 100644
index 4a431ff3163..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/untgz/untgz.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * untgz.c -- Display contents and/or extract file from
- * a gzip'd TAR file
- * written by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
- * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-#ifdef unix
-# include <unistd.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "zlib.h"
-
-#ifdef WIN32
-# ifndef F_OK
-# define F_OK (0)
-# endif
-# ifdef _MSC_VER
-# define mkdir(dirname,mode) _mkdir(dirname)
-# define strdup(str) _strdup(str)
-# define unlink(fn) _unlink(fn)
-# define access(path,mode) _access(path,mode)
-# else
-# define mkdir(dirname,mode) _mkdir(dirname)
-# endif
-#else
-# include <utime.h>
-#endif
-
-
-/* Values used in typeflag field. */
-
-#define REGTYPE '0' /* regular file */
-#define AREGTYPE '\0' /* regular file */
-#define LNKTYPE '1' /* link */
-#define SYMTYPE '2' /* reserved */
-#define CHRTYPE '3' /* character special */
-#define BLKTYPE '4' /* block special */
-#define DIRTYPE '5' /* directory */
-#define FIFOTYPE '6' /* FIFO special */
-#define CONTTYPE '7' /* reserved */
-
-#define BLOCKSIZE 512
-
-struct tar_header
-{ /* byte offset */
- char name[100]; /* 0 */
- char mode[8]; /* 100 */
- char uid[8]; /* 108 */
- char gid[8]; /* 116 */
- char size[12]; /* 124 */
- char mtime[12]; /* 136 */
- char chksum[8]; /* 148 */
- char typeflag; /* 156 */
- char linkname[100]; /* 157 */
- char magic[6]; /* 257 */
- char version[2]; /* 263 */
- char uname[32]; /* 265 */
- char gname[32]; /* 297 */
- char devmajor[8]; /* 329 */
- char devminor[8]; /* 337 */
- char prefix[155]; /* 345 */
- /* 500 */
-};
-
-union tar_buffer {
- char buffer[BLOCKSIZE];
- struct tar_header header;
-};
-
-enum { TGZ_EXTRACT = 0, TGZ_LIST };
-
-static char *TGZfname OF((const char *));
-void TGZnotfound OF((const char *));
-
-int getoct OF((char *, int));
-char *strtime OF((time_t *));
-int ExprMatch OF((char *,char *));
-
-int makedir OF((char *));
-int matchname OF((int,int,char **,char *));
-
-void error OF((const char *));
-int tar OF((gzFile, int, int, int, char **));
-
-void help OF((int));
-int main OF((int, char **));
-
-char *prog;
-
-/* This will give a benign warning */
-
-static char *TGZprefix[] = { "\0", ".tgz", ".tar.gz", ".tar", NULL };
-
-/* Return the real name of the TGZ archive */
-/* or NULL if it does not exist. */
-
-static char *TGZfname OF((const char *fname))
-{
- static char buffer[1024];
- int origlen,i;
-
- strcpy(buffer,fname);
- origlen = strlen(buffer);
-
- for (i=0; TGZprefix[i]; i++)
- {
- strcpy(buffer+origlen,TGZprefix[i]);
- if (access(buffer,F_OK) == 0)
- return buffer;
- }
- return NULL;
-}
-
-/* error message for the filename */
-
-void TGZnotfound OF((const char *fname))
-{
- int i;
-
- fprintf(stderr,"%s : couldn't find ",prog);
- for (i=0;TGZprefix[i];i++)
- fprintf(stderr,(TGZprefix[i+1]) ? "%s%s, " : "or %s%s\n",
- fname,
- TGZprefix[i]);
- exit(1);
-}
-
-
-/* help functions */
-
-int getoct(char *p,int width)
-{
- int result = 0;
- char c;
-
- while (width --)
- {
- c = *p++;
- if (c == ' ')
- continue;
- if (c == 0)
- break;
- result = result * 8 + (c - '0');
- }
- return result;
-}
-
-char *strtime (time_t *t)
-{
- struct tm *local;
- static char result[32];
-
- local = localtime(t);
- sprintf(result,"%2d/%02d/%4d %02d:%02d:%02d",
- local->tm_mday, local->tm_mon+1, local->tm_year+1900,
- local->tm_hour, local->tm_min, local->tm_sec);
- return result;
-}
-
-
-/* regular expression matching */
-
-#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
-
-int ExprMatch(char *string,char *expr)
-{
- while (1)
- {
- if (ISSPECIAL(*expr))
- {
- if (*expr == '/')
- {
- if (*string != '\\' && *string != '/')
- return 0;
- string ++; expr++;
- }
- else if (*expr == '*')
- {
- if (*expr ++ == 0)
- return 1;
- while (*++string != *expr)
- if (*string == 0)
- return 0;
- }
- }
- else
- {
- if (*string != *expr)
- return 0;
- if (*expr++ == 0)
- return 1;
- string++;
- }
- }
-}
-
-/* recursive make directory */
-/* abort if you get an ENOENT errno somewhere in the middle */
-/* e.g. ignore error "mkdir on existing directory" */
-/* */
-/* return 1 if OK */
-/* 0 on error */
-
-int makedir (char *newdir)
-{
- char *buffer = strdup(newdir);
- char *p;
- int len = strlen(buffer);
-
- if (len <= 0) {
- free(buffer);
- return 0;
- }
- if (buffer[len-1] == '/') {
- buffer[len-1] = '\0';
- }
- if (mkdir(buffer, 0775) == 0)
- {
- free(buffer);
- return 1;
- }
-
- p = buffer+1;
- while (1)
- {
- char hold;
-
- while(*p && *p != '\\' && *p != '/')
- p++;
- hold = *p;
- *p = 0;
- if ((mkdir(buffer, 0775) == -1) && (errno == ENOENT))
- {
- fprintf(stderr,"%s: couldn't create directory %s\n",prog,buffer);
- free(buffer);
- return 0;
- }
- if (hold == 0)
- break;
- *p++ = hold;
- }
- free(buffer);
- return 1;
-}
-
-int matchname (int arg,int argc,char **argv,char *fname)
-{
- if (arg == argc) /* no arguments given (untgz tgzarchive) */
- return 1;
-
- while (arg < argc)
- if (ExprMatch(fname,argv[arg++]))
- return 1;
-
- return 0; /* ignore this for the moment being */
-}
-
-
-/* Tar file list or extract */
-
-int tar (gzFile in,int action,int arg,int argc,char **argv)
-{
- union tar_buffer buffer;
- int len;
- int err;
- int getheader = 1;
- int remaining = 0;
- FILE *outfile = NULL;
- char fname[BLOCKSIZE];
- time_t tartime;
-
- if (action == TGZ_LIST)
- printf(" day time size file\n"
- " ---------- -------- --------- -------------------------------------\n");
- while (1)
- {
- len = gzread(in, &buffer, BLOCKSIZE);
- if (len < 0)
- error (gzerror(in, &err));
- /*
- * Always expect complete blocks to process
- * the tar information.
- */
- if (len != BLOCKSIZE)
- error("gzread: incomplete block read");
-
- /*
- * If we have to get a tar header
- */
- if (getheader == 1)
- {
- /*
- * if we met the end of the tar
- * or the end-of-tar block,
- * we are done
- */
- if ((len == 0) || (buffer.header.name[0]== 0)) break;
-
- tartime = (time_t)getoct(buffer.header.mtime,12);
- strcpy(fname,buffer.header.name);
-
- switch (buffer.header.typeflag)
- {
- case DIRTYPE:
- if (action == TGZ_LIST)
- printf(" %s <dir> %s\n",strtime(&tartime),fname);
- if (action == TGZ_EXTRACT)
- makedir(fname);
- break;
- case REGTYPE:
- case AREGTYPE:
- remaining = getoct(buffer.header.size,12);
- if (action == TGZ_LIST)
- printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
- if (action == TGZ_EXTRACT)
- {
- if ((remaining) && (matchname(arg,argc,argv,fname)))
- {
- outfile = fopen(fname,"wb");
- if (outfile == NULL) {
- /* try creating directory */
- char *p = strrchr(fname, '/');
- if (p != NULL) {
- *p = '\0';
- makedir(fname);
- *p = '/';
- outfile = fopen(fname,"wb");
- }
- }
- fprintf(stderr,
- "%s %s\n",
- (outfile) ? "Extracting" : "Couldn't create",
- fname);
- }
- else
- outfile = NULL;
- }
- /*
- * could have no contents
- */
- getheader = (remaining) ? 0 : 1;
- break;
- default:
- if (action == TGZ_LIST)
- printf(" %s <---> %s\n",strtime(&tartime),fname);
- break;
- }
- }
- else
- {
- unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
-
- if ((action == TGZ_EXTRACT) && (outfile != NULL))
- {
- if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
- {
- fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname);
- fclose(outfile);
- unlink(fname);
- }
- }
- remaining -= bytes;
- if (remaining == 0)
- {
- getheader = 1;
- if ((action == TGZ_EXTRACT) && (outfile != NULL))
- {
-#ifdef WIN32
- HANDLE hFile;
- FILETIME ftm,ftLocal;
- SYSTEMTIME st;
- struct tm localt;
-
- fclose(outfile);
-
- localt = *localtime(&tartime);
-
- hFile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, OPEN_EXISTING, 0, NULL);
-
- st.wYear = (WORD)localt.tm_year+1900;
- st.wMonth = (WORD)localt.tm_mon;
- st.wDayOfWeek = (WORD)localt.tm_wday;
- st.wDay = (WORD)localt.tm_mday;
- st.wHour = (WORD)localt.tm_hour;
- st.wMinute = (WORD)localt.tm_min;
- st.wSecond = (WORD)localt.tm_sec;
- st.wMilliseconds = 0;
- SystemTimeToFileTime(&st,&ftLocal);
- LocalFileTimeToFileTime(&ftLocal,&ftm);
- SetFileTime(hFile,&ftm,NULL,&ftm);
- CloseHandle(hFile);
-
- outfile = NULL;
-#else
- struct utimbuf settime;
-
- settime.actime = settime.modtime = tartime;
-
- fclose(outfile);
- outfile = NULL;
- utime(fname,&settime);
-#endif
- }
- }
- }
- }
-
- if (gzclose(in) != Z_OK)
- error("failed gzclose");
-
- return 0;
-}
-
-
-/* =========================================================== */
-
-void help(int exitval)
-{
- fprintf(stderr,
- "untgz v 0.1\n"
- " an sample application of zlib 1.0.4\n\n"
- "Usage : untgz TGZfile to extract all files\n"
- " untgz TGZfile fname ... to extract selected files\n"
- " untgz -l TGZfile to list archive contents\n"
- " untgz -h to display this help\n\n");
- exit(exitval);
-}
-
-void error(const char *msg)
-{
- fprintf(stderr, "%s: %s\n", prog, msg);
- exit(1);
-}
-
-
-/* ====================================================================== */
-
-int _CRT_glob = 0; /* disable globbing of the arguments */
-
-int main(int argc,char **argv)
-{
- int action = TGZ_EXTRACT;
- int arg = 1;
- char *TGZfile;
- gzFile *f;
-
-
- prog = strrchr(argv[0],'\\');
- if (prog == NULL)
- {
- prog = strrchr(argv[0],'/');
- if (prog == NULL)
- {
- prog = strrchr(argv[0],':');
- if (prog == NULL)
- prog = argv[0];
- else
- prog++;
- }
- else
- prog++;
- }
- else
- prog++;
-
- if (argc == 1)
- help(0);
-
- if (strcmp(argv[arg],"-l") == 0)
- {
- action = TGZ_LIST;
- if (argc == ++arg)
- help(0);
- }
- else if (strcmp(argv[arg],"-h") == 0)
- {
- help(0);
- }
-
- if ((TGZfile = TGZfname(argv[arg])) == NULL)
- TGZnotfound(argv[arg]);
-
- ++arg;
- if ((action == TGZ_LIST) && (arg != argc))
- help(1);
-
-/*
- * Process the TGZ file
- */
- switch(action)
- {
- case TGZ_LIST:
- case TGZ_EXTRACT:
- f = gzopen(TGZfile,"rb");
- if (f == NULL)
- {
- fprintf(stderr,"%s: Couldn't gzopen %s\n",
- prog,
- TGZfile);
- return 1;
- }
- exit(tar(f, action, arg, argc, argv));
- break;
-
- default:
- error("Unknown option!");
- exit(1);
- }
-
- return 0;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/visual-basic.txt b/contrib/vmap_extractor_v2/stormlib/zlib/contrib/visual-basic.txt
deleted file mode 100644
index 10fb44bc593..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/contrib/visual-basic.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-See below some functions declarations for Visual Basic.
-
-Frequently Asked Question:
-
-Q: Each time I use the compress function I get the -5 error (not enough
- room in the output buffer).
-
-A: Make sure that the length of the compressed buffer is passed by
- reference ("as any"), not by value ("as long"). Also check that
- before the call of compress this length is equal to the total size of
- the compressed buffer and not zero.
-
-
-From: "Jon Caruana" <jon-net@usa.net>
-Subject: Re: How to port zlib declares to vb?
-Date: Mon, 28 Oct 1996 18:33:03 -0600
-
-Got the answer! (I haven't had time to check this but it's what I got, and
-looks correct):
-
-He has the following routines working:
- compress
- uncompress
- gzopen
- gzwrite
- gzread
- gzclose
-
-Declares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)
-
-#If Win16 Then 'Use Win16 calls.
-Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
- String, comprLen As Any, ByVal buf As String, ByVal buflen
- As Long) As Integer
-Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
- As String, uncomprLen As Any, ByVal compr As String, ByVal
- lcompr As Long) As Integer
-Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
- String, ByVal mode As String) As Long
-Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
- Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
- As Integer
-Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
- Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
- As Integer
-Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
- Long) As Integer
-#Else
-Declare Function compress Lib "ZLIB32.DLL"
- (ByVal compr As String, comprLen As Any, ByVal buf As
- String, ByVal buflen As Long) As Integer
-Declare Function uncompress Lib "ZLIB32.DLL"
- (ByVal uncompr As String, uncomprLen As Any, ByVal compr As
- String, ByVal lcompr As Long) As Long
-Declare Function gzopen Lib "ZLIB32.DLL"
- (ByVal file As String, ByVal mode As String) As Long
-Declare Function gzread Lib "ZLIB32.DLL"
- (ByVal file As Long, ByVal uncompr As String, ByVal
- uncomprLen As Long) As Long
-Declare Function gzwrite Lib "ZLIB32.DLL"
- (ByVal file As Long, ByVal uncompr As String, ByVal
- uncomprLen As Long) As Long
-Declare Function gzclose Lib "ZLIB32.DLL"
- (ByVal file As Long) As Long
-#End If
-
--Jon Caruana
-jon-net@usa.net
-Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/crc32.c b/contrib/vmap_extractor_v2/stormlib/zlib/crc32.c
deleted file mode 100644
index 60deca2ddf4..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/crc32.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-
-#define local static
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local int crc_table_empty = 1;
-local uLongf crc_table[256];
-local void make_crc_table OF((void));
-
-/*
- Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The table is simply the CRC of all possible eight bit values. This is all
- the information needed to generate CRC's on data a byte at a time for all
- combinations of CRC register values and incoming bytes.
-*/
-local void make_crc_table()
-{
- uLong c;
- int n, k;
- uLong poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* make exclusive-or pattern from polynomial (0xedb88320L) */
- poly = 0L;
- for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
- poly |= 1L << (31 - p[n]);
-
- for (n = 0; n < 256; n++)
- {
- c = (uLong)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[n] = c;
- }
- crc_table_empty = 0;
-}
-#else
-/* ========================================================================
- * Table of CRC-32's of all single-byte values (made by make_crc_table)
- */
-local const uLongf crc_table[256] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- 0x2d02ef8dL
-};
-#endif
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const uLongf * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty) make_crc_table();
-#endif
- return (const uLongf *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-
-/* ========================================================================= */
-uLong ZEXPORT crc32(crc, buf, len)
- uLong crc;
- const Bytef *buf;
- uInt len;
-{
- if (buf == Z_NULL) return 0L;
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif
- crc = crc ^ 0xffffffffL;
- while (len >= 8)
- {
- DO8(buf);
- len -= 8;
- }
- if (len) do {
- DO1(buf);
- } while (--len);
- return crc ^ 0xffffffffL;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/deflate.c b/contrib/vmap_extractor_v2/stormlib/zlib/deflate.c
deleted file mode 100644
index 16ebdade3f1..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/deflate.c
+++ /dev/null
@@ -1,1350 +0,0 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in ftp://ds.internic.net/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id$ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-local block_state deflate_slow OF((deflate_state *s, int flush));
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int noheader = 0;
- static const char* my_version = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == Z_NULL) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == Z_NULL) strm->zfree = zcfree;
-
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#ifdef FASTEST
- level = 1;
-#endif
-
- if (windowBits < 0) { /* undocumented feature: suppress zlib header */
- noheader = 1;
- windowBits = -windowBits;
- }
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->noheader = noheader;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
-
- s = strm->state;
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
- dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->noheader < 0) {
- s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
- }
- s->status = s->noheader ? BUSY_STATE : INIT_STATE;
- strm->adler = 1;
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
- if (level == Z_DEFAULT_COMPRESSION) {
- level = 6;
- }
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the zlib header */
- if (s->status == INIT_STATE) {
-
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags = (s->level-1) >> 1;
-
- if (level_flags > 3) level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = 1L;
- }
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUFF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->noheader) return Z_STREAM_END;
-
- /* Write the zlib trailer (adler32) */
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- s->noheader = -1; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE && status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- *dest = *source;
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- *ds = *ss;
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (!strm->state->noheader) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-}
-
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-#ifndef FASTEST
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#else /* FASTEST */
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 only
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return len <= s->lookahead ? len : s->lookahead;
-}
-#endif /* FASTEST */
-#endif /* ASMV */
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if strstart == 0
- * and lookahead == 1 (input done one byte at time)
- */
- more--;
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- } else if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in hash table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
- (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR))) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/deflate.h b/contrib/vmap_extractor_v2/stormlib/zlib/deflate.h
deleted file mode 100644
index b99a48a5214..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/deflate.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2002 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef _DEFLATE_H
-#define _DEFLATE_H
-
-#include "zutil.h"
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- int pending; /* nb of bytes in the pending buffer */
- int noheader; /* suppress zlib header and adler32 */
- Byte data_type; /* UNKNOWN, BINARY or ASCII */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/descrip.mms b/contrib/vmap_extractor_v2/stormlib/zlib/descrip.mms
deleted file mode 100644
index 9d364598a27..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/descrip.mms
+++ /dev/null
@@ -1,48 +0,0 @@
-# descrip.mms: MMS description file for building zlib on VMS
-# written by Martin P.J. Zinser <m.zinser@gsi.de>
-
-cc_defs =
-c_deb =
-
-.ifdef __DECC__
-pref = /prefix=all
-.endif
-
-OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
- deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
- inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
-
-CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
-
-all : example.exe minigzip.exe
- @ write sys$output " Example applications available"
-libz.olb : libz.olb($(OBJS))
- @ write sys$output " libz available"
-
-example.exe : example.obj libz.olb
- link example,libz.olb/lib
-
-minigzip.exe : minigzip.obj libz.olb
- link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
-
-clean :
- delete *.obj;*,libz.olb;*
-
-
-# Other dependencies.
-adler32.obj : zutil.h zlib.h zconf.h
-compress.obj : zlib.h zconf.h
-crc32.obj : zutil.h zlib.h zconf.h
-deflate.obj : deflate.h zutil.h zlib.h zconf.h
-example.obj : zlib.h zconf.h
-gzio.obj : zutil.h zlib.h zconf.h
-infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
-inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
-inflate.obj : zutil.h zlib.h zconf.h infblock.h
-inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
-infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
-minigzip.obj : zlib.h zconf.h
-trees.obj : deflate.h zutil.h zlib.h zconf.h
-uncompr.obj : zlib.h zconf.h
-zutil.obj : zutil.h zlib.h zconf.h
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/example.c b/contrib/vmap_extractor_v2/stormlib/zlib/example.c
deleted file mode 100644
index e7e3673333e..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/example.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include <stdio.h>
-#include "zlib.h"
-
-#ifdef STDC
-# include <string.h>
-# include <stdlib.h>
-#else
- extern void exit OF((int));
-#endif
-
-#if defined(VMS) || defined(RISCOS)
-# define TESTFILE "foo-gz"
-#else
-# define TESTFILE "foo.gz"
-#endif
-
-#define CHECK_ERR(err, msg) { \
- if (err != Z_OK) { \
- fprintf(stderr, "%s error: %d\n", msg, err); \
- exit(1); \
- } \
-}
-
-const char hello[] = "hello, hello!";
-/* "hello world" would be more standard, but the repeated "hello"
- * stresses the compression code better, sorry...
- */
-
-const char dictionary[] = "hello";
-uLong dictId; /* Adler32 value of the dictionary */
-
-void test_compress OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_gzio OF((const char *out, const char *in,
- Byte *uncompr, int uncomprLen));
-void test_deflate OF((Byte *compr, uLong comprLen));
-void test_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_large_deflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_large_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_flush OF((Byte *compr, uLong *comprLen));
-void test_sync OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_dict_deflate OF((Byte *compr, uLong comprLen));
-void test_dict_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-int main OF((int argc, char *argv[]));
-
-/* ===========================================================================
- * Test compress() and uncompress()
- */
-void test_compress(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- uLong len = strlen(hello)+1;
-
- err = compress(compr, &comprLen, (const Bytef*)hello, len);
- CHECK_ERR(err, "compress");
-
- strcpy((char*)uncompr, "garbage");
-
- err = uncompress(uncompr, &uncomprLen, compr, comprLen);
- CHECK_ERR(err, "uncompress");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad uncompress\n");
- exit(1);
- } else {
- printf("uncompress(): %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Test read/write of .gz files
- */
-void test_gzio(out, in, uncompr, uncomprLen)
- const char *out; /* compressed output file */
- const char *in; /* compressed input file */
- Byte *uncompr;
- int uncomprLen;
-{
- int err;
- int len = strlen(hello)+1;
- gzFile file;
- z_off_t pos;
-
- file = gzopen(out, "wb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- exit(1);
- }
- gzputc(file, 'h');
- if (gzputs(file, "ello") != 4) {
- fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (gzprintf(file, ", %s!", "hello") != 8) {
- fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
- exit(1);
- }
- gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
- gzclose(file);
-
- file = gzopen(in, "rb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- }
- strcpy((char*)uncompr, "garbage");
-
- uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
- if (uncomprLen != len) {
- fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
- exit(1);
- } else {
- printf("gzread(): %s\n", (char *)uncompr);
- }
-
- pos = gzseek(file, -8L, SEEK_CUR);
- if (pos != 6 || gztell(file) != pos) {
- fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
- (long)pos, (long)gztell(file));
- exit(1);
- }
-
- if (gzgetc(file) != ' ') {
- fprintf(stderr, "gzgetc error\n");
- exit(1);
- }
-
- gzgets(file, (char*)uncompr, uncomprLen);
- uncomprLen = strlen((char*)uncompr);
- if (uncomprLen != 6) { /* "hello!" */
- fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello+7)) {
- fprintf(stderr, "bad gzgets after gzseek\n");
- exit(1);
- } else {
- printf("gzgets() after gzseek: %s\n", (char *)uncompr);
- }
-
- gzclose(file);
-}
-
-/* ===========================================================================
- * Test deflate() with small buffers
- */
-void test_deflate(compr, comprLen)
- Byte *compr;
- uLong comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
- int len = strlen(hello)+1;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.next_out = compr;
-
- while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
- c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
- }
- /* Finish the stream, still forcing small buffers: */
- for (;;) {
- c_stream.avail_out = 1;
- err = deflate(&c_stream, Z_FINISH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "deflate");
- }
-
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with small buffers
- */
-void test_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = 0;
- d_stream.next_out = uncompr;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
- d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "inflate");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad inflate\n");
- exit(1);
- } else {
- printf("inflate(): %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Test deflate() with large buffers and dynamic change of compression level
- */
-void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_BEST_SPEED);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_out = compr;
- c_stream.avail_out = (uInt)comprLen;
-
- /* At this point, uncompr is still mostly zeroes, so it should compress
- * very well:
- */
- c_stream.next_in = uncompr;
- c_stream.avail_in = (uInt)uncomprLen;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
- if (c_stream.avail_in != 0) {
- fprintf(stderr, "deflate not greedy\n");
- exit(1);
- }
-
- /* Feed in already compressed data and switch to no compression: */
- deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
- c_stream.next_in = compr;
- c_stream.avail_in = (uInt)comprLen/2;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
-
- /* Switch back to compressing mode: */
- deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
- c_stream.next_in = uncompr;
- c_stream.avail_in = (uInt)uncomprLen;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with large buffers
- */
-void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = (uInt)comprLen;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- for (;;) {
- d_stream.next_out = uncompr; /* discard the output */
- d_stream.avail_out = (uInt)uncomprLen;
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "large inflate");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
- fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
- exit(1);
- } else {
- printf("large_inflate(): OK\n");
- }
-}
-
-/* ===========================================================================
- * Test deflate() with full flush
- */
-void test_flush(compr, comprLen)
- Byte *compr;
- uLong *comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
- int len = strlen(hello)+1;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.next_out = compr;
- c_stream.avail_in = 3;
- c_stream.avail_out = (uInt)*comprLen;
- err = deflate(&c_stream, Z_FULL_FLUSH);
- CHECK_ERR(err, "deflate");
-
- compr[3]++; /* force an error in first compressed block */
- c_stream.avail_in = len - 3;
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- CHECK_ERR(err, "deflate");
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-
- *comprLen = c_stream.total_out;
-}
-
-/* ===========================================================================
- * Test inflateSync()
- */
-void test_sync(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = 2; /* just read the zlib header */
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- d_stream.next_out = uncompr;
- d_stream.avail_out = (uInt)uncomprLen;
-
- inflate(&d_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "inflate");
-
- d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
- err = inflateSync(&d_stream); /* but skip the damaged part */
- CHECK_ERR(err, "inflateSync");
-
- err = inflate(&d_stream, Z_FINISH);
- if (err != Z_DATA_ERROR) {
- fprintf(stderr, "inflate should report DATA_ERROR\n");
- /* Because of incorrect adler32 */
- exit(1);
- }
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- printf("after inflateSync(): hel%s\n", (char *)uncompr);
-}
-
-/* ===========================================================================
- * Test deflate() with preset dictionary
- */
-void test_dict_deflate(compr, comprLen)
- Byte *compr;
- uLong comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- err = deflateSetDictionary(&c_stream,
- (const Bytef*)dictionary, sizeof(dictionary));
- CHECK_ERR(err, "deflateSetDictionary");
-
- dictId = c_stream.adler;
- c_stream.next_out = compr;
- c_stream.avail_out = (uInt)comprLen;
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.avail_in = (uInt)strlen(hello)+1;
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with a preset dictionary
- */
-void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = (uInt)comprLen;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- d_stream.next_out = uncompr;
- d_stream.avail_out = (uInt)uncomprLen;
-
- for (;;) {
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- if (err == Z_NEED_DICT) {
- if (d_stream.adler != dictId) {
- fprintf(stderr, "unexpected dictionary");
- exit(1);
- }
- err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
- sizeof(dictionary));
- }
- CHECK_ERR(err, "inflate with dict");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad inflate with dict\n");
- exit(1);
- } else {
- printf("inflate with dictionary: %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Usage: example [output.gz [input.gz]]
- */
-
-int main(argc, argv)
- int argc;
- char *argv[];
-{
- Byte *compr, *uncompr;
- uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
- uLong uncomprLen = comprLen;
- static const char* myVersion = ZLIB_VERSION;
-
- if (zlibVersion()[0] != myVersion[0]) {
- fprintf(stderr, "incompatible zlib version\n");
- exit(1);
-
- } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
- fprintf(stderr, "warning: different zlib version\n");
- }
-
- compr = (Byte*)calloc((uInt)comprLen, 1);
- uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
- /* compr and uncompr are cleared to avoid reading uninitialized
- * data and to ensure that uncompr compresses well.
- */
- if (compr == Z_NULL || uncompr == Z_NULL) {
- printf("out of memory\n");
- exit(1);
- }
- test_compress(compr, comprLen, uncompr, uncomprLen);
-
- test_gzio((argc > 1 ? argv[1] : TESTFILE),
- (argc > 2 ? argv[2] : TESTFILE),
- uncompr, (int)uncomprLen);
-
- test_deflate(compr, comprLen);
- test_inflate(compr, comprLen, uncompr, uncomprLen);
-
- test_large_deflate(compr, comprLen, uncompr, uncomprLen);
- test_large_inflate(compr, comprLen, uncompr, uncomprLen);
-
- test_flush(compr, &comprLen);
- test_sync(compr, comprLen, uncompr, uncomprLen);
- comprLen = uncomprLen;
-
- test_dict_deflate(compr, comprLen);
- test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
-
- exit(0);
- return 0; /* to avoid warning */
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/gzio.c b/contrib/vmap_extractor_v2/stormlib/zlib/gzio.c
deleted file mode 100644
index 09e0a20b8ce..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/gzio.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_DEFLATE to avoid the compression code.
- */
-
-/* @(#) $Id$ */
-
-#include <stdio.h>
-
-#include "zutil.h"
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- long startpos; /* start of compressed data in file (header skipped) */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open return NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->startpos = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * startpos anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->startpos = (ftell(s->file) - s->stream.avail_in);
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[20];
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "<fd:%d>", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Check the gzip magic header */
- for (len = 0; len < 2; len++) {
- c = get_byte(s);
- if (c != gz_magic[len]) {
- if (len != 0) s->stream.avail_in++, s->stream.next_in--;
- if (c != EOF) {
- s->stream.avail_in++, s->stream.next_in--;
- s->transparent = 1;
- }
- s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
- return;
- }
- }
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
- s->file);
- }
- len -= s->stream.avail_out;
- s->stream.total_in += (uLong)len;
- s->stream.total_out += (uLong)len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may
- * be different from s->stream.total_out) in case of
- * concatenated .gz files. Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- uLong total_in = s->stream.total_in;
- uLong total_out = s->stream.total_out;
-
- inflateReset(&(s->stream));
- s->stream.total_in = total_in;
- s->stream.total_out = total_out;
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- 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. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_DEFLATE
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- const voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include <stdarg.h>
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- va_start(va, format);
-#ifdef HAS_vsnprintf
- (void)vsnprintf(buf, sizeof(buf), format, va);
-#else
- (void)vsprintf(buf, format, va);
-#endif
- va_end(va);
- len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
-#ifdef HAS_snprintf
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#else
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#endif
- len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- 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.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->z_err = deflate(&(s->stream), flush);
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_DEFLATE */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->stream.total_in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return (z_off_t)s->stream.total_in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->stream.total_out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->stream.total_in = s->stream.total_out = (uLong)offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if ((uLong)offset >= s->stream.total_out) {
- offset -= s->stream.total_out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return (z_off_t)s->stream.total_out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
-
- if (s->startpos == 0) { /* not a compressed file */
- rewind(s->file);
- return 0;
- }
-
- (void) inflateReset(&s->stream);
- return fseek(s->file, s->startpos, SEEK_SET);
-}
-
-/* ===========================================================================
- 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.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- int err;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return Z_STREAM_ERROR;
-#else
- err = do_flush (file, Z_FINISH);
- if (err != Z_OK) return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, s->stream.total_in);
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-/* ===========================================================================
- Returns the error message for the last error which occured on the
- given compressed file. errnum is set to zlib error number. If an
- error occured 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.
-*/
-const char* ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infblock.c b/contrib/vmap_extractor_v2/stormlib/zlib/infblock.c
deleted file mode 100644
index dd7a6d40a8d..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/infblock.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local const uInt border[] = { /* Order of the bit length code lengths */
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
- Notes beyond the 1.93a appnote.txt:
-
- 1. Distance pointers never point before the beginning of the output
- stream.
- 2. Distance pointers can point back across blocks, up to 32k away.
- 3. There is an implied maximum of 7 bits for the bit length table and
- 15 bits for the actual data.
- 4. If only one code exists, then it is encoded using one bit. (Zero
- would be more efficient, but perhaps a little confusing.) If two
- codes exist, they are coded using one bit each (0 and 1).
- 5. There is no way of sending zero distance codes--a dummy must be
- sent if there are none. (History: a pre 2.0 version of PKZIP would
- store blocks with no distance codes, but this was discovered to be
- too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
- zero distance codes, which is sent as one code of zero bits in
- length.
- 6. There are up to 286 literal/length codes. Code 256 represents the
- end-of-block. Note however that the static length tree defines
- 288 codes just to fill out the Huffman codes. Codes 286 and 287
- cannot be used though, since there is no length base or extra bits
- defined for them. Similarily, there are up to 30 distance codes.
- However, static trees define 32 codes (all 5 bits) to fill out the
- Huffman codes, but the last two had better not show up in the data.
- 7. Unzip can check dynamic Huffman blocks for complete code sets.
- The exception is that a single code would not be complete (see #4).
- 8. The five bits following the block type is really the number of
- literal codes sent minus 257.
- 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
- (1+6+6). Therefore, to output three times the length, you output
- three codes (1+1+1), whereas to output four times the same length,
- you only need two codes (1+3). Hmm.
- 10. In the tree reconstruction algorithm, Code = Code + Increment
- only if BitLength(i) is not zero. (Pretty obvious.)
- 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
- 12. Note: length code 284 can represent 227-258, but length code 285
- really is 258. The last length deserves its own, short code
- since it gets used a lot in very redundant files. The length
- 258 is special since 258 - 3 (the min match length) is 255.
- 13. The literal/length and distance code bit lengths are read as a
- single stream of lengths. It is possible (and advantageous) for
- a repeat code (16, 17, or 18) to go across the boundary between
- the two sets of lengths.
- */
-
-
-void inflate_blocks_reset(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
- if (c != Z_NULL)
- *c = s->check;
- if (s->mode == BTREE || s->mode == DTREE)
- ZFREE(z, s->sub.trees.blens);
- if (s->mode == CODES)
- inflate_codes_free(s->sub.decode.codes, z);
- s->mode = TYPE;
- s->bitk = 0;
- s->bitb = 0;
- s->read = s->write = s->window;
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
- Tracev((stderr, "inflate: blocks reset\n"));
-}
-
-
-inflate_blocks_statef *inflate_blocks_new(z, c, w)
-z_streamp z;
-check_func c;
-uInt w;
-{
- inflate_blocks_statef *s;
-
- if ((s = (inflate_blocks_statef *)ZALLOC
- (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
- return s;
- if ((s->hufts =
- (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
- {
- ZFREE(z, s);
- return Z_NULL;
- }
- if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
- {
- ZFREE(z, s->hufts);
- ZFREE(z, s);
- return Z_NULL;
- }
- s->end = s->window + w;
- s->checkfn = c;
- s->mode = TYPE;
- Tracev((stderr, "inflate: blocks allocated\n"));
- inflate_blocks_reset(s, z, Z_NULL);
- return s;
-}
-
-
-int inflate_blocks(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt t; /* temporary storage */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input based on current state */
- while (1) switch (s->mode)
- {
- case TYPE:
- NEEDBITS(3)
- t = (uInt)b & 7;
- s->last = t & 1;
- switch (t >> 1)
- {
- case 0: /* stored */
- Tracev((stderr, "inflate: stored block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- t = k & 7; /* go to byte boundary */
- DUMPBITS(t)
- s->mode = LENS; /* get length of stored block */
- break;
- case 1: /* fixed */
- Tracev((stderr, "inflate: fixed codes block%s\n",
- s->last ? " (last)" : ""));
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
-
- inflate_trees_fixed(&bl, &bd, &tl, &td, z);
- s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
- if (s->sub.decode.codes == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- }
- DUMPBITS(3)
- s->mode = CODES;
- break;
- case 2: /* dynamic */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- s->mode = TABLE;
- break;
- case 3: /* illegal */
- DUMPBITS(3)
- s->mode = BAD;
- z->msg = (char*)"invalid block type";
- r = Z_DATA_ERROR;
- LEAVE
- }
- break;
- case LENS:
- NEEDBITS(32)
- if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
- {
- s->mode = BAD;
- z->msg = (char*)"invalid stored block lengths";
- r = Z_DATA_ERROR;
- LEAVE
- }
- s->sub.left = (uInt)b & 0xffff;
- b = k = 0; /* dump bits */
- Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
- s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
- break;
- case STORED:
- if (n == 0)
- LEAVE
- NEEDOUT
- t = s->sub.left;
- if (t > n) t = n;
- if (t > m) t = m;
- zmemcpy(q, p, t);
- p += t; n -= t;
- q += t; m -= t;
- if ((s->sub.left -= t) != 0)
- break;
- Tracev((stderr, "inflate: stored end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- s->mode = s->last ? DRY : TYPE;
- break;
- case TABLE:
- NEEDBITS(14)
- s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
- if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
- {
- s->mode = BAD;
- z->msg = (char*)"too many length or distance symbols";
- r = Z_DATA_ERROR;
- LEAVE
- }
-#endif
- t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- DUMPBITS(14)
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: table sizes ok\n"));
- s->mode = BTREE;
- case BTREE:
- while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
- {
- NEEDBITS(3)
- s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
- DUMPBITS(3)
- }
- while (s->sub.trees.index < 19)
- s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
- s->sub.trees.bb = 7;
- t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
- &s->sub.trees.tb, s->hufts, z);
- if (t != Z_OK)
- {
- r = t;
- if (r == Z_DATA_ERROR)
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- }
- LEAVE
- }
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: bits tree ok\n"));
- s->mode = DTREE;
- case DTREE:
- while (t = s->sub.trees.table,
- s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
- {
- inflate_huft *h;
- uInt i, j, c;
-
- t = s->sub.trees.bb;
- NEEDBITS(t)
- h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
- t = h->bits;
- c = h->base;
- if (c < 16)
- {
- DUMPBITS(t)
- s->sub.trees.blens[s->sub.trees.index++] = c;
- }
- else /* c == 16..18 */
- {
- i = c == 18 ? 7 : c - 14;
- j = c == 18 ? 11 : 3;
- NEEDBITS(t + i)
- DUMPBITS(t)
- j += (uInt)b & inflate_mask[i];
- DUMPBITS(i)
- i = s->sub.trees.index;
- t = s->sub.trees.table;
- if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
- (c == 16 && i < 1))
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- z->msg = (char*)"invalid bit length repeat";
- r = Z_DATA_ERROR;
- LEAVE
- }
- c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
- do {
- s->sub.trees.blens[i++] = c;
- } while (--j);
- s->sub.trees.index = i;
- }
- }
- s->sub.trees.tb = Z_NULL;
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
- inflate_codes_statef *c;
-
- bl = 9; /* must be <= 9 for lookahead assumptions */
- bd = 6; /* must be <= 9 for lookahead assumptions */
- t = s->sub.trees.table;
- t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
- s->sub.trees.blens, &bl, &bd, &tl, &td,
- s->hufts, z);
- if (t != Z_OK)
- {
- if (t == (uInt)Z_DATA_ERROR)
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- }
- r = t;
- LEAVE
- }
- Tracev((stderr, "inflate: trees ok\n"));
- if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.decode.codes = c;
- }
- ZFREE(z, s->sub.trees.blens);
- s->mode = CODES;
- case CODES:
- UPDATE
- if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
- return inflate_flush(s, z, r);
- r = Z_OK;
- inflate_codes_free(s->sub.decode.codes, z);
- LOAD
- Tracev((stderr, "inflate: codes end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- if (!s->last)
- {
- s->mode = TYPE;
- break;
- }
- s->mode = DRY;
- case DRY:
- FLUSH
- if (s->read != s->write)
- LEAVE
- s->mode = DONE;
- case DONE:
- r = Z_STREAM_END;
- LEAVE
- case BAD:
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-int inflate_blocks_free(s, z)
-inflate_blocks_statef *s;
-z_streamp z;
-{
- inflate_blocks_reset(s, z, Z_NULL);
- ZFREE(z, s->window);
- ZFREE(z, s->hufts);
- ZFREE(z, s);
- Tracev((stderr, "inflate: blocks freed\n"));
- return Z_OK;
-}
-
-
-void inflate_set_dictionary(s, d, n)
-inflate_blocks_statef *s;
-const Bytef *d;
-uInt n;
-{
- zmemcpy(s->window, d, n);
- s->read = s->write = s->window + n;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
- * IN assertion: s != Z_NULL
- */
-int inflate_blocks_sync_point(s)
-inflate_blocks_statef *s;
-{
- return s->mode == LENS;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infblock.h b/contrib/vmap_extractor_v2/stormlib/zlib/infblock.h
deleted file mode 100644
index 173b2267ade..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/infblock.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-extern inflate_blocks_statef * inflate_blocks_new OF((
- z_streamp z,
- check_func c, /* check function */
- uInt w)); /* window size */
-
-extern int inflate_blocks OF((
- inflate_blocks_statef *,
- z_streamp ,
- int)); /* initial return code */
-
-extern void inflate_blocks_reset OF((
- inflate_blocks_statef *,
- z_streamp ,
- uLongf *)); /* check value on output */
-
-extern int inflate_blocks_free OF((
- inflate_blocks_statef *,
- z_streamp));
-
-extern void inflate_set_dictionary OF((
- inflate_blocks_statef *s,
- const Bytef *d, /* dictionary */
- uInt n)); /* dictionary length */
-
-extern int inflate_blocks_sync_point OF((
- inflate_blocks_statef *s));
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.c b/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.c
deleted file mode 100644
index 9abe5412b9c..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- START, /* x: set up for LEN */
- LEN, /* i: get length/literal/eob next */
- LENEXT, /* i: getting length extra (have base) */
- DIST, /* i: get distance next */
- DISTEXT, /* i: getting distance extra */
- COPY, /* o: copying bytes in window, waiting for space */
- LIT, /* o: got literal, waiting for output space */
- WASH, /* o: got eob, possibly still output waiting */
- END, /* x: got eob and all data flushed */
- BADCODE} /* x: got error */
-inflate_codes_mode;
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
- /* mode */
- inflate_codes_mode mode; /* current inflate_codes mode */
-
- /* mode dependent information */
- uInt len;
- union {
- struct {
- inflate_huft *tree; /* pointer into tree */
- uInt need; /* bits needed */
- } code; /* if LEN or DIST, where in tree */
- uInt lit; /* if LIT, literal */
- struct {
- uInt get; /* bits to get for extra */
- uInt dist; /* distance back to copy from */
- } copy; /* if EXT or COPY, where and how much */
- } sub; /* submode */
-
- /* mode independent information */
- Byte lbits; /* ltree bits decoded per branch */
- Byte dbits; /* dtree bits decoder per branch */
- inflate_huft *ltree; /* literal/length/eob tree */
- inflate_huft *dtree; /* distance tree */
-
-};
-
-
-inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-z_streamp z;
-{
- inflate_codes_statef *c;
-
- if ((c = (inflate_codes_statef *)
- ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
- {
- c->mode = START;
- c->lbits = (Byte)bl;
- c->dbits = (Byte)bd;
- c->ltree = tl;
- c->dtree = td;
- Tracev((stderr, "inflate: codes new\n"));
- }
- return c;
-}
-
-
-int inflate_codes(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt j; /* temporary storage */
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- Bytef *f; /* pointer to copy strings from */
- inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input and output based on current state */
- while (1) switch (c->mode)
- { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- case START: /* x: set up for LEN */
-#ifndef SLOW
- if (m >= 258 && n >= 10)
- {
- UPDATE
- r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
- LOAD
- if (r != Z_OK)
- {
- c->mode = r == Z_STREAM_END ? WASH : BADCODE;
- break;
- }
- }
-#endif /* !SLOW */
- c->sub.code.need = c->lbits;
- c->sub.code.tree = c->ltree;
- c->mode = LEN;
- case LEN: /* i: get length/literal/eob next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e == 0) /* literal */
- {
- c->sub.lit = t->base;
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", t->base));
- c->mode = LIT;
- break;
- }
- if (e & 16) /* length */
- {
- c->sub.copy.get = e & 15;
- c->len = t->base;
- c->mode = LENEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t + t->base;
- break;
- }
- if (e & 32) /* end of block */
- {
- Tracevv((stderr, "inflate: end of block\n"));
- c->mode = WASH;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = (char*)"invalid literal/length code";
- r = Z_DATA_ERROR;
- LEAVE
- case LENEXT: /* i: getting length extra (have base) */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->len += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- c->sub.code.need = c->dbits;
- c->sub.code.tree = c->dtree;
- Tracevv((stderr, "inflate: length %u\n", c->len));
- c->mode = DIST;
- case DIST: /* i: get distance next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e & 16) /* distance */
- {
- c->sub.copy.get = e & 15;
- c->sub.copy.dist = t->base;
- c->mode = DISTEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t + t->base;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = (char*)"invalid distance code";
- r = Z_DATA_ERROR;
- LEAVE
- case DISTEXT: /* i: getting distance extra */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->sub.copy.dist += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
- c->mode = COPY;
- case COPY: /* o: copying bytes in window, waiting for space */
- f = q - c->sub.copy.dist;
- while (f < s->window) /* modulo window size-"while" instead */
- f += s->end - s->window; /* of "if" handles invalid distances */
- while (c->len)
- {
- NEEDOUT
- OUTBYTE(*f++)
- if (f == s->end)
- f = s->window;
- c->len--;
- }
- c->mode = START;
- break;
- case LIT: /* o: got literal, waiting for output space */
- NEEDOUT
- OUTBYTE(c->sub.lit)
- c->mode = START;
- break;
- case WASH: /* o: got eob, possibly more output */
- if (k > 7) /* return unused byte, if any */
- {
- Assert(k < 16, "inflate_codes grabbed too many bytes")
- k -= 8;
- n++;
- p--; /* can always return one */
- }
- FLUSH
- if (s->read != s->write)
- LEAVE
- c->mode = END;
- case END:
- r = Z_STREAM_END;
- LEAVE
- case BADCODE: /* x: got error */
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-#ifdef NEED_DUMMY_RETURN
- return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-#endif
-}
-
-
-void inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_streamp z;
-{
- ZFREE(z, c);
- Tracev((stderr, "inflate: codes free\n"));
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.h b/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.h
deleted file mode 100644
index 46821a02be6..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/infcodes.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-extern inflate_codes_statef *inflate_codes_new OF((
- uInt, uInt,
- inflate_huft *, inflate_huft *,
- z_streamp ));
-
-extern int inflate_codes OF((
- inflate_blocks_statef *,
- z_streamp ,
- int));
-
-extern void inflate_codes_free OF((
- inflate_codes_statef *,
- z_streamp ));
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inffast.c b/contrib/vmap_extractor_v2/stormlib/zlib/inffast.c
deleted file mode 100644
index aa7f1d4d2ad..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/inffast.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
-
-/* Called with number of bytes left to write in window at least 258
- (the maximum string length) and number of input bytes available
- at least ten. The ten bytes are six bytes for the longest length/
- distance pair plus four bytes for overloading the bit buffer. */
-
-int inflate_fast(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-inflate_blocks_statef *s;
-z_streamp z;
-{
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- uInt ml; /* mask for literal/length tree */
- uInt md; /* mask for distance tree */
- uInt c; /* bytes to copy */
- uInt d; /* distance back to copy from */
- Bytef *r; /* copy source pointer */
-
- /* load input, output, bit values */
- LOAD
-
- /* initialize masks */
- ml = inflate_mask[bl];
- md = inflate_mask[bd];
-
- /* do until not enough input or output space for fast loop */
- do { /* assume called with m >= 258 && n >= 10 */
- /* get literal/length code */
- GRABBITS(20) /* max bits for literal/length code */
- if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- continue;
- }
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits for length */
- e &= 15;
- c = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * length %u\n", c));
-
- /* decode distance base of block to copy */
- GRABBITS(15); /* max bits for distance code */
- e = (t = td + ((uInt)b & md))->exop;
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits to add to distance base */
- e &= 15;
- GRABBITS(e) /* get extra bits (up to 13) */
- d = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * distance %u\n", d));
-
- /* do the copy */
- m -= c;
- r = q - d;
- if (r < s->window) /* wrap if needed */
- {
- do {
- r += s->end - s->window; /* force pointer in window */
- } while (r < s->window); /* covers invalid distances */
- e = s->end - r;
- if (c > e)
- {
- c -= e; /* wrapped copy */
- do {
- *q++ = *r++;
- } while (--e);
- r = s->window;
- do {
- *q++ = *r++;
- } while (--c);
- }
- else /* normal copy */
- {
- *q++ = *r++; c--;
- *q++ = *r++; c--;
- do {
- *q++ = *r++;
- } while (--c);
- }
- }
- else /* normal copy */
- {
- *q++ = *r++; c--;
- *q++ = *r++; c--;
- do {
- *q++ = *r++;
- } while (--c);
- }
- break;
- }
- else if ((e & 64) == 0)
- {
- t += t->base;
- e = (t += ((uInt)b & inflate_mask[e]))->exop;
- }
- else
- {
- z->msg = (char*)"invalid distance code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- break;
- }
- if ((e & 64) == 0)
- {
- t += t->base;
- if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- break;
- }
- }
- else if (e & 32)
- {
- Tracevv((stderr, "inflate: * end of block\n"));
- UNGRAB
- UPDATE
- return Z_STREAM_END;
- }
- else
- {
- z->msg = (char*)"invalid literal/length code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- } while (m >= 258 && n >= 10);
-
- /* not enough input or output--restore pointers and return */
- UNGRAB
- UPDATE
- return Z_OK;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inffast.h b/contrib/vmap_extractor_v2/stormlib/zlib/inffast.h
deleted file mode 100644
index a31a4bbb058..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/inffast.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-extern int inflate_fast OF((
- uInt,
- uInt,
- inflate_huft *,
- inflate_huft *,
- inflate_blocks_statef *,
- z_streamp ));
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inffixed.h b/contrib/vmap_extractor_v2/stormlib/zlib/inffixed.h
deleted file mode 100644
index 77f7e763145..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/inffixed.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* inffixed.h -- table for decoding fixed codes
- * Generated automatically by the maketree.c program
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-local uInt fixed_bl = 9;
-local uInt fixed_bd = 5;
-local inflate_huft fixed_tl[] = {
- {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
- {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
- {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
- {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
- {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
- {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
- {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
- {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
- {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
- {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
- {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
- {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
- {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
- {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
- {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
- {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
- {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
- {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
- {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
- {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
- {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
- {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
- {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
- {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
- {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
- {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
- {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
- {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
- {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
- {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
- {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
- {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
- {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
- {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
- {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
- {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
- {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
- {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
- {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
- {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
- {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
- {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
- {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
- {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
- {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
- {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
- {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
- {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
- {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
- {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
- {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
- {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
- {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
- {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
- {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
- {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
- {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
- {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
- {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
- {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
- {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
- {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
- {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
- {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
- {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
- {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
- {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
- {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
- {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
- {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
- {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
- {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
- {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
- {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
- {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
- {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
- {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
- {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
- {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
- {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
- {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
- {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
- {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
- {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
- {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
- {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
- {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
- {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
- {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
- {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
- {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
- {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
- {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
- {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
- {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
- {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
- {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
- {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
- {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
- {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
- {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
- {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
- {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
- {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
- {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
- {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
- {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
- {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
- {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
- {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
- {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
- {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
- {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
- {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
- {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
- {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
- {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
- {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
- {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
- {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
- {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
- {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
- {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
- {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
- };
-local inflate_huft fixed_td[] = {
- {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
- {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
- {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
- {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
- {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
- {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
- {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
- {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
- };
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inflate.c b/contrib/vmap_extractor_v2/stormlib/zlib/inflate.c
deleted file mode 100644
index dfb2e867d81..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/inflate.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-
-struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
-
-typedef enum {
- METHOD, /* waiting for method byte */
- FLAG, /* waiting for flag byte */
- DICT4, /* four dictionary check bytes to go */
- DICT3, /* three dictionary check bytes to go */
- DICT2, /* two dictionary check bytes to go */
- DICT1, /* one dictionary check byte to go */
- DICT0, /* waiting for inflateSetDictionary */
- BLOCKS, /* decompressing blocks */
- CHECK4, /* four check bytes to go */
- CHECK3, /* three check bytes to go */
- CHECK2, /* two check bytes to go */
- CHECK1, /* one check byte to go */
- DONE, /* finished check, done */
- BAD} /* got an error--stay here */
-inflate_mode;
-
-/* inflate private state */
-struct internal_state {
-
- /* mode */
- inflate_mode mode; /* current inflate mode */
-
- /* mode dependent information */
- union {
- uInt method; /* if FLAGS, method byte */
- struct {
- uLong was; /* computed check value */
- uLong need; /* stream check value */
- } check; /* if CHECK, check values to compare */
- uInt marker; /* if BAD, inflateSync's marker bytes count */
- } sub; /* submode */
-
- /* mode independent information */
- int nowrap; /* flag for no wrapper */
- uInt wbits; /* log2(window size) (8..15, defaults to 15) */
- inflate_blocks_statef
- *blocks; /* current inflate_blocks state */
-
-};
-
-
-int ZEXPORT inflateReset(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- z->total_in = z->total_out = 0;
- z->msg = Z_NULL;
- z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
- inflate_blocks_reset(z->state->blocks, z, Z_NULL);
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-
-int ZEXPORT inflateEnd(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->blocks != Z_NULL)
- inflate_blocks_free(z->state->blocks, z);
- ZFREE(z, z->state);
- z->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-
-int ZEXPORT inflateInit2_(z, w, version, stream_size)
-z_streamp z;
-int w;
-const char *version;
-int stream_size;
-{
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != sizeof(z_stream))
- return Z_VERSION_ERROR;
-
- /* initialize state */
- if (z == Z_NULL)
- return Z_STREAM_ERROR;
- z->msg = Z_NULL;
- if (z->zalloc == Z_NULL)
- {
- z->zalloc = zcalloc;
- z->opaque = (voidpf)0;
- }
- if (z->zfree == Z_NULL) z->zfree = zcfree;
- if ((z->state = (struct internal_state FAR *)
- ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
- return Z_MEM_ERROR;
- z->state->blocks = Z_NULL;
-
- /* handle undocumented nowrap option (no zlib header or check) */
- z->state->nowrap = 0;
- if (w < 0)
- {
- w = - w;
- z->state->nowrap = 1;
- }
-
- /* set window size */
- if (w < 8 || w > 15)
- {
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- z->state->wbits = (uInt)w;
-
- /* create inflate_blocks state */
- if ((z->state->blocks =
- inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
- == Z_NULL)
- {
- inflateEnd(z);
- return Z_MEM_ERROR;
- }
- Tracev((stderr, "inflate: allocated\n"));
-
- /* reset state */
- inflateReset(z);
- return Z_OK;
-}
-
-
-int ZEXPORT inflateInit_(z, version, stream_size)
-z_streamp z;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(z, DEF_WBITS, version, stream_size);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int ZEXPORT inflate(z, f)
-z_streamp z;
-int f;
-{
- int r;
- uInt b;
-
- if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
- return Z_STREAM_ERROR;
- f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
- r = Z_BUF_ERROR;
- while (1) switch (z->state->mode)
- {
- case METHOD:
- NEEDBYTE
- if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
- {
- z->state->mode = BAD;
- z->msg = (char*)"unknown compression method";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
- {
- z->state->mode = BAD;
- z->msg = (char*)"invalid window size";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- z->state->mode = FLAG;
- case FLAG:
- NEEDBYTE
- b = NEXTBYTE;
- if (((z->state->sub.method << 8) + b) % 31)
- {
- z->state->mode = BAD;
- z->msg = (char*)"incorrect header check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Tracev((stderr, "inflate: zlib header ok\n"));
- if (!(b & PRESET_DICT))
- {
- z->state->mode = BLOCKS;
- break;
- }
- z->state->mode = DICT4;
- case DICT4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = DICT3;
- case DICT3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = DICT2;
- case DICT2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = DICT1;
- case DICT1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
- z->adler = z->state->sub.check.need;
- z->state->mode = DICT0;
- return Z_NEED_DICT;
- case DICT0:
- z->state->mode = BAD;
- z->msg = (char*)"need dictionary";
- z->state->sub.marker = 0; /* can try inflateSync */
- return Z_STREAM_ERROR;
- case BLOCKS:
- r = inflate_blocks(z->state->blocks, z, r);
- if (r == Z_DATA_ERROR)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- break;
- }
- if (r == Z_OK)
- r = f;
- if (r != Z_STREAM_END)
- return r;
- r = f;
- inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
- if (z->state->nowrap)
- {
- z->state->mode = DONE;
- break;
- }
- z->state->mode = CHECK4;
- case CHECK4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = CHECK3;
- case CHECK3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = CHECK2;
- case CHECK2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = CHECK1;
- case CHECK1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
-
- if (z->state->sub.check.was != z->state->sub.check.need)
- {
- z->state->mode = BAD;
- z->msg = (char*)"incorrect data check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Tracev((stderr, "inflate: zlib check ok\n"));
- z->state->mode = DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
-#ifdef NEED_DUMMY_RETURN
- return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-#endif
-}
-
-
-int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
-z_streamp z;
-const Bytef *dictionary;
-uInt dictLength;
-{
- uInt length = dictLength;
-
- if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
- return Z_STREAM_ERROR;
-
- if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
- z->adler = 1L;
-
- if (length >= ((uInt)1<<z->state->wbits))
- {
- length = (1<<z->state->wbits)-1;
- dictionary += dictLength - length;
- }
- inflate_set_dictionary(z->state->blocks, dictionary, length);
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-
-int ZEXPORT inflateSync(z)
-z_streamp z;
-{
- uInt n; /* number of bytes to look at */
- Bytef *p; /* pointer to bytes */
- uInt m; /* number of marker bytes found in a row */
- uLong r, w; /* temporaries to save total_in and total_out */
-
- /* set up */
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->mode != BAD)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0;
- }
- if ((n = z->avail_in) == 0)
- return Z_BUF_ERROR;
- p = z->next_in;
- m = z->state->sub.marker;
-
- /* search */
- while (n && m < 4)
- {
- static const Byte mark[4] = {0, 0, 0xff, 0xff};
- if (*p == mark[m])
- m++;
- else if (*p)
- m = 0;
- else
- m = 4 - m;
- p++, n--;
- }
-
- /* restore */
- z->total_in += p - z->next_in;
- z->next_in = p;
- z->avail_in = n;
- z->state->sub.marker = m;
-
- /* return no joy or set up to restart on a new block */
- if (m != 4)
- return Z_DATA_ERROR;
- r = z->total_in; w = z->total_out;
- inflateReset(z);
- z->total_in = r; z->total_out = w;
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
- * but removes the length bytes of the resulting empty stored block. When
- * decompressing, PPP checks that at the end of input packet, inflate is
- * waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
- return Z_STREAM_ERROR;
- return inflate_blocks_sync_point(z->state->blocks);
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.c b/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.c
deleted file mode 100644
index 4c32ca30d99..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#if !defined(BUILDFIXED) && !defined(STDC)
-# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
-#endif
-
-const char inflate_copyright[] =
- " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
- uIntf *, /* code lengths in bits */
- uInt, /* number of codes */
- uInt, /* number of "simple" codes */
- const uIntf *, /* list of base values for non-simple codes */
- const uIntf *, /* list of extra bits for non-simple codes */
- inflate_huft * FAR*,/* result: starting table */
- uIntf *, /* maximum lookup bits (returns actual) */
- inflate_huft *, /* space for trees */
- uInt *, /* hufts used in space */
- uIntf * )); /* space for values */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- /* see note #13 above about 258 */
-local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
-local const uInt cpdext[30] = { /* Extra bits for distance codes */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
-/*
- Huffman code decoding is performed using a multi-level table lookup.
- The fastest way to decode is to simply build a lookup table whose
- size is determined by the longest code. However, the time it takes
- to build this table can also be a factor if the data being decoded
- is not very long. The most common codes are necessarily the
- shortest codes, so those codes dominate the decoding time, and hence
- the speed. The idea is you can have a shorter table that decodes the
- shorter, more probable codes, and then point to subsidiary tables for
- the longer codes. The time it costs to decode the longer codes is
- then traded against the time it takes to make longer tables.
-
- This results of this trade are in the variables lbits and dbits
- below. lbits is the number of bits the first level table for literal/
- length codes can decode in one step, and dbits is the same thing for
- the distance codes. Subsequent tables are also less than or equal to
- those sizes. These values may be adjusted either when all of the
- codes are shorter than that, in which case the longest code length in
- bits is used, or when the shortest code is *longer* than the requested
- table size, in which case the length of the shortest code in bits is
- used.
-
- There are two different values for the two tables, since they code a
- different number of possibilities each. The literal/length table
- codes 286 possible values, or in a flat code, a little over eight
- bits. The distance table codes 30 possible values, or a little less
- than five bits, flat. The optimum values for speed end up being
- about one bit more than those, so lbits is 8+1 and dbits is 5+1.
- The optimum values may differ though from machine to machine, and
- possibly even between compilers. Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15 /* maximum bit length of any code */
-
-local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
-uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-uInt n; /* number of codes (assumed <= 288) */
-uInt s; /* number of simple-valued codes (0..s-1) */
-const uIntf *d; /* list of base values for non-simple codes */
-const uIntf *e; /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t; /* result: starting table */
-uIntf *m; /* maximum lookup bits, returns actual */
-inflate_huft *hp; /* space for trees */
-uInt *hn; /* hufts used in space */
-uIntf *v; /* working area: values in order of bit length */
-/* Given a list of code lengths and a maximum table size, make a set of
- tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
- if the given code set is incomplete (the tables are still built in this
- case), or Z_DATA_ERROR if the input is invalid. */
-{
-
- uInt a; /* counter for codes of length k */
- uInt c[BMAX+1]; /* bit length count table */
- uInt f; /* i repeats in table every f entries */
- int g; /* maximum code length */
- int h; /* table level */
- register uInt i; /* counter, current code */
- register uInt j; /* counter */
- register int k; /* number of bits in current code */
- int l; /* bits per table (returned in m) */
- uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
- register uIntf *p; /* pointer into c[], b[], or v[] */
- inflate_huft *q; /* points to current table */
- struct inflate_huft_s r; /* table entry for structure assignment */
- inflate_huft *u[BMAX]; /* table stack */
- register int w; /* bits before this table == (l * h) */
- uInt x[BMAX+1]; /* bit offsets, then code stack */
- uIntf *xp; /* pointer into x */
- int y; /* number of dummy codes added */
- uInt z; /* number of entries in current table */
-
-
- /* Generate counts for each bit length */
- p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
- C4 /* clear c[]--assume BMAX+1 is 16 */
- p = b; i = n;
- do {
- c[*p++]++; /* assume all entries <= BMAX */
- } while (--i);
- if (c[0] == n) /* null input--all zero length codes */
- {
- *t = (inflate_huft *)Z_NULL;
- *m = 0;
- return Z_OK;
- }
-
-
- /* Find minimum and maximum length, bound *m by those */
- l = *m;
- for (j = 1; j <= BMAX; j++)
- if (c[j])
- break;
- k = j; /* minimum code length */
- if ((uInt)l < j)
- l = j;
- for (i = BMAX; i; i--)
- if (c[i])
- break;
- g = i; /* maximum code length */
- if ((uInt)l > i)
- l = i;
- *m = l;
-
-
- /* Adjust last length count to fill out codes, if needed */
- for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
- return Z_DATA_ERROR;
- if ((y -= c[i]) < 0)
- return Z_DATA_ERROR;
- c[i] += y;
-
-
- /* Generate starting offsets into the value table for each length */
- x[1] = j = 0;
- p = c + 1; xp = x + 2;
- while (--i) { /* note that i == g from above */
- *xp++ = (j += *p++);
- }
-
-
- /* Make a table of values in order of bit lengths */
- p = b; i = 0;
- do {
- if ((j = *p++) != 0)
- v[x[j]++] = i;
- } while (++i < n);
- n = x[g]; /* set n to length of v */
-
-
- /* Generate the Huffman codes and for each, make the table entries */
- x[0] = i = 0; /* first Huffman code is zero */
- p = v; /* grab values in bit order */
- h = -1; /* no tables yet--level -1 */
- w = -l; /* bits decoded == (l * h) */
- u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
- q = (inflate_huft *)Z_NULL; /* ditto */
- z = 0; /* ditto */
-
- /* go through the bit lengths (k already is bits in shortest code) */
- for (; k <= g; k++)
- {
- a = c[k];
- while (a--)
- {
- /* here i is the Huffman code of length k bits for value *p */
- /* make tables up to required level */
- while (k > w + l)
- {
- h++;
- w += l; /* previous table always l bits */
-
- /* compute minimum size table less than or equal to l bits */
- z = g - w;
- z = z > (uInt)l ? l : z; /* table size upper limit */
- if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
- { /* too few codes for k-w bit table */
- f -= a + 1; /* deduct codes from patterns left */
- xp = c + k;
- if (j < z)
- while (++j < z) /* try smaller tables up to z bits */
- {
- if ((f <<= 1) <= *++xp)
- break; /* enough codes to use up j bits */
- f -= *xp; /* else deduct codes from patterns */
- }
- }
- z = 1 << j; /* table entries for j-bit table */
-
- /* allocate new table */
- if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
- return Z_DATA_ERROR; /* overflow of MANY */
- u[h] = q = hp + *hn;
- *hn += z;
-
- /* connect to last table, if there is one */
- if (h)
- {
- x[h] = i; /* save pattern for backing up */
- r.bits = (Byte)l; /* bits to dump before this table */
- r.exop = (Byte)j; /* bits in this table */
- j = i >> (w - l);
- r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
- u[h-1][j] = r; /* connect to last table */
- }
- else
- *t = q; /* first table is returned result */
- }
-
- /* set up table entry in r */
- r.bits = (Byte)(k - w);
- if (p >= v + n)
- r.exop = 128 + 64; /* out of values--invalid code */
- else if (*p < s)
- {
- r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
- r.base = *p++; /* simple code is just the value */
- }
- else
- {
- r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
- r.base = d[*p++ - s];
- }
-
- /* fill code-like entries with r */
- f = 1 << (k - w);
- for (j = i >> w; j < z; j += f)
- q[j] = r;
-
- /* backwards increment the k-bit code i */
- for (j = 1 << (k - 1); i & j; j >>= 1)
- i ^= j;
- i ^= j;
-
- /* backup over finished tables */
- mask = (1 << w) - 1; /* needed on HP, cc -O bug */
- while ((i & mask) != x[h])
- {
- h--; /* don't need to update q */
- w -= l;
- mask = (1 << w) - 1;
- }
- }
- }
-
-
- /* Return Z_BUF_ERROR if we were given an incomplete table */
- return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-int inflate_trees_bits(c, bb, tb, hp, z)
-uIntf *c; /* 19 code lengths */
-uIntf *bb; /* bits tree desired/actual depth */
-inflate_huft * FAR *tb; /* bits tree result */
-inflate_huft *hp; /* space for trees */
-z_streamp z; /* for messages */
-{
- int r;
- uInt hn = 0; /* hufts used in space */
- uIntf *v; /* work area for huft_build */
-
- if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
- r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
- tb, bb, hp, &hn, v);
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed dynamic bit lengths tree";
- else if (r == Z_BUF_ERROR || *bb == 0)
- {
- z->msg = (char*)"incomplete dynamic bit lengths tree";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
-}
-
-
-int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
-uInt nl; /* number of literal/length codes */
-uInt nd; /* number of distance codes */
-uIntf *c; /* that many (total) code lengths */
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-inflate_huft *hp; /* space for trees */
-z_streamp z; /* for messages */
-{
- int r;
- uInt hn = 0; /* hufts used in space */
- uIntf *v; /* work area for huft_build */
-
- /* allocate work area */
- if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
-
- /* build literal/length tree */
- r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
- if (r != Z_OK || *bl == 0)
- {
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed literal/length tree";
- else if (r != Z_MEM_ERROR)
- {
- z->msg = (char*)"incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
- }
-
- /* build distance tree */
- r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
- if (r != Z_OK || (*bd == 0 && nl > 257))
- {
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed distance tree";
- else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
- r = Z_OK;
- }
-#else
- z->msg = (char*)"incomplete distance tree";
- r = Z_DATA_ERROR;
- }
- else if (r != Z_MEM_ERROR)
- {
- z->msg = (char*)"empty distance tree with lengths";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
-#endif
- }
-
- /* done */
- ZFREE(z, v);
- return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-#ifdef BUILDFIXED
-local int fixed_built = 0;
-#define FIXEDH 544 /* number of hufts used by fixed tables */
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-#else
-#include "inffixed.h"
-#endif
-
-
-int inflate_trees_fixed(bl, bd, tl, td, z)
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-z_streamp z; /* for memory allocation */
-{
-#ifdef BUILDFIXED
- /* build fixed tables if not already */
- if (!fixed_built)
- {
- int k; /* temporary variable */
- uInt f = 0; /* number of hufts used in fixed_mem */
- uIntf *c; /* length list for huft_build */
- uIntf *v; /* work area for huft_build */
-
- /* allocate memory */
- if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
- if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- {
- ZFREE(z, c);
- return Z_MEM_ERROR;
- }
-
- /* literal table */
- for (k = 0; k < 144; k++)
- c[k] = 8;
- for (; k < 256; k++)
- c[k] = 9;
- for (; k < 280; k++)
- c[k] = 7;
- for (; k < 288; k++)
- c[k] = 8;
- fixed_bl = 9;
- huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
- fixed_mem, &f, v);
-
- /* distance table */
- for (k = 0; k < 30; k++)
- c[k] = 5;
- fixed_bd = 5;
- huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
- fixed_mem, &f, v);
-
- /* done */
- ZFREE(z, v);
- ZFREE(z, c);
- fixed_built = 1;
- }
-#endif
- *bl = fixed_bl;
- *bd = fixed_bd;
- *tl = fixed_tl;
- *td = fixed_td;
- return Z_OK;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.h b/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.h
deleted file mode 100644
index 04b73b7296a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/inftrees.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
- that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
- union {
- struct {
- Byte Exop; /* number of extra bits or operation */
- Byte Bits; /* number of bits in this code or subcode */
- } what;
- uInt pad; /* pad structure to a power of 2 (4 bytes for */
- } word; /* 16-bit, 8 bytes for 32-bit int's) */
- uInt base; /* literal, length base, distance base,
- or table offset */
-};
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1004 huft structures (850 for length/literals
- and 154 for distances, the latter actually the result of an
- exhaustive search). The actual maximum is not known, but the
- value below is more than safe. */
-#define MANY 1440
-
-extern int inflate_trees_bits OF((
- uIntf *, /* 19 code lengths */
- uIntf *, /* bits tree desired/actual depth */
- inflate_huft * FAR *, /* bits tree result */
- inflate_huft *, /* space for trees */
- z_streamp)); /* for messages */
-
-extern int inflate_trees_dynamic OF((
- uInt, /* number of literal/length codes */
- uInt, /* number of distance codes */
- uIntf *, /* that many (total) code lengths */
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- inflate_huft *, /* space for trees */
- z_streamp)); /* for messages */
-
-extern int inflate_trees_fixed OF((
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- z_streamp)); /* for memory allocation */
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infutil.c b/contrib/vmap_extractor_v2/stormlib/zlib/infutil.c
deleted file mode 100644
index 9a076221f2a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/infutil.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* And'ing with mask[n] masks the lower n bits */
-uInt inflate_mask[17] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-int inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt n;
- Bytef *p;
- Bytef *q;
-
- /* local copies of source and destination pointers */
- p = z->next_out;
- q = s->read;
-
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy as far as end of window */
- zmemcpy(p, q, n);
- p += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* compute bytes to copy */
- n = (uInt)(s->write - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy */
- zmemcpy(p, q, n);
- p += n;
- q += n;
- }
-
- /* update pointers */
- z->next_out = p;
- s->read = q;
-
- /* done */
- return r;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/infutil.h b/contrib/vmap_extractor_v2/stormlib/zlib/infutil.h
deleted file mode 100644
index 4401df82fc8..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/infutil.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFUTIL_H
-#define _INFUTIL_H
-
-typedef enum {
- TYPE, /* get type bits (3, including end bit) */
- LENS, /* get lengths for stored */
- STORED, /* processing stored block */
- TABLE, /* get table lengths */
- BTREE, /* get bit lengths tree for a dynamic block */
- DTREE, /* get length, distance trees for a dynamic block */
- CODES, /* processing fixed or dynamic block */
- DRY, /* output remaining window bytes */
- DONE, /* finished last block, done */
- BAD} /* got a data error--stuck here */
-inflate_block_mode;
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
- /* mode */
- inflate_block_mode mode; /* current inflate_block mode */
-
- /* mode dependent information */
- union {
- uInt left; /* if STORED, bytes left to copy */
- struct {
- uInt table; /* table lengths (14 bits) */
- uInt index; /* index into blens (or border) */
- uIntf *blens; /* bit lengths of codes */
- uInt bb; /* bit length tree depth */
- inflate_huft *tb; /* bit length decoding tree */
- } trees; /* if DTREE, decoding info for trees */
- struct {
- inflate_codes_statef
- *codes;
- } decode; /* if CODES, current state */
- } sub; /* submode */
- uInt last; /* true if this block is the last block */
-
- /* mode independent information */
- uInt bitk; /* bits in bit buffer */
- uLong bitb; /* bit buffer */
- inflate_huft *hufts; /* single malloc for tree space */
- Bytef *window; /* sliding window */
- Bytef *end; /* one byte after sliding window */
- Bytef *read; /* window read pointer */
- Bytef *write; /* window write pointer */
- check_func checkfn; /* check function */
- uLong check; /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/* update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/* get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/* output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/* load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-extern uInt inflate_mask[17];
-
-/* copy as much as possible from the sliding window to the output area */
-extern int inflate_flush OF((
- inflate_blocks_statef *,
- z_streamp ,
- int));
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#endif
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/maketree.c b/contrib/vmap_extractor_v2/stormlib/zlib/maketree.c
deleted file mode 100644
index a16d4b14608..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/maketree.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* maketree.c -- make inffixed.h table for decoding fixed codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* This program is included in the distribution for completeness.
- You do not need to compile or run this program since inffixed.h
- is already included in the distribution. To use this program
- you need to compile zlib with BUILDFIXED defined and then compile
- and link this program with the zlib library. Then the output of
- this program can be piped to inffixed.h. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "zutil.h"
-#include "inftrees.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* generate initialization table for an inflate_huft structure array */
-void maketree(uInt b, inflate_huft *t)
-{
- int i, e;
-
- i = 0;
- while (1)
- {
- e = t[i].exop;
- if (e && (e & (16+64)) == 0) /* table pointer */
- {
- fprintf(stderr, "maketree: cannot initialize sub-tables!\n");
- exit(1);
- }
- if (i % 4 == 0)
- printf("\n ");
- printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base);
- if (++i == (1<<b))
- break;
- putchar(',');
- }
- puts("");
-}
-
-/* create the fixed tables in C initialization syntax */
-void main(void)
-{
- int r;
- uInt bl, bd;
- inflate_huft *tl, *td;
- z_stream z;
-
- z.zalloc = zcalloc;
- z.opaque = (voidpf)0;
- z.zfree = zcfree;
- r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z);
- if (r)
- {
- fprintf(stderr, "inflate_trees_fixed error %d\n", r);
- return;
- }
- puts("/* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by the maketree.c program");
- puts(" */");
- puts("");
- puts("/* WARNING: this file should *not* be used by applications. It is");
- puts(" part of the implementation of the compression library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- printf("local uInt fixed_bl = %d;\n", bl);
- printf("local uInt fixed_bd = %d;\n", bd);
- printf("local inflate_huft fixed_tl[] = {");
- maketree(bl, tl);
- puts(" };");
- printf("local inflate_huft fixed_td[] = {");
- maketree(bd, td);
- puts(" };");
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/minigzip.c b/contrib/vmap_extractor_v2/stormlib/zlib/minigzip.c
deleted file mode 100644
index 97b7c2d93b2..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/minigzip.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * minigzip is a minimal implementation of the gzip utility. This is
- * only an example of using zlib and isn't meant to replace the
- * full-featured gzip. No attempt is made to deal with file systems
- * limiting names to 14 or 8+3 characters, etc... Error checking is
- * very limited. So use minigzip only for testing; use gzip for the
- * real thing. On MSDOS, use only on file names without extension
- * or in pipe mode.
- */
-
-/* @(#) $Id$ */
-
-#include <stdio.h>
-#include "zlib.h"
-
-#ifdef STDC
-# include <string.h>
-# include <stdlib.h>
-#else
- extern void exit OF((int));
-#endif
-
-#ifdef USE_MMAP
-# include <sys/types.h>
-# include <sys/mman.h>
-# include <sys/stat.h>
-#endif
-
-#if defined(MSDOS) || defined(OS2) || defined(WIN32)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-
-#ifdef VMS
-# define unlink delete
-# define GZ_SUFFIX "-gz"
-#endif
-#ifdef RISCOS
-# define unlink remove
-# define GZ_SUFFIX "-gz"
-# define fileno(file) file->__file
-#endif
-#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fileno */
-#endif
-
-#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
- extern int unlink OF((const char *));
-#endif
-
-#ifndef GZ_SUFFIX
-# define GZ_SUFFIX ".gz"
-#endif
-#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
-
-#define BUFLEN 16384
-#define MAX_NAME_LEN 1024
-
-#ifdef MAXSEG_64K
-# define local static
- /* Needed for systems with limitation on stack size. */
-#else
-# define local
-#endif
-
-char *prog;
-
-void error OF((const char *msg));
-void gz_compress OF((FILE *in, gzFile out));
-#ifdef USE_MMAP
-int gz_compress_mmap OF((FILE *in, gzFile out));
-#endif
-void gz_uncompress OF((gzFile in, FILE *out));
-void file_compress OF((char *file, char *mode));
-void file_uncompress OF((char *file));
-int main OF((int argc, char *argv[]));
-
-/* ===========================================================================
- * Display error message and exit
- */
-void error(msg)
- const char *msg;
-{
- fprintf(stderr, "%s: %s\n", prog, msg);
- exit(1);
-}
-
-/* ===========================================================================
- * Compress input to output then close both files.
- */
-
-void gz_compress(in, out)
- FILE *in;
- gzFile out;
-{
- local char buf[BUFLEN];
- int len;
- int err;
-
-#ifdef USE_MMAP
- /* Try first compressing with mmap. If mmap fails (minigzip used in a
- * pipe), use the normal fread loop.
- */
- if (gz_compress_mmap(in, out) == Z_OK) return;
-#endif
- for (;;) {
- len = fread(buf, 1, sizeof(buf), in);
- if (ferror(in)) {
- perror("fread");
- exit(1);
- }
- if (len == 0) break;
-
- if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
- }
- fclose(in);
- if (gzclose(out) != Z_OK) error("failed gzclose");
-}
-
-#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
-
-/* Try compressing the input file at once using mmap. Return Z_OK if
- * if success, Z_ERRNO otherwise.
- */
-int gz_compress_mmap(in, out)
- FILE *in;
- gzFile out;
-{
- int len;
- int err;
- int ifd = fileno(in);
- caddr_t buf; /* mmap'ed buffer for the entire input file */
- off_t buf_len; /* length of the input file */
- struct stat sb;
-
- /* Determine the size of the file, needed for mmap: */
- if (fstat(ifd, &sb) < 0) return Z_ERRNO;
- buf_len = sb.st_size;
- if (buf_len <= 0) return Z_ERRNO;
-
- /* Now do the actual mmap: */
- buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
- if (buf == (caddr_t)(-1)) return Z_ERRNO;
-
- /* Compress the whole file at once: */
- len = gzwrite(out, (char *)buf, (unsigned)buf_len);
-
- if (len != (int)buf_len) error(gzerror(out, &err));
-
- munmap(buf, buf_len);
- fclose(in);
- if (gzclose(out) != Z_OK) error("failed gzclose");
- return Z_OK;
-}
-#endif /* USE_MMAP */
-
-/* ===========================================================================
- * Uncompress input to output then close both files.
- */
-void gz_uncompress(in, out)
- gzFile in;
- FILE *out;
-{
- local char buf[BUFLEN];
- int len;
- int err;
-
- for (;;) {
- len = gzread(in, buf, sizeof(buf));
- if (len < 0) error (gzerror(in, &err));
- if (len == 0) break;
-
- if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
- error("failed fwrite");
- }
- }
- if (fclose(out)) error("failed fclose");
-
- if (gzclose(in) != Z_OK) error("failed gzclose");
-}
-
-
-/* ===========================================================================
- * Compress the given file: create a corresponding .gz file and remove the
- * original.
- */
-void file_compress(file, mode)
- char *file;
- char *mode;
-{
- local char outfile[MAX_NAME_LEN];
- FILE *in;
- gzFile out;
-
- strcpy(outfile, file);
- strcat(outfile, GZ_SUFFIX);
-
- in = fopen(file, "rb");
- if (in == NULL) {
- perror(file);
- exit(1);
- }
- out = gzopen(outfile, mode);
- if (out == NULL) {
- fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
- exit(1);
- }
- gz_compress(in, out);
-
- unlink(file);
-}
-
-
-/* ===========================================================================
- * Uncompress the given file and remove the original.
- */
-void file_uncompress(file)
- char *file;
-{
- local char buf[MAX_NAME_LEN];
- char *infile, *outfile;
- FILE *out;
- gzFile in;
- int len = strlen(file);
-
- strcpy(buf, file);
-
- if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
- infile = file;
- outfile = buf;
- outfile[len-3] = '\0';
- } else {
- outfile = file;
- infile = buf;
- strcat(infile, GZ_SUFFIX);
- }
- in = gzopen(infile, "rb");
- if (in == NULL) {
- fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
- exit(1);
- }
- out = fopen(outfile, "wb");
- if (out == NULL) {
- perror(file);
- exit(1);
- }
-
- gz_uncompress(in, out);
-
- unlink(infile);
-}
-
-
-/* ===========================================================================
- * Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...]
- * -d : decompress
- * -f : compress with Z_FILTERED
- * -h : compress with Z_HUFFMAN_ONLY
- * -1 to -9 : compression level
- */
-
-int main(argc, argv)
- int argc;
- char *argv[];
-{
- int uncompr = 0;
- gzFile file;
- char outmode[20];
-
- strcpy(outmode, "wb6 ");
-
- prog = argv[0];
- argc--, argv++;
-
- while (argc > 0) {
- if (strcmp(*argv, "-d") == 0)
- uncompr = 1;
- else if (strcmp(*argv, "-f") == 0)
- outmode[3] = 'f';
- else if (strcmp(*argv, "-h") == 0)
- outmode[3] = 'h';
- else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
- (*argv)[2] == 0)
- outmode[2] = (*argv)[1];
- else
- break;
- argc--, argv++;
- }
- if (argc == 0) {
- SET_BINARY_MODE(stdin);
- SET_BINARY_MODE(stdout);
- if (uncompr) {
- file = gzdopen(fileno(stdin), "rb");
- if (file == NULL) error("can't gzdopen stdin");
- gz_uncompress(file, stdout);
- } else {
- file = gzdopen(fileno(stdout), outmode);
- if (file == NULL) error("can't gzdopen stdout");
- gz_compress(stdin, file);
- }
- } else {
- do {
- if (uncompr) {
- file_uncompress(*argv);
- } else {
- file_compress(*argv, outmode);
- }
- } while (argv++, --argc);
- }
- exit(0);
- return 0; /* to avoid warning */
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.b32 b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.b32
deleted file mode 100644
index f476da91649..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.b32
+++ /dev/null
@@ -1,104 +0,0 @@
-# Makefile for zlib
-# Borland C++
-
-# This version of the zlib makefile was adapted by Chris Young for use
-# with Borland C 4.5x with the Dos Power Pack for a 32-bit protected mode
-# flat memory model. It was created for use with POV-Ray ray tracer and
-# you may choose to edit the CFLAGS to suit your needs but the
-# switches -WX and -DMSDOS are required.
-# -- Chris Young 76702.1655@compuserve.com
-
-# To use, do "make -fmakefile.b32"
-
-# See zconf.h for details about the memory requirements.
-
-# ------------- Borland C++ -------------
-MODEL=-WX
-CFLAGS= $(MODEL) -P-C -K -N- -k- -d -3 -r- -v- -f -DMSDOS
-CC=bcc32
-LD=bcc32
-LIB=tlib
-LDFLAGS= $(MODEL)
-O=.obj
-
-# variables
-OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
- trees$(O)
-OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
- trees$(O)
-OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
- infutil$(O) inffast$(O)
-OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
- infutil$(O)+inffast$(O)
-
-all: test
-
-adler32.obj: adler32.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-compress.obj: compress.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-crc32.obj: crc32.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
- infcodes.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
- infcodes.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
- $(CC) -c $(CFLAGS) $*.c
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
- $(CC) -c $(CFLAGS) $*.c
-
-infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-uncompr.obj: uncompr.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-example.obj: example.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-# we must cut the command line to fit in the MS/DOS 128 byte limit:
-zlib.lib: $(OBJ1) $(OBJ2)
- del zlib.lib
- $(LIB) zlib +$(OBJP1)
- $(LIB) zlib +$(OBJP2)
-
-example.exe: example.obj zlib.lib
- $(LD) $(LDFLAGS) example.obj zlib.lib
-
-minigzip.exe: minigzip.obj zlib.lib
- $(LD) $(LDFLAGS) minigzip.obj zlib.lib
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-#clean:
-# del *.obj
-# del *.exe
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.bor b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.bor
deleted file mode 100644
index f5651b40fec..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.bor
+++ /dev/null
@@ -1,125 +0,0 @@
-# Makefile for zlib
-# Borland C++ ************ UNTESTED ***********
-
-# To use, do "make -fmakefile.bor"
-# To compile in small model, set below: MODEL=s
-
-# WARNING: the small model is supported but only for small values of
-# MAX_WBITS and MAX_MEM_LEVEL. For example:
-# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
-# If you wish to reduce the memory requirements (default 256K for big
-# objects plus a few K), you can add to the LOC macro below:
-# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
-# See zconf.h for details about the memory requirements.
-
-# ------------- Turbo C++, Borland C++ -------------
-
-# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
-# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
-# to the declaration of LOC here:
-LOC = $(LOCAL_ZLIB)
-
-# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
-CPU_TYP = 0
-
-# Memory model: one of s, m, c, l (small, medium, compact, large)
-MODEL=l
-
-CC=bcc
-# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
-LD=$(CC)
-AR=tlib
-
-# compiler flags
-CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
-# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
-
-LDFLAGS=-m$(MODEL)
-
-O=.obj
-
-# variables
-OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
- trees$(O)
-OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
- trees$(O)
-OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
- infutil$(O) inffast$(O)
-OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
- infutil$(O)+inffast$(O)
-
-ZLIB_H = zlib.h zconf.h
-ZUTIL_H = zutil.h $(ZLIB_H)
-
-ZLIB_LIB = zlib_$(MODEL).lib
-
-all: test
-
-# individual dependencies and action rules:
-adler32.obj: adler32.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-compress.obj: compress.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crc32.obj: crc32.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-deflate.obj: deflate.c deflate.h $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-gzio.obj: gzio.c $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-inflate.obj: inflate.c $(ZUTIL_H) infblock.h
- $(CC) -c $(CFLAGS) $*.c
-
-inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h
- $(CC) -c $(CFLAGS) $*.c
-
-infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-trees.obj: trees.c deflate.h $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-uncompr.obj: uncompr.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-zutil.obj: zutil.c $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-example.obj: example.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-# we must cut the command line to fit in the MS/DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- del $(ZLIB_LIB)
- $(AR) $(ZLIB_LIB) +$(OBJP1)
- $(AR) $(ZLIB_LIB) +$(OBJP2)
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-#clean:
-# del *.obj
-# del *.exe
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.dj2 b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.dj2
deleted file mode 100644
index 0ab431c8a11..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.dj2
+++ /dev/null
@@ -1,100 +0,0 @@
-# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.dj2; make test -fmakefile.dj2
-#
-# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
-#
-# make install -fmakefile.dj2
-#
-# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
-# in the sample below if the pattern of the DJGPP distribution is to
-# be followed. Remember that, while <sp>'es around <=> are ignored in
-# makefiles, they are *not* in batch files or in djgpp.env.
-# - - - - -
-# [make]
-# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
-# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
-# BUTT=-m486
-# - - - - -
-# Alternately, these variables may be defined below, overriding the values
-# in djgpp.env, as
-# INCLUDE_PATH=c:\usr\include
-# LIBRARY_PATH=c:\usr\lib
-
-CC=gcc
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lz
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=libz.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-libz.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
-
-.PHONY : uninstall clean
-
-install: $(INCL) $(LIBS)
- -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
- -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
- $(INSTALL) zlib.h $(INCLUDE_PATH)
- $(INSTALL) zconf.h $(INCLUDE_PATH)
- $(INSTALL) libz.a $(LIBRARY_PATH)
-
-uninstall:
- $(RM) $(INCLUDE_PATH)\zlib.h
- $(RM) $(INCLUDE_PATH)\zconf.h
- $(RM) $(LIBRARY_PATH)\libz.a
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) libz.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.emx b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.emx
deleted file mode 100644
index 0e5e5cc4338..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.emx
+++ /dev/null
@@ -1,69 +0,0 @@
-# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98.
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.emx; make test -fmakefile.emx
-#
-
-CC=gcc
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lzlib
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=zlib.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-zlib.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-
-.PHONY : clean
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) zlib.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.msc b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.msc
deleted file mode 100644
index 562201d87ea..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.msc
+++ /dev/null
@@ -1,121 +0,0 @@
-# Makefile for zlib
-# Microsoft C 5.1 or later
-
-# To use, do "make makefile.msc"
-# To compile in small model, set below: MODEL=S
-
-# If you wish to reduce the memory requirements (default 256K for big
-# objects plus a few K), you can add to the LOC macro below:
-# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
-# See zconf.h for details about the memory requirements.
-
-# ------------- Microsoft C 5.1 and later -------------
-
-# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
-# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
-# to the declaration of LOC here:
-LOC = $(LOCAL_ZLIB)
-
-# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
-CPU_TYP = 0
-
-# Memory model: one of S, M, C, L (small, medium, compact, large)
-MODEL=L
-
-CC=cl
-CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
-#-Ox generates bad code with MSC 5.1
-LIB_CFLAGS=-Zl $(CFLAGS)
-
-LD=link
-LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
-# "/farcall/packcode" are only useful for `large code' memory models
-# but should be a "no-op" for small code models.
-
-O=.obj
-
-# variables
-OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
- trees$(O)
-OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
- trees$(O)
-OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
- infutil$(O) inffast$(O)
-OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
- infutil$(O)+inffast$(O)
-
-ZLIB_H = zlib.h zconf.h
-ZUTIL_H = zutil.h $(ZLIB_H)
-
-ZLIB_LIB = zlib_$(MODEL).lib
-
-all: $(ZLIB_LIB) example.exe minigzip.exe
-
-# individual dependencies and action rules:
-adler32.obj: adler32.c $(ZLIB_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-compress.obj: compress.c $(ZLIB_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-crc32.obj: crc32.c $(ZLIB_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-deflate.obj: deflate.c deflate.h $(ZUTIL_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-gzio.obj: gzio.c $(ZUTIL_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-inflate.obj: inflate.c $(ZUTIL_H) infblock.h
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-trees.obj: trees.c deflate.h $(ZUTIL_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-uncompr.obj: uncompr.c $(ZLIB_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-zutil.obj: zutil.c $(ZUTIL_H)
- $(CC) -c $(LIB_CFLAGS) $*.c
-
-example.obj: example.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-# we must cut the command line to fit in the MS/DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- if exist $(ZLIB_LIB) del $(ZLIB_LIB)
- lib $(ZLIB_LIB) $(OBJ1);
- lib $(ZLIB_LIB) $(OBJ2);
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-#clean:
-# del *.obj
-# del *.exe
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.tc b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.tc
deleted file mode 100644
index 63e0550359f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.tc
+++ /dev/null
@@ -1,108 +0,0 @@
-# Makefile for zlib
-# TurboC 2.0
-
-# To use, do "make -fmakefile.tc"
-# To compile in small model, set below: MODEL=-ms
-
-# WARNING: the small model is supported but only for small values of
-# MAX_WBITS and MAX_MEM_LEVEL. For example:
-# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-# If you wish to reduce the memory requirements (default 256K for big
-# objects plus a few K), you can add to CFLAGS below:
-# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
-# See zconf.h for details about the memory requirements.
-
-# ------------- Turbo C 2.0 -------------
-MODEL=l
-# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-CFLAGS=-O2 -G -Z -m$(MODEL)
-CC=tcc -I\tc\include
-LD=tcc -L\tc\lib
-AR=tlib
-LDFLAGS=-m$(MODEL) -f-
-O=.obj
-
-# variables
-OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
- trees$(O)
-OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
- trees$(O)
-OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
- infutil$(O) inffast$(O)
-OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
- infutil$(O)+inffast$(O)
-
-ZLIB_H = zlib.h zconf.h
-ZUTIL_H = zutil.h $(ZLIB_H)
-
-ZLIB_LIB = zlib_$(MODEL).lib
-
-all: test
-
-adler32.obj: adler32.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-compress.obj: compress.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crc32.obj: crc32.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-deflate.obj: deflate.c deflate.h $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-gzio.obj: gzio.c $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-inflate.obj: inflate.c $(ZUTIL_H) infblock.h
- $(CC) -c $(CFLAGS) $*.c
-
-inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h
- $(CC) -c $(CFLAGS) $*.c
-
-infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-trees.obj: trees.c deflate.h $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-uncompr.obj: uncompr.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-zutil.obj: zutil.c $(ZUTIL_H)
- $(CC) -c $(CFLAGS) $*.c
-
-example.obj: example.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c $(ZLIB_H)
- $(CC) -c $(CFLAGS) $*.c
-
-# we must cut the command line to fit in the MS/DOS 128 byte limit:
-$(ZLIB_LIB): $(OBJ1) $(OBJ2)
- del $(ZLIB_LIB)
- $(AR) $(ZLIB_LIB) +$(OBJP1)
- $(AR) $(ZLIB_LIB) +$(OBJP2)
-
-example.exe: example.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) -eexample.exe example.obj $(ZLIB_LIB)
-
-minigzip.exe: minigzip.obj $(ZLIB_LIB)
- $(LD) $(LDFLAGS) -eminigzip.exe minigzip.obj $(ZLIB_LIB)
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-#clean:
-# del *.obj
-# del *.exe
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.w32 b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.w32
deleted file mode 100644
index 0a05fa9a469..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.w32
+++ /dev/null
@@ -1,97 +0,0 @@
-# Makefile for zlib
-# Microsoft 32-bit Visual C++ 4.0 or later (may work on earlier versions)
-
-# To use, do "nmake /f makefile.w32"
-
-# If you wish to reduce the memory requirements (default 256K for big
-# objects plus a few K), you can add to CFLAGS below:
-# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
-# See zconf.h for details about the memory requirements.
-
-# ------------- Microsoft Visual C++ 4.0 and later -------------
-MODEL=
-CFLAGS=-Ox -GA3s -nologo -W3
-CC=cl
-LD=link
-LDFLAGS=
-O=.obj
-
-# variables
-OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
- trees$(O)
-OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
- trees$(O)
-OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
- infutil$(O) inffast$(O)
-OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
- infutil$(O)+inffast$(O)
-
-all: zlib.lib example.exe minigzip.exe
-
-adler32.obj: adler32.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-compress.obj: compress.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-crc32.obj: crc32.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
- infcodes.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
- infcodes.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
- $(CC) -c $(CFLAGS) $*.c
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
- $(CC) -c $(CFLAGS) $*.c
-
-infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
- $(CC) -c $(CFLAGS) $*.c
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
- $(CC) -c $(CFLAGS) $*.c
-
-trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-uncompr.obj: uncompr.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-example.obj: example.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c zlib.h zconf.h
- $(CC) -c $(CFLAGS) $*.c
-
-zlib.lib: $(OBJ1) $(OBJ2)
- if exist zlib.lib del zlib.lib
- lib /OUT:zlib.lib $(OBJ1) $(OBJ2)
-
-example.exe: example.obj zlib.lib
- $(LD) $(LDFLAGS) example.obj zlib.lib /OUT:example.exe /SUBSYSTEM:CONSOLE
-
-minigzip.exe: minigzip.obj zlib.lib
- $(LD) $(LDFLAGS) minigzip.obj zlib.lib /OUT:minigzip.exe /SUBSYSTEM:CONSOLE
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-#clean:
-# del *.obj
-# del *.exe
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.wat b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.wat
deleted file mode 100644
index 44bf8607f6f..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/Makefile.wat
+++ /dev/null
@@ -1,103 +0,0 @@
-# Makefile for zlib
-# Watcom 10a
-
-# This version of the zlib makefile was adapted by Chris Young for use
-# with Watcom 10a 32-bit protected mode flat memory model. It was created
-# for use with POV-Ray ray tracer and you may choose to edit the CFLAGS to
-# suit your needs but the -DMSDOS is required.
-# -- Chris Young 76702.1655@compuserve.com
-
-# To use, do "wmake -f makefile.wat"
-
-# See zconf.h for details about the memory requirements.
-
-# ------------- Watcom 10a -------------
-MODEL=-mf
-CFLAGS= $(MODEL) -fpi87 -fp5 -zp4 -5r -w5 -oneatx -DMSDOS
-CC=wcc386
-LD=wcl386
-LIB=wlib -b -c
-LDFLAGS=
-O=.obj
-
-# variables
-OBJ1=adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O)
-OBJ2=trees$(O) zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O)
-OBJ3=infutil$(O) inffast$(O)
-OBJP1=adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)
-OBJP2=trees$(O)+zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)
-OBJP3=infutil$(O)+inffast$(O)
-
-all: test
-
-adler32.obj: adler32.c zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-compress.obj: compress.c zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-crc32.obj: crc32.c zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h &
- infcodes.h infutil.h
- $(CC) $(CFLAGS) $*.c
-
-infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h &
- infcodes.h inffast.h
- $(CC) $(CFLAGS) $*.c
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
- $(CC) $(CFLAGS) $*.c
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
- $(CC) $(CFLAGS) $*.c
-
-infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
- $(CC) $(CFLAGS) $*.c
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
- $(CC) $(CFLAGS) $*.c
-
-trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-uncompr.obj: uncompr.c zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-example.obj: example.c zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c zlib.h zconf.h
- $(CC) $(CFLAGS) $*.c
-
-# we must cut the command line to fit in the MS/DOS 128 byte limit:
-zlib.lib: $(OBJ1) $(OBJ2) $(OBJ3)
- del zlib.lib
- $(LIB) zlib.lib +$(OBJP1)
- $(LIB) zlib.lib +$(OBJP2)
- $(LIB) zlib.lib +$(OBJP3)
-
-example.exe: example.obj zlib.lib
- $(LD) $(LDFLAGS) example.obj zlib.lib
-
-minigzip.exe: minigzip.obj zlib.lib
- $(LD) $(LDFLAGS) minigzip.obj zlib.lib
-
-test: minigzip.exe example.exe
- example
- echo hello world | minigzip | minigzip -d >test
- type test
-
-#clean:
-# del *.obj
-# del *.exe
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.def b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.def
deleted file mode 100644
index 6c04412f9b0..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.def
+++ /dev/null
@@ -1,60 +0,0 @@
-LIBRARY "zlib"
-
-DESCRIPTION '"""zlib data compression library"""'
-
-EXETYPE NT
-
-SUBSYSTEM WINDOWS
-
-STUB 'WINSTUB.EXE'
-
-VERSION 1.13
-
-CODE EXECUTE READ
-
-DATA READ WRITE
-
-HEAPSIZE 1048576,4096
-
-EXPORTS
- adler32 @1
- compress @2
- crc32 @3
- deflate @4
- deflateCopy @5
- deflateEnd @6
- deflateInit2_ @7
- deflateInit_ @8
- deflateParams @9
- deflateReset @10
- deflateSetDictionary @11
- gzclose @12
- gzdopen @13
- gzerror @14
- gzflush @15
- gzopen @16
- gzread @17
- gzwrite @18
- inflate @19
- inflateEnd @20
- inflateInit2_ @21
- inflateInit_ @22
- inflateReset @23
- inflateSetDictionary @24
- inflateSync @25
- uncompress @26
- zlibVersion @27
- gzprintf @28
- gzputc @29
- gzgetc @30
- gzseek @31
- gzrewind @32
- gztell @33
- gzeof @34
- gzsetparams @35
- zError @36
- inflateSyncPoint @37
- get_crc_table @38
- compress2 @39
- gzputs @40
- gzgets @41
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.rc b/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.rc
deleted file mode 100644
index 556d4ff950a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/msdos/zlib.rc
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <windows.h>
-
-#define IDR_VERSION1 1
-IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
- FILEVERSION 1,1,3,0
- PRODUCTVERSION 1,1,3,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0
- FILEOS VOS_DOS_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0 // not used
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904E4"
- //language ID = U.S. English, char set = Windows, Multilingual
-
- BEGIN
- VALUE "FileDescription", "zlib data compression library\0"
- VALUE "FileVersion", "1.1.3\0"
- VALUE "InternalName", "zlib\0"
- VALUE "OriginalFilename", "zlib.dll\0"
- VALUE "ProductName", "ZLib.DLL\0"
- VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
- VALUE "LegalCopyright", "(C) 1995-1998 Jean-loup Gailly & Mark Adler\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x0409, 1252
- END
-END
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.emx b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.emx
deleted file mode 100644
index 2d475b1847e..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.emx
+++ /dev/null
@@ -1,138 +0,0 @@
-# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.emx; make test -fmakefile.emx
-#
-
-CC=gcc -Zwin32
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lzlib
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=zlib.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-zlib.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-
-.PHONY : clean
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) zlib.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
-# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98.
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.emx; make test -fmakefile.emx
-#
-
-CC=gcc
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lzlib
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=zlib.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-zlib.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-
-.PHONY : clean
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) zlib.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.gcc b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.gcc
deleted file mode 100644
index cdd652f2360..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.gcc
+++ /dev/null
@@ -1,87 +0,0 @@
-# Makefile for zlib. Modified for mingw32 by C. Spieler, 6/16/98.
-# (This Makefile is directly derived from Makefile.dj2)
-# Copyright (C) 1995-1998 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile, or to compile and test, type:
-#
-# make -fmakefile.gcc; make test -fmakefile.gcc
-#
-# To install libz.a, zconf.h and zlib.h in the mingw32 directories, type:
-#
-# make install -fmakefile.gcc
-#
-
-CC=gcc
-
-#CFLAGS=-MMD -O
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-MMD -g -DDEBUG
-CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
- -Wstrict-prototypes -Wmissing-prototypes
-
-# If cp.exe is available, replace "copy /Y" with "cp -fp" .
-CP=copy /Y
-# If gnu install.exe is available, replace $(CP) with ginstall.
-INSTALL=$(CP)
-# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
-RM=del
-LDLIBS=-L. -lz
-LD=$(CC) -s -o
-LDSHARED=$(CC)
-
-INCL=zlib.h zconf.h
-LIBS=libz.a
-
-AR=ar rcs
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-all: example.exe minigzip.exe
-
-test: all
- ./example
- echo hello world | .\minigzip | .\minigzip -d
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-libz.a: $(OBJS)
- $(AR) $@ $(OBJS)
-
-%.exe : %.o $(LIBS)
- $(LD) $@ $< $(LDLIBS)
-
-# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
-
-.PHONY : uninstall clean
-
-install: $(INCL) $(LIBS)
- -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
- -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
- $(INSTALL) zlib.h $(INCLUDE_PATH)
- $(INSTALL) zconf.h $(INCLUDE_PATH)
- $(INSTALL) libz.a $(LIBRARY_PATH)
-
-uninstall:
- $(RM) $(INCLUDE_PATH)\zlib.h
- $(RM) $(INCLUDE_PATH)\zconf.h
- $(RM) $(LIBRARY_PATH)\libz.a
-
-clean:
- $(RM) *.d
- $(RM) *.o
- $(RM) *.exe
- $(RM) libz.a
- $(RM) foo.gz
-
-DEPS := $(wildcard *.d)
-ifneq ($(DEPS),)
-include $(DEPS)
-endif
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.nt b/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.nt
deleted file mode 100644
index b250f2ac7d2..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/nt/Makefile.nt
+++ /dev/null
@@ -1,88 +0,0 @@
-# Makefile for zlib
-
-!include <ntwin32.mak>
-
-CC=cl
-LD=link
-CFLAGS=-O -nologo
-LDFLAGS=
-O=.obj
-
-# variables
-OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
- trees$(O)
-OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
- infutil$(O) inffast$(O)
-
-all: zlib.dll example.exe minigzip.exe
-
-adler32.obj: adler32.c zutil.h zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-compress.obj: compress.c zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-crc32.obj: crc32.c zutil.h zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-gzio.obj: gzio.c zutil.h zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
- infcodes.h infutil.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
- infcodes.h inffast.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-uncompr.obj: uncompr.c zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-zutil.obj: zutil.c zutil.h zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-example.obj: example.c zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-minigzip.obj: minigzip.c zlib.h zconf.h
- $(CC) -c $(cvarsdll) $(CFLAGS) $*.c
-
-zlib.dll: $(OBJ1) $(OBJ2) zlib.dnt
- link $(dlllflags) -out:$@ -def:zlib.dnt $(OBJ1) $(OBJ2) $(guilibsdll)
-
-zlib.lib: zlib.dll
-
-example.exe: example.obj zlib.lib
- $(LD) $(LDFLAGS) example.obj zlib.lib
-
-minigzip.exe: minigzip.obj zlib.lib
- $(LD) $(LDFLAGS) minigzip.obj zlib.lib
-
-test: example.exe minigzip.exe
- example
- echo hello world | minigzip | minigzip -d
-
-clean:
- del *.obj
- del *.exe
- del *.dll
- del *.lib
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/nt/zlib.dnt b/contrib/vmap_extractor_v2/stormlib/zlib/nt/zlib.dnt
deleted file mode 100644
index 7f9475cfb0e..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/nt/zlib.dnt
+++ /dev/null
@@ -1,47 +0,0 @@
-LIBRARY zlib.dll
-EXETYPE WINDOWS
-CODE PRELOAD MOVEABLE DISCARDABLE
-DATA PRELOAD MOVEABLE MULTIPLE
-
-EXPORTS
- adler32 @1
- compress @2
- crc32 @3
- deflate @4
- deflateCopy @5
- deflateEnd @6
- deflateInit2_ @7
- deflateInit_ @8
- deflateParams @9
- deflateReset @10
- deflateSetDictionary @11
- gzclose @12
- gzdopen @13
- gzerror @14
- gzflush @15
- gzopen @16
- gzread @17
- gzwrite @18
- inflate @19
- inflateEnd @20
- inflateInit2_ @21
- inflateInit_ @22
- inflateReset @23
- inflateSetDictionary @24
- inflateSync @25
- uncompress @26
- zlibVersion @27
- gzprintf @28
- gzputc @29
- gzgetc @30
- gzseek @31
- gzrewind @32
- gztell @33
- gzeof @34
- gzsetparams @35
- zError @36
- inflateSyncPoint @37
- get_crc_table @38
- compress2 @39
- gzputs @40
- gzgets @41
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/os2/Makefile.os2 b/contrib/vmap_extractor_v2/stormlib/zlib/os2/Makefile.os2
deleted file mode 100644
index 4f569471eca..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/os2/Makefile.os2
+++ /dev/null
@@ -1,136 +0,0 @@
-# Makefile for zlib under OS/2 using GCC (PGCC)
-# For conditions of distribution and use, see copyright notice in zlib.h
-
-# To compile and test, type:
-# cp Makefile.os2 ..
-# cd ..
-# make -f Makefile.os2 test
-
-# This makefile will build a static library z.lib, a shared library
-# z.dll and a import library zdll.lib. You can use either z.lib or
-# zdll.lib by specifying either -lz or -lzdll on gcc's command line
-
-CC=gcc -Zomf -s
-
-CFLAGS=-O6 -Wall
-#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
-#CFLAGS=-g -DDEBUG
-#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-# -Wstrict-prototypes -Wmissing-prototypes
-
-#################### BUG WARNING: #####################
-## infcodes.c hits a bug in pgcc-1.0, so you have to use either
-## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
-## This bug is reportedly fixed in pgcc >1.0, but this was not tested
-CFLAGS+=-fno-force-mem
-
-LDFLAGS=-s -L. -lzdll -Zcrtdll
-LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
-
-VER=1.1.0
-ZLIB=z.lib
-SHAREDLIB=z.dll
-SHAREDLIBIMP=zdll.lib
-LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
-
-AR=emxomfar cr
-IMPLIB=emximp
-RANLIB=echo
-TAR=tar
-SHELL=bash
-
-prefix=/usr/local
-exec_prefix = $(prefix)
-
-OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
- zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
-
-TEST_OBJS = example.o minigzip.o
-
-DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
- algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
- nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \
- contrib/asm386/*.asm contrib/asm386/*.c \
- contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
- contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
- contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
-
-all: example.exe minigzip.exe
-
-test: all
- @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
- echo hello world | ./minigzip | ./minigzip -d || \
- echo ' *** minigzip test FAILED ***' ; \
- if ./example; then \
- echo ' *** zlib test OK ***'; \
- else \
- echo ' *** zlib test FAILED ***'; \
- fi
-
-$(ZLIB): $(OBJS)
- $(AR) $@ $(OBJS)
- -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
-
-$(SHAREDLIB): $(OBJS) os2/z.def
- $(LDSHARED) -o $@ $^
-
-$(SHAREDLIBIMP): os2/z.def
- $(IMPLIB) -o $@ $^
-
-example.exe: example.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
-
-minigzip.exe: minigzip.o $(LIBS)
- $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
-
-clean:
- rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
-
-distclean: clean
-
-zip:
- mv Makefile Makefile~; cp -p Makefile.in Makefile
- rm -f test.c ztest*.c
- v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
- zip -ul9 zlib$$v $(DISTFILES)
- mv Makefile~ Makefile
-
-dist:
- mv Makefile Makefile~; cp -p Makefile.in Makefile
- rm -f test.c ztest*.c
- d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
- rm -f $$d.tar.gz; \
- if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
- files=""; \
- for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
- cd ..; \
- GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
- if test ! -d $$d; then rm -f $$d; fi
- mv Makefile~ Makefile
-
-tags:
- etags *.[ch]
-
-depend:
- makedepend -- $(CFLAGS) -- *.[ch]
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: zlib.h zconf.h
-deflate.o: deflate.h zutil.h zlib.h zconf.h
-example.o: zlib.h zconf.h
-gzio.o: zutil.h zlib.h zconf.h
-infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
-infcodes.o: zutil.h zlib.h zconf.h
-infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h
-inffast.o: infblock.h infcodes.h infutil.h inffast.h
-inflate.o: zutil.h zlib.h zconf.h infblock.h
-inftrees.o: zutil.h zlib.h zconf.h inftrees.h
-infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/os2/zlib.def b/contrib/vmap_extractor_v2/stormlib/zlib/os2/zlib.def
deleted file mode 100644
index 4c753f1a3b9..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/os2/zlib.def
+++ /dev/null
@@ -1,51 +0,0 @@
-;
-; Slightly modified version of ../nt/zlib.dnt :-)
-;
-
-LIBRARY Z
-DESCRIPTION "Zlib compression library for OS/2"
-CODE PRELOAD MOVEABLE DISCARDABLE
-DATA PRELOAD MOVEABLE MULTIPLE
-
-EXPORTS
- adler32
- compress
- crc32
- deflate
- deflateCopy
- deflateEnd
- deflateInit2_
- deflateInit_
- deflateParams
- deflateReset
- deflateSetDictionary
- gzclose
- gzdopen
- gzerror
- gzflush
- gzopen
- gzread
- gzwrite
- inflate
- inflateEnd
- inflateInit2_
- inflateInit_
- inflateReset
- inflateSetDictionary
- inflateSync
- uncompress
- zlibVersion
- gzprintf
- gzputc
- gzgetc
- gzseek
- gzrewind
- gztell
- gzeof
- gzsetparams
- zError
- inflateSyncPoint
- get_crc_table
- compress2
- gzputs
- gzgets
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/trees.c b/contrib/vmap_extractor_v2/stormlib/zlib/trees.c
deleted file mode 100644
index 0a984056738..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/trees.c
+++ /dev/null
@@ -1,1214 +0,0 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2002 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id$ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-#define MAX(a,b) (a >= b ? a : b)
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if (tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is ascii or binary */
- if (s->data_type == Z_UNKNOWN) set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute first the block length in bytes*/
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to ASCII or BINARY, using a crude approximation:
- * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
- * IN assertion: the fields freq of dyn_ltree are set and the total of all
- * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
- */
-local void set_data_type(s)
- deflate_state *s;
-{
- int n = 0;
- unsigned ascii_freq = 0;
- unsigned bin_freq = 0;
- while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
- while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
- while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
- s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/trees.h b/contrib/vmap_extractor_v2/stormlib/zlib/trees.h
deleted file mode 100644
index 72facf900f7..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/trees.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/uncompr.c b/contrib/vmap_extractor_v2/stormlib/zlib/uncompr.c
deleted file mode 100644
index a287714f5de..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/uncompr.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-
-/* ===========================================================================
- 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 compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- 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.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zconf.h b/contrib/vmap_extractor_v2/stormlib/zlib/zconf.h
deleted file mode 100644
index eb0ae2e1a0c..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/zconf.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2002 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.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateReset z_inflateReset
-# define compress z_compress
-# define compress2 z_compress2
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-# define WIN32
-#endif
-#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-# ifndef __32BIT__
-# define __32BIT__
-# endif
-#endif
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#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).
- */
-#if defined(MSDOS) && !defined(__32BIT__)
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
-# define STDC
-#endif
-#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
-# ifndef STDC
-# define STDC
-# endif
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const
-# 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
-
-/* Old Borland C incorrectly complains about missing returns: */
-#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
-# define NEED_DUMMY_RETURN
-#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.
- */
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-#endif
-#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-# ifndef __32BIT__
-# define SMALL_MEDIUM
-# define FAR _far
-# endif
-#endif
-
-/* Compile with -DZLIB_DLL for Windows DLL support */
-#if defined(ZLIB_DLL)
-# if defined(_WINDOWS) || defined(WINDOWS)
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR _cdecl _export
-# endif
-# endif
-# if defined (__BORLANDC__)
-# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
-# include <windows.h>
-# define ZEXPORT __declspec(dllexport) WINAPI
-# define ZEXPORTRVA __declspec(dllexport) WINAPIV
-# else
-# if defined (_Windows) && defined (__DLL__)
-# define ZEXPORT _export
-# define ZEXPORTVA _export
-# endif
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# if defined (ZLIB_DLL)
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-#endif
-
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(MACOS) && !defined(TARGET_OS_MAC)
-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 FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# define z_off_t off_t
-#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
-
-/* 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(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(inflate_blocks,"INBL")
-# pragma map(inflate_blocks_new,"INBLNE")
-# pragma map(inflate_blocks_free,"INBLFR")
-# pragma map(inflate_blocks_reset,"INBLRE")
-# pragma map(inflate_codes_free,"INCOFR")
-# pragma map(inflate_codes,"INCO")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_flush,"INFLU")
-# pragma map(inflate_mask,"INMA")
-# pragma map(inflate_set_dictionary,"INSEDI2")
-# pragma map(inflate_copyright,"INCOPY")
-# pragma map(inflate_trees_bits,"INTRBI")
-# pragma map(inflate_trees_dynamic,"INTRDY")
-# pragma map(inflate_trees_fixed,"INTRFI")
-# pragma map(inflate_trees_free,"INTRFR")
-#endif
-
-#endif /* _ZCONF_H */
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.3 b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.3
deleted file mode 100644
index 3a6e45047fe..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.3
+++ /dev/null
@@ -1,107 +0,0 @@
-.TH ZLIB 3 "11 March 2002"
-.SH NAME
-zlib \- compression/decompression library
-.SH SYNOPSIS
-[see
-.I zlib.h
-for full description]
-.SH DESCRIPTION
-The
-.I zlib
-library is a general purpose data compression library.
-The code is thread safe.
-It 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.
-.LP
-Compression can be done in a single step if the buffers are large enough
-(for example if an input file is mmap'ed),
-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.
-.LP
-The library also supports reading and writing files in
-.I gzip
-(.gz) format
-with an interface similar to that of stdio.
-.LP
-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.
-.LP
-All functions of the compression library are documented in the file
-.IR zlib.h.
-The distribution source includes examples of use of the library
-the files
-.I example.c
-and
-.IR minigzip.c .
-.LP
-A Java implementation of
-.IR zlib
-is available in the Java Development Kit 1.1
-.IP
-http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
-.LP
-A Perl interface to
-.IR zlib ,
-written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
-is available at CPAN (Comprehensive Perl Archive Network) sites,
-such as:
-.IP
-ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
-.LP
-A Python interface to
-.IR zlib
-written by A.M. Kuchling <amk@magnet.com>
-is available from the Python Software Association sites, such as:
-.IP
-ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz
-.SH "SEE ALSO"
-Questions about zlib should be sent to:
-.IP
-zlib@quest.jpl.nasa.gov
-or, if this fails, to the author addresses given below.
-The zlib home page is:
-.IP
-http://www.cdrom.com/pub/infozip/zlib/
-.LP
-The data format used by the zlib library is described by RFC
-(Request for Comments) 1950 to 1952 in the files:
-.IP
-ftp://ds.internic.net/rfc/rfc1950.txt (zlib format)
-.br
-rfc1951.txt (deflate format)
-.br
-rfc1952.txt (gzip format)
-.LP
-These documents are also available in other formats from:
-.IP
-ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
-.SH AUTHORS
-Version 1.1.4
-Copyright (C) 1995-2002 Jean-loup Gailly (jloup@gzip.org)
-and Mark Adler (madler@alumni.caltech.edu).
-.LP
-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.
-See the distribution directory with respect to requirements
-governing redistribution.
-The deflate format used by
-.I zlib
-was defined by Phil Katz.
-The deflate and
-.I zlib
-specifications were written by L. Peter Deutsch.
-Thanks to all the people who reported problems and suggested various
-improvements in
-.IR zlib ;
-who are too numerous to cite here.
-.LP
-UNIX manual page by R. P. C. Rodgers,
-U.S. National Library of Medicine (rodgers@nlm.nih.gov).
-.\" end of man page
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.h b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.h
deleted file mode 100644
index 52cb529f6f3..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.h
+++ /dev/null
@@ -1,893 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.1.4, March 11th, 2002
-
- Copyright (C) 1995-2002 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 ftp://ds.internic.net/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.1.4"
-
-/*
- 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 (for example if an input file is mmap'ed), 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 library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio.
-
- 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: ascii or binary */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- 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 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-/* Allowed flush values; see deflate() 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_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field */
-
-#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,
- 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.
-
- 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.
-
- 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
- the 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).
-
- 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
- 0.1% larger than avail_in plus 12 bytes. 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 data_type if it can make a good guess about
- the input data type (Z_ASCII or Z_BINARY). 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 NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero).
-*/
-
-
-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. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-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 some
- 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.
-
- If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
- output as possible to the output buffer. The flushing behavior of inflate is
- not specified for values of the flush parameter other than Z_SYNC_FLUSH
- and Z_FINISH, but the current implementation actually flushes as much output
- as possible anyway.
-
- 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 routine
- may be used for the single inflate() call.
-
- If a preset dictionary is needed at this point (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() 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
- adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
- (for example if next_in or next_out was 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. In the Z_DATA_ERROR
- case, the application may then call inflateSync to look for a good
- compression block.
-*/
-
-
-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.
-
- 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), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match). 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 and Z_HUFFMAN_ONLY. The strategy parameter only affects
- the compression ratio but not the correctness of the compressed output even
- if it is not set appropriately.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). 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 in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front.
-
- 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.)
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) 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 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 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 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. 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.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
- memLevel). msg is set to null if there is no error message. inflateInit2
- does not perform any decompression apart from reading the zlib header if
- present: this will be done by inflate(). (So next_in and avail_in may be
- modified, but next_out and avail_out are unchanged.)
-*/
-
-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 this call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the Adler32 value returned by this call of
- inflate. The compressor and decompressor must use exactly the same
- dictionary (see deflateSetDictionary).
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) 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 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 NULL).
-*/
-
-
- /* 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 easily 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 0.1% larger than
- sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- 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 0.1% larger than sourceLen plus
- 12 bytes. 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 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 compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- 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.
-*/
-
-
-typedef voidp gzFile;
-
-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". (See the description
- of deflateInit2 for more information about the strategy parameter.)
-
- 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 or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
-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 (in 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 gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-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.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- const voidp buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-
-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. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
-*/
-
-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 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 returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-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.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-
-ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-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.
-*/
-
- /* 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 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 crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running crc with the bytes buf[0..len-1] and return the updated
- crc. If buf is NULL, this function returns the required initial value
- 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();
-*/
-
-
- /* 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));
-#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))
-
-
-#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN const char * ZEXPORT zError OF((int err));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZLIB_H */
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.html b/contrib/vmap_extractor_v2/stormlib/zlib/zlib.html
deleted file mode 100644
index c3437038693..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/zlib.html
+++ /dev/null
@@ -1,971 +0,0 @@
-<html>
-<head>
- <title>
- zlib general purpose compression library version 1.1.4
- </title>
-</head>
-<body bgcolor="White" text="Black" vlink="Red" alink="Navy" link="Red">
-<!-- background="zlibbg.gif" -->
-
-<h1> zlib 1.1.4 Manual </h1>
-<hr>
-<a name="Contents"><h2>Contents</h2>
-<ol type="I">
-<li> <a href="#Prologue">Prologue</a>
-<li> <a href="#Introduction">Introduction</a>
-<li> <a href="#Utility functions">Utility functions</a>
-<li> <a href="#Basic functions">Basic functions</a>
-<li> <a href="#Advanced functions">Advanced functions</a>
-<li> <a href="#Constants">Constants</a>
-<li> <a href="#struct z_stream_s">struct z_stream_s</a>
-<li> <a href="#Checksum functions">Checksum functions</a>
-<li> <a href="#Misc">Misc</a>
-</ol>
-<hr>
-<a name="Prologue"><h2> Prologue </h2>
- 'zlib' general purpose compression library version 1.1.4, March 11th, 2002
- <p>
- Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
- <p>
- 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.
- <p>
- 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:
- <ol>
- <li> 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.
- <li> Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- <li> This notice may not be removed or altered from any source distribution.
- </ol>
-
- <dl>
- <dt>Jean-loup Gailly
- <dd><a href="mailto:jloup@gzip.org">jloup@gzip.org</a>
- <dt>Mark Adler
- <dd><a href="mailto:madler@alumni.caltech.edu">madler@alumni.caltech.edu</a>
- </dl>
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files
- <a href="ftp://ds.internic.net/rfc/rfc1950.txt">
- ftp://ds.internic.net/rfc/rfc1950.txt </a>
- (zlib format),
- <a href="ftp://ds.internic.net/rfc/rfc1951.txt">
- rfc1951.txt </a>
- (<a href="#deflate">deflate</a> format) and
- <a href="ftp://ds.internic.net/rfc/rfc1952.txt">
- rfc1952.txt </a>
- (gzip format).
- <p>
- This manual is converted from zlib.h by
- <a href="mailto:piaip@csie.ntu.edu.tw"> piaip </a>
- <p>
- Visit <a href="http://ftp.cdrom.com/pub/infozip/zlib/">
- http://ftp.cdrom.com/pub/infozip/zlib/</a>
- for the official zlib web page.
- <p>
-
-<hr>
-<a name="Introduction"><h2> Introduction </h2>
- 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.
- <p>
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), 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.
- <p>
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio.
- <p>
-
- 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.
- <p>
-
-<hr>
-<a name="Utility functions"><h2> Utility functions </h2>
- The following utility functions are implemented on top of the
- <a href="#Basic functions">basic stream-oriented functions</a>.
- 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 easily be modified if you need special options.
-<h3> Function list </h3>
-<ul>
-<li> int <a href="#compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
-<li> int <a href="#compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);
-<li> int <a href="#uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
-<li> typedef voidp gzFile;
-<li> gzFile <a href="#gzopen">gzopen</a> (const char *path, const char *mode);
-<li> gzFile <a href="#gzdopen">gzdopen</a> (int fd, const char *mode);
-<li> int <a href="#gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy);
-<li> int <a href="#gzread">gzread</a> (gzFile file, voidp buf, unsigned len);
-<li> int <a href="#gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len);
-<li> int VA <a href="#gzprintf">gzprintf</a> (gzFile file, const char *format, ...);
-<li> int <a href="#gzputs">gzputs</a> (gzFile file, const char *s);
-<li> char * <a href="#gzgets">gzgets</a> (gzFile file, char *buf, int len);
-<li> int <a href="#gzputc">gzputc</a> (gzFile file, int c);
-<li> int <a href="#gzgetc">gzgetc</a> (gzFile file);
-<li> int <a href="#gzflush">gzflush</a> (gzFile file, int flush);
-<li> z_off_t <a href="#gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence);
-<li> z_off_t <a href="#gztell">gztell</a> (gzFile file);
-<li> int <a href="#gzrewind">gzrewind</a> (gzFile file);
-<li> int <a href="#gzeof">gzeof</a> (gzFile file);
-<li> int <a href="#gzclose">gzclose</a> (gzFile file);
-<li> const char * <a href="#gzerror">gzerror</a> (gzFile file, int *errnum);
-</ul>
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> int <a name="compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font>
-<dd>
- 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 0.1% larger than
- sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
- compressed buffer.<p>
- This function can be used to <a href="#compress">compress</a> a whole file at once if the
- input file is mmap'ed.<p>
- <a href="#compress">compress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output
- buffer.<p>
-
-<font color="Blue"><dt> int <a name="compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);</font>
-<dd>
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in <a href="#deflateInit">deflateInit</a>. 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 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
- <p>
-
- <a href="#compress2">compress2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output buffer,
- <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the level parameter is invalid.
- <p>
-
-<font color="Blue"><dt> int <a name="uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font>
-<dd>
- 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 compressed buffer. <p>
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
- <p>
-
- <a href="#uncompress">uncompress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output
- buffer, or <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was corrupted.
- <p>
-
-<dt> typedef voidp gzFile;
-<dd> <p>
-
-<font color="Blue"><dt> gzFile <a name="gzopen">gzopen</a> (const char *path, const char *mode);</font>
-<dd>
- 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". (See the description
- of <a href="#deflateInit2">deflateInit2</a> for more information about the strategy parameter.)
- <p>
-
- <a href="#gzopen">gzopen</a> can be used to read a file which is not in gzip format ; in this
- case <a href="#gzread">gzread</a> will directly read from the file without decompression.
- <p>
-
- <a href="#gzopen">gzopen</a> returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression <a href="#state">state</a> ; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a>).
- <p>
-
-<font color="Blue"><dt> gzFile <a name="gzdopen">gzdopen</a> (int fd, const char *mode);</font>
-<dd>
- <a href="#gzdopen">gzdopen</a>() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in <a href="#gzopen">gzopen</a>.
- <p>
- The next call of <a href="#gzclose">gzclose</a> 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 <a href="#gzdopen">gzdopen</a>(dup(fd), mode).
- <p>
- <a href="#gzdopen">gzdopen</a> returns NULL if there was insufficient memory to allocate
- the (de)compression <a href="#state">state</a>.
- <p>
-
-<font color="Blue"><dt> int <a name="gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy);</font>
-<dd>
- Dynamically update the compression level or strategy. See the description
- of <a href="#deflateInit2">deflateInit2</a> for the meaning of these parameters.
- <p>
- <a href="#gzsetparams">gzsetparams</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the file was not
- opened for writing.
- <p>
-
-<font color="Blue"><dt> int <a name="gzread">gzread</a> (gzFile file, voidp buf, unsigned len);</font>
-<dd>
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, <a href="#gzread">gzread</a> copies the given number
- of bytes into the buffer.
- <p>
- <a href="#gzread">gzread</a> returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error).
- <p>
-
-<font color="Blue"><dt> int <a name="gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len);</font>
-<dd>
- Writes the given number of uncompressed bytes into the compressed file.
- <a href="#gzwrite">gzwrite</a> returns the number of uncompressed bytes actually written
- (0 in case of error).
- <p>
-
-<font color="Blue"><dt> int VA <a name="gzprintf">gzprintf</a> (gzFile file, const char *format, ...);</font>
-<dd>
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. <a href="#gzprintf">gzprintf</a> returns the number of
- uncompressed bytes actually written (0 in case of error).
- <p>
-
-<font color="Blue"><dt> int <a name="gzputs">gzputs</a> (gzFile file, const char *s);</font>
-<dd>
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- <p>
- <a href="#gzputs">gzputs</a> returns the number of characters written, or -1 in case of error.
- <p>
-
-<font color="Blue"><dt> char * <a name="gzgets">gzgets</a> (gzFile file, char *buf, int len);</font>
-<dd>
- 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. The string is then terminated with a null
- character.
- <p>
- <a href="#gzgets">gzgets</a> returns buf, or <a href="#Z_NULL">Z_NULL</a> in case of error.
- <p>
-
-<font color="Blue"><dt> int <a name="gzputc">gzputc</a> (gzFile file, int c);</font>
-<dd>
- Writes c, converted to an unsigned char, into the compressed file.
- <a href="#gzputc">gzputc</a> returns the value that was written, or -1 in case of error.
- <p>
-
-<font color="Blue"><dt> int <a name="gzgetc">gzgetc</a> (gzFile file);</font>
-<dd>
- Reads one byte from the compressed file. <a href="#gzgetc">gzgetc</a> returns this byte
- or -1 in case of end of file or error.
- <p>
-
-<font color="Blue"><dt> int <a name="gzflush">gzflush</a> (gzFile file, int flush);</font>
-<dd>
- Flushes all pending output into the compressed file. The parameter
- flush is as in the <a href="#deflate">deflate</a>() function. The return value is the zlib
- error number (see function <a href="#gzerror">gzerror</a> below). <a href="#gzflush">gzflush</a> returns <a href="#Z_OK">Z_OK</a> if
- the flush parameter is <a href="#Z_FINISH">Z_FINISH</a> and all output could be flushed.
- <p>
- <a href="#gzflush">gzflush</a> should be called only when strictly necessary because it can
- degrade compression.
- <p>
-
-<font color="Blue"><dt> z_off_t <a name="gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence);</font>
-<dd>
- Sets the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> 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.
- <p>
- 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 ; <a href="#gzseek">gzseek</a> then compresses a sequence of zeroes up to the new
- starting position.
- <p>
- <a href="#gzseek">gzseek</a> 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.
- <p>
-
-<font color="Blue"><dt> int <a name="gzrewind">gzrewind</a> (gzFile file);</font>
-<dd>
- Rewinds the given file. This function is supported only for reading.
- <p>
- <a href="#gzrewind">gzrewind</a>(file) is equivalent to (int)<a href="#gzseek">gzseek</a>(file, 0L, SEEK_SET)
- <p>
-
-<font color="Blue"><dt> z_off_t <a name="gztell">gztell</a> (gzFile file);</font>
-<dd>
- Returns the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
- <p>
-
- <a href="#gztell">gztell</a>(file) is equivalent to <a href="#gzseek">gzseek</a>(file, 0L, SEEK_CUR)
- <p>
-
-<font color="Blue"><dt> int <a name="gzeof">gzeof</a> (gzFile file);</font>
-<dd>
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
- <p>
-
-<font color="Blue"><dt> int <a name="gzclose">gzclose</a> (gzFile file);</font>
-<dd>
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression <a href="#state">state</a>. The return value is the zlib
- error number (see function <a href="#gzerror">gzerror</a> below).
- <p>
-
-<font color="Blue"><dt> const char * <a name="gzerror">gzerror</a> (gzFile file, int *errnum);</font>
-<dd>
- 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 <a href="#Z_ERRNO">Z_ERRNO</a> and the application may consult errno
- to get the exact error code.
- <p>
-</dl>
-<hr>
-<a name="Basic functions"><h2> Basic functions </h2>
-<h3> Function list </h3>
-<ul>
-<li> const char * <a href="#zlibVersion">zlibVersion</a> (void);
-<li> int <a href="#deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level);
-<li> int <a href="#deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);
-<li> int <a href="#deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);
-<li> int <a href="#inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);
-</ul>
-
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> const char * <a name="zlibVersion">zlibVersion</a> (void);</font>
-<dd> The application can compare <a href="#zlibVersion">zlibVersion</a> 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 <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a>.
- <p>
-
-<font color="Blue"><dt> int <a name="deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level);</font>
-<dd>
- Initializes the internal stream <a href="#state">state</a> for compression. The fields
- <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by the caller.
- If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#deflateInit">deflateInit</a> updates them to
- use default allocation functions.
- <p>
-
- The compression level must be <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a>, 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).
- <p>
-
- <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> requests a default compromise between speed and
- compression (currently equivalent to level 6).
- <p>
-
- <a href="#deflateInit">deflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if level is not a valid compression level,
- <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version (<a href="#zlib_version">zlib_version</a>) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit">deflateInit</a> does not
- perform any compression: this will be done by <a href="#deflate">deflate</a>().
- <p>
-
-<font color="Blue"><dt> int <a name="deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font>
-<dd>
- <a href="#deflate">deflate</a> 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.<p>
-
- The detailed semantics are as follows. <a href="#deflate">deflate</a> performs one or both of the
- following actions:
-
- <ul>
- <li> Compress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a>
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> are updated and
- processing will resume at this point for the next call of <a href="#deflate">deflate</a>().
-
- <li>
- Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a>
- 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.
- </ul> <p>
-
- Before the call of <a href="#deflate">deflate</a>(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> accordingly ; <a href="#avail_out">avail_out</a>
- 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
- (<a href="#avail_out">avail_out</a> == 0), or after each call of <a href="#deflate">deflate</a>(). If <a href="#deflate">deflate</a> returns <a href="#Z_OK">Z_OK</a>
- and with zero <a href="#avail_out">avail_out</a>, it must be called again after making room in the
- output buffer because there might be more output pending.
- <p>
-
- If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, 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
- <a href="#avail_in">avail_in</a> 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.
- <p>
-
- If flush is set to <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>, all output is flushed as with
- <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, and the compression <a href="#state">state</a> is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a> too often can seriously degrade
- the compression.
- <p>
-
- If <a href="#deflate">deflate</a> returns with <a href="#avail_out">avail_out</a> == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- <a href="#avail_out">avail_out</a>), until the flush is complete (<a href="#deflate">deflate</a> returns with non-zero
- <a href="#avail_out">avail_out</a>).
- <p>
-
- If the parameter flush is set to <a href="#Z_FINISH">Z_FINISH</a>, pending input is processed,
- pending output is flushed and <a href="#deflate">deflate</a> returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> if there
- was enough output space ; if <a href="#deflate">deflate</a> returns with <a href="#Z_OK">Z_OK</a>, this function must be
- called again with <a href="#Z_FINISH">Z_FINISH</a> and more output space (updated <a href="#avail_out">avail_out</a>) but no
- more input data, until it returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> or an error. After
- <a href="#deflate">deflate</a> has returned <a href="#Z_STREAM_END">Z_STREAM_END</a>, the only possible operations on the
- stream are <a href="#deflateReset">deflateReset</a> or <a href="#deflateEnd">deflateEnd</a>.
- <p>
-
- <a href="#Z_FINISH">Z_FINISH</a> can be used immediately after <a href="#deflateInit">deflateInit</a> if all the compression
- is to be done in a single step. In this case, <a href="#avail_out">avail_out</a> must be at least
- 0.1% larger than <a href="#avail_in">avail_in</a> plus 12 bytes. If <a href="#deflate">deflate</a> does not return
- <a href="#Z_STREAM_END">Z_STREAM_END</a>, then it must be called again as described above.
- <p>
-
- <a href="#deflate">deflate</a>() sets strm-&gt <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all input read
- so far (that is, <a href="#total_in">total_in</a> bytes).
- <p>
-
- <a href="#deflate">deflate</a>() may update <a href="#data_type">data_type</a> if it can make a good guess about
- the input data type (<a href="#Z_ASCII">Z_ASCII</a> or <a href="#Z_BINARY">Z_BINARY</a>). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
- <p>
-
- <a href="#deflate">deflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input
- processed or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if all input has been
- consumed and all output has been produced (only when flush is set to
- <a href="#Z_FINISH">Z_FINISH</a>), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a> was inconsistent (for example
- if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible
- (for example <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> was zero).
- <p>
-
-<font color="Blue"><dt> int <a name="deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
- <p>
-
- <a href="#deflateEnd">deflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the
- stream <a href="#state">state</a> was inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- <a href="#msg">msg</a> may be set but then points to a static string (which must not be
- deallocated).
- <p>
-
-<font color="Blue"><dt> int <a name="inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- Initializes the internal stream <a href="#state">state</a> for decompression. The fields
- <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by
- the caller. If <a href="#next_in">next_in</a> is not <a href="#Z_NULL">Z_NULL</a> and <a href="#avail_in">avail_in</a> is large enough (the exact
- value depends on the compression method), <a href="#inflateInit">inflateInit</a> 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
- <a href="#inflate">inflate</a>. If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#inflateInit">inflateInit</a> updates them to
- use default allocation functions.
- <p>
-
- <a href="#inflateInit">inflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version is incompatible with the
- version assumed by the caller. <a href="#msg">msg</a> is set to null if there is no error
- message. <a href="#inflateInit">inflateInit</a> does not perform any decompression apart from reading
- the zlib header if present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and
- <a href="#avail_in">avail_in</a> may be modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.)
- <p>
-
-<font color="Blue"><dt> int <a name="inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font>
-<dd>
- <a href="#inflate">inflate</a> decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may some
- introduce some output latency (reading input without producing any output)
- except when forced to flush.
- <p>
-
- The detailed semantics are as follows. <a href="#inflate">inflate</a> performs one or both of the
- following actions:
-
- <ul>
- <li> Decompress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a>
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), <a href="#next_in">next_in</a> is updated and processing
- will resume at this point for the next call of <a href="#inflate">inflate</a>().
-
- <li> Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and
- <a href="#avail_out">avail_out</a> accordingly. <a href="#inflate">inflate</a>() 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).
- </ul> <p>
-
- Before the call of <a href="#inflate">inflate</a>(), 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 (<a href="#avail_out">avail_out</a> == 0), or after each
- call of <a href="#inflate">inflate</a>(). If <a href="#inflate">inflate</a> returns <a href="#Z_OK">Z_OK</a> and with zero <a href="#avail_out">avail_out</a>, it
- must be called again after making room in the output buffer because there
- might be more output pending.
- <p>
-
- If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, <a href="#inflate">inflate</a> flushes as much
- output as possible to the output buffer. The flushing behavior of <a href="#inflate">inflate</a> is
- not specified for values of the flush parameter other than <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>
- and <a href="#Z_FINISH">Z_FINISH</a>, but the current implementation actually flushes as much output
- as possible anyway.
- <p>
-
- <a href="#inflate">inflate</a>() should normally be called until it returns <a href="#Z_STREAM_END">Z_STREAM_END</a> or an
- error. However if all decompression is to be performed in a single step
- (a single call of <a href="#inflate">inflate</a>), the parameter flush should be set to
- <a href="#Z_FINISH">Z_FINISH</a>. In this case all pending input is processed and all pending
- output is flushed ; <a href="#avail_out">avail_out</a> 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 <a href="#inflateEnd">inflateEnd</a> to deallocate the decompression <a href="#state">state</a>. The use of <a href="#Z_FINISH">Z_FINISH</a>
- is never required, but can be used to inform <a href="#inflate">inflate</a> that a faster routine
- may be used for the single <a href="#inflate">inflate</a>() call.
- <p>
-
- If a preset dictionary is needed at this point (see <a href="#inflateSetDictionary">inflateSetDictionary</a>
- below), <a href="#inflate">inflate</a> sets strm-<a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of the
- dictionary chosen by the compressor and returns <a href="#Z_NEED_DICT">Z_NEED_DICT</a> ; otherwise
- it sets strm-&gt <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all output produced
- so far (that is, <a href="#total_out">total_out</a> bytes) and returns <a href="#Z_OK">Z_OK</a>, <a href="#Z_STREAM_END">Z_STREAM_END</a> or
- an error code as described below. At the end of the stream, <a href="#inflate">inflate</a>()
- checks that its computed <a href="#adler32">adler32</a> checksum is equal to that saved by the
- compressor and returns <a href="#Z_STREAM_END">Z_STREAM_END</a> only if the checksum is correct.
- <p>
-
- <a href="#inflate">inflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input processed
- or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if the end of the compressed data has
- been reached and all uncompressed output has been produced, <a href="#Z_NEED_DICT">Z_NEED_DICT</a> if a
- preset dictionary is needed at this point, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect
- <a href="#adler32">adler32</a> checksum), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent
- (for example if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible or if there was not
- enough room in the output buffer when <a href="#Z_FINISH">Z_FINISH</a> is used. In the <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a>
- case, the application may then call <a href="#inflateSync">inflateSync</a> to look for a good
- compression block.
- <p>
-
-<font color="Blue"><dt> int <a name="inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
- <p>
-
- <a href="#inflateEnd">inflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a>
- was inconsistent. In the error case, <a href="#msg">msg</a> may be set but then points to a
- static string (which must not be deallocated).
-</dl>
-<hr>
-<a name="Advanced functions"><h2> Advanced functions </h2>
- The following functions are needed only in some special applications.
-<h3> Function list </h3>
-<ul>
-<li> int <a href="#deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm,
-<li> int <a href="#deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);
-<li> int <a href="#deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source);
-<li> int <a href="#deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy);
-<li> int <a href="#inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits);
-<li> int <a href="#inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);
-<li> int <a href="#inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm);
-<li> int <a href="#inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);
-
-</ul>
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> int <a name="deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int method, int windowBits, int memLevel, int strategy);</font>
-
-<dd> This is another version of <a href="#deflateInit">deflateInit</a> with more compression options. The
- fields <a href="#next_in">next_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by
- the caller.<p>
-
- The method parameter is the compression method. It must be <a href="#Z_DEFLATED">Z_DEFLATED</a> in
- this version of the library.<p>
-
- 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
- <a href="#deflateInit">deflateInit</a> is used instead.<p>
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression <a href="#state">state</a>. 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.<p>
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value <a href="#Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> for normal data, <a href="#Z_FILTERED">Z_FILTERED</a> for data produced by a
- filter (or predictor), or <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> to force Huffman encoding only (no
- string match). Filtered data consists mostly of small values with a
- somewhat random distribution. In this case, the compression algorithm is
- tuned to <a href="#compress">compress</a> them better. The effect of <a href="#Z_FILTERED">Z_FILTERED</a> is to force more
- Huffman coding and less string matching ; it is somewhat intermediate
- between Z_DEFAULT and <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a>. The strategy parameter only affects
- the compression ratio but not the correctness of the compressed output even
- if it is not set appropriately.<p>
-
- <a href="#deflateInit2">deflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as an invalid
- method). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit2">deflateInit2</a> does
- not perform any compression: this will be done by <a href="#deflate">deflate</a>().<p>
-
-<font color="Blue"><dt> int <a name="deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font>
-<dd>
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after <a href="#deflateInit">deflateInit</a>, <a href="#deflateInit2">deflateInit2</a> or <a href="#deflateReset">deflateReset</a>, before any
- call of <a href="#deflate">deflate</a>. The compressor and decompressor must use exactly the same
- dictionary (see <a href="#inflateSetDictionary">inflateSetDictionary</a>).<p>
-
- 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.<p>
-
- Depending on the size of the compression data structures selected by
- <a href="#deflateInit">deflateInit</a> or <a href="#deflateInit2">deflateInit2</a>, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- <a href="#deflate">deflate</a> or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front.<p>
-
- Upon return of this function, strm-&gt <a href="#adler">adler</a> 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.)<p>
-
- <a href="#deflateSetDictionary">deflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a
- parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is
- inconsistent (for example if <a href="#deflate">deflate</a> has already been called for this stream
- or if the compression method is bsort). <a href="#deflateSetDictionary">deflateSetDictionary</a> does not
- perform any compression: this will be done by <a href="#deflate">deflate</a>().<p>
-
-<font color="Blue"><dt> int <a name="deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source);</font>
-<dd>
- Sets the destination stream as a complete copy of the source stream.<p>
-
- 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 <a href="#deflateEnd">deflateEnd</a>. Note that <a href="#deflateCopy">deflateCopy</a> duplicates the internal
- compression <a href="#state">state</a> which can be quite large, so this strategy is slow and
- can consume lots of memory.<p>
-
- <a href="#deflateCopy">deflateCopy</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
- enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source stream <a href="#state">state</a> was inconsistent
- (such as <a href="#zalloc">zalloc</a> being NULL). <a href="#msg">msg</a> is left unchanged in both source and
- destination.<p>
-
-<font color="Blue"><dt> int <a name="deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd> This function is equivalent to <a href="#deflateEnd">deflateEnd</a> followed by <a href="#deflateInit">deflateInit</a>,
- but does not free and reallocate all the internal compression <a href="#state">state</a>.
- The stream will keep the same compression level and any other attributes
- that may have been set by <a href="#deflateInit2">deflateInit2</a>.<p>
-
- <a href="#deflateReset">deflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
- stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL).<p>
-
-<font color="Blue"><dt> int <a name="deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy);</font>
-<dd>
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in <a href="#deflateInit2">deflateInit2</a>. 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 <a href="#deflate">deflate</a>().<p>
-
- Before the call of <a href="#deflateParams">deflateParams</a>, the stream <a href="#state">state</a> must be set as for
- a call of <a href="#deflate">deflate</a>(), since the currently available input may have to
- be compressed and flushed. In particular, strm-&gt <a href="#avail_out">avail_out</a> must be
- non-zero.<p>
-
- <a href="#deflateParams">deflateParams</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
- stream <a href="#state">state</a> was inconsistent or if a parameter was invalid, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a>
- if strm-&gtavail_out was zero.<p>
-
-<font color="Blue"><dt> int <a name="inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits);</font>
-
-<dd> This is another version of <a href="#inflateInit">inflateInit</a> with an extra parameter. The
- fields <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized
- before by the caller.<p>
-
- 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 <a href="#inflateInit">inflateInit</a> is used
- instead. If a compressed stream with a larger window size is given as
- input, <a href="#inflate">inflate</a>() will return with the error code <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> instead of
- trying to allocate a larger window.<p>
-
- <a href="#inflateInit2">inflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
- memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as a negative
- memLevel). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#inflateInit2">inflateInit2</a>
- does not perform any decompression apart from reading the zlib header if
- present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> may be
- modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.)<p>
-
-<font color="Blue"><dt> int <a name="inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font>
-<dd>
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of <a href="#inflate">inflate</a>
- if this call returned <a href="#Z_NEED_DICT">Z_NEED_DICT</a>. The dictionary chosen by the compressor
- can be determined from the Adler32 value returned by this call of
- <a href="#inflate">inflate</a>. The compressor and decompressor must use exactly the same
- dictionary (see <a href="#deflateSetDictionary">deflateSetDictionary</a>).<p>
-
- <a href="#inflateSetDictionary">inflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a
- parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is
- inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the given dictionary doesn't match the
- expected one (incorrect Adler32 value). <a href="#inflateSetDictionary">inflateSetDictionary</a> does not
- perform any decompression: this will be done by subsequent calls of
- <a href="#inflate">inflate</a>().<p>
-
-<font color="Blue"><dt> int <a name="inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-
-<dd> Skips invalid compressed data until a full flush point (see above the
- description of <a href="#deflate">deflate</a> with <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>) can be found, or until all
- available input is skipped. No output is provided.<p>
-
- <a href="#inflateSync">inflateSync</a> returns <a href="#Z_OK">Z_OK</a> if a full flush point has been found, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a>
- if no more input was provided, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if no flush point has been found,
- or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent. In the success
- case, the application may save the current current value of <a href="#total_in">total_in</a> which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call <a href="#inflateSync">inflateSync</a>, providing more input each time,
- until success or end of the input data.<p>
-
-<font color="Blue"><dt> int <a name="inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
-<dd>
- This function is equivalent to <a href="#inflateEnd">inflateEnd</a> followed by <a href="#inflateInit">inflateInit</a>,
- but does not free and reallocate all the internal decompression <a href="#state">state</a>.
- The stream will keep attributes that may have been set by <a href="#inflateInit2">inflateInit2</a>.
- <p>
-
- <a href="#inflateReset">inflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
- stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL).
- <p>
-</dl>
-
-<hr>
-<a name="Checksum functions"><h2> Checksum functions </h2>
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-<h3> Function list </h3>
-<ul>
-<li> uLong <a href="#adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len);
-<li> uLong <a href="#crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len);
-</ul>
-<h3> Function description </h3>
-<dl>
-<font color="Blue"><dt> uLong <a name="adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len);</font>
-<dd>
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- <p>
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
- <pre>
-
- uLong <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(<a href="#adler">adler</a>, buffer, length);
- }
- if (<a href="#adler">adler</a> != original_adler) error();
- </pre>
-
-<font color="Blue"><dt> uLong <a name="crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len);</font>
-<dd>
- Update a running crc with the bytes buf[0..len-1] and return the updated
- crc. If buf is NULL, this function returns the required initial value
- 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:
- <pre>
-
- uLong crc = <a href="#crc32">crc32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = <a href="#crc32">crc32</a>(crc, buffer, length);
- }
- if (crc != original_crc) error();
- </pre>
-</dl>
-<hr>
-<a name="struct z_stream_s"><h2> struct z_stream_s </h2>
-<font color="Blue">
-<a name="z_stream_s">
-<pre>
-typedef struct z_stream_s {
- Bytef *<a name="next_in">next_in</a>; /* next input byte */
- uInt <a name="avail_in">avail_in</a>; /* number of bytes available at <a href="#next_in">next_in</a> */
- uLong <a name="total_in">total_in</a>; /* total nb of input bytes read so far */
-
- Bytef *<a name="next_out">next_out</a>; /* next output byte should be put there */
- uInt <a name="avail_out">avail_out</a>; /* remaining free space at <a href="#next_out">next_out</a> */
- uLong <a name="total_out">total_out</a>; /* total nb of bytes output so far */
-
- char *<a name="msg">msg</a>; /* last error message, NULL if no error */
- struct internal_state FAR *<a name="state">state</a>; /* not visible by applications */
-
- alloc_func <a name="zalloc">zalloc</a>; /* used to allocate the internal <a href="#state">state</a> */
- free_func <a name="zfree">zfree</a>; /* used to free the internal <a href="#state">state</a> */
- voidpf <a name="opaque">opaque</a>; /* private data object passed to <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> */
-
- int <a name="data_type">data_type</a>; /* best guess about the data type: ascii or binary */
- uLong <a name="adler">adler</a>; /* <a href="#adler32">adler32</a> value of the uncompressed data */
- uLong <a name="reserved">reserved</a>; /* <a href="#reserved">reserved</a> for future use */
-} <a href="#z_stream_s">z_stream</a> ;
-
-typedef <a href="#z_stream_s">z_stream</a> FAR * <a name="z_streamp">z_streamp</a>; ÿ
-</pre>
-</font>
- The application must update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> when <a href="#avail_in">avail_in</a> has
- dropped to zero. It must update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> when <a href="#avail_out">avail_out</a>
- has dropped to zero. The application must initialize <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and
- <a href="#opaque">opaque</a> before calling the init function. All other fields are set by the
- compression library and must not be updated by the application. <p>
-
- The <a href="#opaque">opaque</a> value provided by the application will be passed as the first
- parameter for calls of <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a>. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- <a href="#opaque">opaque</a> value. <p>
-
- <a href="#zalloc">zalloc</a> must return <a href="#Z_NULL">Z_NULL</a> if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> must be
- thread safe. <p>
-
- On 16-bit systems, the functions <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> 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 <a href="#zalloc">zalloc</a> 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).
- <p>
-
- The fields <a href="#total_in">total_in</a> and <a href="#total_out">total_out</a> can be used for statistics or
- progress reports. After compression, <a href="#total_in">total_in</a> 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). <p>
-
-<hr>
-<a name="Constants"><h2> Constants </h2>
-<font color="Blue">
-<pre>
-#define <a name="Z_NO_FLUSH">Z_NO_FLUSH</a> 0
-#define <a name="Z_PARTIAL_FLUSH">Z_PARTIAL_FLUSH</a> 1
- /* will be removed, use <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> instead */
-#define <a name="Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> 2
-#define <a name="Z_FULL_FLUSH">Z_FULL_FLUSH</a> 3
-#define <a name="Z_FINISH">Z_FINISH</a> 4
-/* Allowed flush values ; see <a href="#deflate">deflate</a>() below for details */
-
-#define <a name="Z_OK">Z_OK</a> 0
-#define <a name="Z_STREAM_END">Z_STREAM_END</a> 1
-#define <a name="Z_NEED_DICT">Z_NEED_DICT</a> 2
-#define <a name="Z_ERRNO">Z_ERRNO</a> (-1)
-#define <a name="Z_STREAM_ERROR">Z_STREAM_ERROR</a> (-2)
-#define <a name="Z_DATA_ERROR">Z_DATA_ERROR</a> (-3)
-#define <a name="Z_MEM_ERROR">Z_MEM_ERROR</a> (-4)
-#define <a name="Z_BUF_ERROR">Z_BUF_ERROR</a> (-5)
-#define <a name="Z_VERSION_ERROR">Z_VERSION_ERROR</a> (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define <a name="Z_NO_COMPRESSION">Z_NO_COMPRESSION</a> 0
-#define <a name="Z_BEST_SPEED">Z_BEST_SPEED</a> 1
-#define <a name="Z_BEST_COMPRESSION">Z_BEST_COMPRESSION</a> 9
-#define <a name="Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> (-1)
-/* compression levels */
-
-#define <a name="Z_FILTERED">Z_FILTERED</a> 1
-#define <a name="Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> 2
-#define <a name="Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> 0
-/* compression strategy ; see <a href="#deflateInit2">deflateInit2</a>() below for details */
-
-#define <a name="Z_BINARY">Z_BINARY</a> 0
-#define <a name="Z_ASCII">Z_ASCII</a> 1
-#define <a name="Z_UNKNOWN">Z_UNKNOWN</a> 2
-/* Possible values of the <a href="#data_type">data_type</a> field */
-
-#define <a name="Z_DEFLATED">Z_DEFLATED</a> 8
-/* The <a href="#deflate">deflate</a> compression method (the only one supported in this version) */
-
-#define <a name="Z_NULL">Z_NULL</a> 0 /* for initializing <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a>, <a href="#opaque">opaque</a> */
-
-#define <a name="zlib_version">zlib_version</a> <a href="#zlibVersion">zlibVersion</a>()
-/* for compatibility with versions less than 1.0.2 */
-</pre>
-</font>
-
-<hr>
-<a name="Misc"><h2> Misc </h2>
- <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a> are macros to allow checking the zlib version
- and the compiler's view of <a href="#z_stream_s">z_stream</a>.
- <p>
- Other functions:
- <dl>
- <font color="Blue"><dt> const char * <a name="zError">zError</a> (int err);</font>
- <font color="Blue"><dt> int <a name="inflateSyncPoint">inflateSyncPoint</a> (<a href="#z_streamp">z_streamp</a> z);</font>
- <font color="Blue"><dt> const uLongf * <a name="get_crc_table">get_crc_table</a> (void);</font>
- </dl>
- <hr>
- <font size="-1">
- Last update: Wed Oct 13 20:42:34 1999<br>
- piapi@csie.ntu.edu.tw
- </font>
-
-</body>
-</html>
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zmemory.c b/contrib/vmap_extractor_v2/stormlib/zlib/zmemory.c
deleted file mode 100644
index fc9749c5711..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/zmemory.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* zmemory.c
- Internal memory alloc and memory free functions
- */
-
-#include <malloc.h>
-
-#include "zlib.h"
-
-const char *z_errmsg[10]; // Needed by zlib
-
-voidpf zcalloc(voidpf opaque, uInt items, uInt size)
-{
- return (voidpf)calloc(items, size);
-}
-
-void zcfree(voidpf opaque, voidpf address)
-{
- free(address);
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zutil.c b/contrib/vmap_extractor_v2/stormlib/zlib/zutil.c
deleted file mode 100644
index 9a076221f2a..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/zutil.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* And'ing with mask[n] masks the lower n bits */
-uInt inflate_mask[17] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-int inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt n;
- Bytef *p;
- Bytef *q;
-
- /* local copies of source and destination pointers */
- p = z->next_out;
- q = s->read;
-
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy as far as end of window */
- zmemcpy(p, q, n);
- p += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* compute bytes to copy */
- n = (uInt)(s->write - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy */
- zmemcpy(p, q, n);
- p += n;
- q += n;
- }
-
- /* update pointers */
- z->next_out = p;
- s->read = q;
-
- /* done */
- return r;
-}
diff --git a/contrib/vmap_extractor_v2/stormlib/zlib/zutil.h b/contrib/vmap_extractor_v2/stormlib/zlib/zutil.h
deleted file mode 100644
index 718ebc15be1..00000000000
--- a/contrib/vmap_extractor_v2/stormlib/zlib/zutil.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#ifdef MSDOS
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-#endif
-
-#ifdef WIN32 /* Window 95 & Windows NT */
-# define OS_CODE 0x0b
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0F
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-# define fdopen(fd,type) _fdopen(fd,type)
-#endif
-
-
- /* Common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#ifdef HAVE_STRERROR
- extern char *strerror OF((int));
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
- uInt len));
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* _Z_UTIL_H */
diff --git a/contrib/vmap_extractor_v2/stormlibdll/DllMain.c b/contrib/vmap_extractor_v2/stormlibdll/DllMain.c
deleted file mode 100644
index cbfa84a08a8..00000000000
--- a/contrib/vmap_extractor_v2/stormlibdll/DllMain.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*****************************************************************************/
-/* DllMain.c Copyright (c) Ladislav Zezula 2006 */
-/*---------------------------------------------------------------------------*/
-/* Description: DllMain for the StormLib.dll library */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 23.11.06 1.00 Lad The first version of DllMain.c */
-/*****************************************************************************/
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-//-----------------------------------------------------------------------------
-// DllMain
-
-DWORD WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
-{
- UNREFERENCED_PARAMETER(hInst);
- UNREFERENCED_PARAMETER(dwReason);
- UNREFERENCED_PARAMETER(lpReserved);
-
- return TRUE;
-}
diff --git a/contrib/vmap_extractor_v2/stormlibdll/StormLib.def b/contrib/vmap_extractor_v2/stormlibdll/StormLib.def
deleted file mode 100644
index c220b6dcca4..00000000000
--- a/contrib/vmap_extractor_v2/stormlibdll/StormLib.def
+++ /dev/null
@@ -1,47 +0,0 @@
-LIBRARY StormLib.dll
-
-EXPORTS
-
- SFileSetLocale
- SFileGetLocale
- SFileOpenArchive
- SFileCloseArchive
-
- SFileOpenFileEx
- SFileCloseFile
- SFileGetFilePos
- SFileGetFileSize
- SFileSetFilePointer
- SFileReadFile
- SFileExtractFile
-
- SFileAddListFile
-
- SFileCreateArchiveEx
-
- SFileAddFile
- SFileAddWave
- SFileRemoveFile
- SFileRenameFile
- SFileSetFileLocale
-
- SFileHasFile
- SFileGetFileName
- SFileGetFileInfo
-
- SFileFindFirstFile
- SFileFindNextFile
- SFileFindClose
-
- SListFileFindFirstFile
- SListFileFindNextFile
- SListFileFindClose
-
- SFileSetCompactCallback
- SFileCompactArchive
-
- SFileEnumLocales
-
- SCompCompress
- SCompDecompress
- SCompSetDataCompression
diff --git a/contrib/vmap_extractor_v2/vmapextract/CMakeLists.txt b/contrib/vmap_extractor_v2/vmapextract/CMakeLists.txt
new file mode 100644
index 00000000000..51e867ec07e
--- /dev/null
+++ b/contrib/vmap_extractor_v2/vmapextract/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+cmake_minimum_required (VERSION 2.6)
+project (MANGOS_IOMAP_EXTRACTOR)
+
+LINK_DIRECTORIES( ${LINK_DIRECTORIES} ../../libmpq/libmpq/.libs/ )
+add_executable(vmapextractor adtfile.cpp dbcfile.cpp model.cpp mpq_libmpq.cpp vmapexport.cpp wdtfile.cpp wmo.cpp)
+target_link_libraries(vmapextractor mpq)
diff --git a/contrib/vmap_extractor_v2/vmapextract/adtfile.cpp b/contrib/vmap_extractor_v2/vmapextract/adtfile.cpp
index 49717c04748..055408edca6 100644
--- a/contrib/vmap_extractor_v2/vmapextract/adtfile.cpp
+++ b/contrib/vmap_extractor_v2/vmapextract/adtfile.cpp
@@ -1,6 +1,11 @@
#include "adtfile.h"
#include <algorithm>
+#include <cstdio>
+
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
char * GetPlainName(char * FileName)
{
@@ -23,6 +28,9 @@ void fixnamen(char *name, size_t len)
name[i] &= ~0x20;
}
}
+ //extension in lowercase
+ for(size_t i=len-3; i<len; i++)
+ name[i] |= 0x20;
}
void fixname2(char *name, size_t len)
@@ -39,12 +47,12 @@ ADTFile::ADTFile(char* filename): ADT(filename)
Adtfilename.append(filename);
}
-bool ADTFile::init(char *map_id)
+bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
{
if(ADT.isEof ())
return false;
- size_t size;
+ uint32 size;
string xMap;
string yMap;
@@ -56,17 +64,17 @@ bool ADTFile::init(char *map_id)
yMap = TempMapNumber.substr(TempMapNumber.find_last_of("_")+1,(TempMapNumber.length()) - (TempMapNumber.find_last_of("_")));
Adtfilename.erase((Adtfilename.length()-xMap.length()-yMap.length()-2), (xMap.length()+yMap.length()+2));
string AdtMapNumber = xMap + ' ' + yMap + ' ' + GetPlainName((char*)Adtfilename.c_str());
- printf("Processing map %s...\n", AdtMapNumber.c_str());
+ //printf("Processing map %s...\n", AdtMapNumber.c_str());
//printf("MapNumber = %s\n", TempMapNumber.c_str());
//printf("xMap = %s\n", xMap.c_str());
//printf("yMap = %s\n", yMap.c_str());
- const char dirname[] = "buildings\\dir";
+ const char dirname[] = "Buildings/dir_bin";
FILE *dirfile;
dirfile = fopen(dirname, "ab");
if(!dirfile)
{
- printf("Can't open dirfile!'%s'\n");
+ printf("Can't open dirfile!'%s'\n", dirname);
return false;
}
@@ -116,15 +124,14 @@ bool ADTFile::init(char *map_id)
// >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
// nothing do
- char szLocalFile[MAX_PATH];
- sprintf(szLocalFile, ".\\buildings\\%s", s);
+ char szLocalFile[1024];
+ snprintf(szLocalFile, 1024, "./Buildings/%s", s);
FILE * output = fopen(szLocalFile,"rb");
if(!output)
{
- Model * m2 = new Model(path);
- if(m2->open())
- m2->ConvertToVMAPModel(szLocalFile);
- delete m2;
+ Model m2(path);
+ if(m2.open())
+ m2.ConvertToVMAPModel(szLocalFile);
}
else
fclose(output);
@@ -161,9 +168,9 @@ bool ADTFile::init(char *map_id)
nMDX = (int)size / 36;
for (int i=0; i<nMDX; ++i)
{
- int id;
+ uint32 id;
ADT.read(&id, 4);
- ModelInstance inst(ADT,ModelInstansName[id].c_str(),map_id, dirfile);//!!!!!!!!!!!
+ ModelInstance inst(ADT,ModelInstansName[id].c_str(), map_num, tileX, tileY, dirfile);
}
delete[] ModelInstansName;
}
@@ -175,44 +182,14 @@ bool ADTFile::init(char *map_id)
nWMO = (int)size / 64;
for (int i=0; i<nWMO; ++i)
{
- int id;
+ uint32 id;
ADT.read(&id, 4);
- WMOInstance inst(ADT,WmoInstansName[id].c_str(),map_id, dirfile);//!!!!!!!!!!!!!
+ WMOInstance inst(ADT,WmoInstansName[id].c_str(), map_num, tileX, tileY, dirfile);
}
delete[] WmoInstansName;
}
}
//======================
-#if 0
- else if (!strcmp(fourcc,"MDDF"))
- {
- if (size)
- {
- nMDX = (int)size / 36;
- for (int i=0; i<nMDX; ++i)
- {
- int id;
- ADT.read(&id, 4);
- ModelInstance inst(ADT,ModelInstansName[id].c_str(),AdtMapNumber.c_str(), dirfile);
- }
- delete[] ModelInstansName;
- }
- }
- else if (!strcmp(fourcc,"MODF"))
- {
- if (size)
- {
- nWMO = (int)size / 64;
- for (int i=0; i<nWMO; ++i)
- {
- int id;
- ADT.read(&id, 4);
- WMOInstance inst(ADT,WmoInstansName[id].c_str(),AdtMapNumber.c_str(), dirfile);
- }
- delete[] WmoInstansName;
- }
- }
-#endif
ADT.seek(nextpos);
}
ADT.close();
diff --git a/contrib/vmap_extractor_v2/vmapextract/adtfile.h b/contrib/vmap_extractor_v2/vmapextract/adtfile.h
index 0ce5851ab79..eaf09a9243d 100644
--- a/contrib/vmap_extractor_v2/vmapextract/adtfile.h
+++ b/contrib/vmap_extractor_v2/vmapextract/adtfile.h
@@ -1,20 +1,14 @@
#ifndef ADT_H
#define ADT_H
-#include "mpq.h"
+#include "mpq_libmpq04.h"
#include "wmo.h"
#include "model.h"
-#define __STORMLIB_SELF__
-
#define TILESIZE (533.33333f)
#define CHUNKSIZE ((TILESIZE) / 16.0f)
#define UNITSIZE (CHUNKSIZE / 8.0f)
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-
class Liquid;
typedef struct
@@ -104,7 +98,7 @@ public:
int nMDX;
string* WmoInstansName;
string* ModelInstansName;
- bool init(char *map_id);
+ bool init(uint32 map_num, uint32 tileX, uint32 tileY);
//void LoadMapChunks();
//uint32 wmo_count;
diff --git a/contrib/vmap_extractor_v2/vmapextract/dbcfile.cpp b/contrib/vmap_extractor_v2/vmapextract/dbcfile.cpp
index 52eb18c42b7..8b8afe9f23c 100644
--- a/contrib/vmap_extractor_v2/vmapextract/dbcfile.cpp
+++ b/contrib/vmap_extractor_v2/vmapextract/dbcfile.cpp
@@ -1,7 +1,9 @@
#include "dbcfile.h"
-#include "mpq.h"
-#include "Stormlib.h"
-#define __STORMLIB_SELF__
+#include "mpq_libmpq04.h"
+#undef min
+#undef max
+
+#include <cstdio>
DBCFile::DBCFile(const std::string &filename) : filename(filename)
{
diff --git a/contrib/vmap_extractor_v2/vmapextract/dbcfile.h b/contrib/vmap_extractor_v2/vmapextract/dbcfile.h
index 002e7eeeb20..7381ab9f668 100644
--- a/contrib/vmap_extractor_v2/vmapextract/dbcfile.h
+++ b/contrib/vmap_extractor_v2/vmapextract/dbcfile.h
@@ -4,8 +4,10 @@
#include <cassert>
#include <string>
-#include "Stormlib.h"
+//#include "StormLib.h"
+#undef min
+#undef max
class DBCFile
{
public:
@@ -80,8 +82,8 @@ public:
}
private:
Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {}
- unsigned char *offset;
DBCFile &file;
+ unsigned char *offset;
friend class DBCFile;
friend class Iterator;
diff --git a/contrib/vmap_extractor_v2/vmapextract/loadlib/loadlib.h b/contrib/vmap_extractor_v2/vmapextract/loadlib/loadlib.h
new file mode 100644
index 00000000000..53731753425
--- /dev/null
+++ b/contrib/vmap_extractor_v2/vmapextract/loadlib/loadlib.h
@@ -0,0 +1,59 @@
+#ifndef LOAD_LIB_H
+#define LOAD_LIB_H
+
+#ifdef WIN32
+typedef __int64 int64;
+typedef __int32 int32;
+typedef __int16 int16;
+typedef __int8 int8;
+typedef unsigned __int64 uint64;
+typedef unsigned __int32 uint32;
+typedef unsigned __int16 uint16;
+typedef unsigned __int8 uint8;
+#else
+#include <stdint.h>
+#ifndef uint64_t
+#ifdef __linux__
+#include <linux/types.h>
+#endif
+#endif
+typedef int64_t int64;
+typedef int32_t int32;
+typedef int16_t int16;
+typedef int8_t int8;
+typedef uint64_t uint64;
+typedef uint32_t uint32;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
+#endif
+
+#define FILE_FORMAT_VERSION 18
+
+//
+// File version chunk
+//
+struct file_MVER
+{
+ union{
+ uint32 fcc;
+ char fcc_txt[4];
+ };
+ uint32 size;
+ uint32 ver;
+};
+
+class FileLoader{
+ uint8 *data;
+ uint32 data_size;
+public:
+ virtual bool prepareLoadedData();
+ uint8 *GetData() {return data;}
+ uint32 GetDataSize() {return data_size;}
+
+ file_MVER *version;
+ FileLoader();
+ ~FileLoader();
+ bool loadFile(char *filename, bool log = true);
+ virtual void free();
+};
+#endif
diff --git a/contrib/vmap_extractor_v2/vmapextract/model.cpp b/contrib/vmap_extractor_v2/vmapextract/model.cpp
index 9605e3320ab..b914ed96406 100644
--- a/contrib/vmap_extractor_v2/vmapextract/model.cpp
+++ b/contrib/vmap_extractor_v2/vmapextract/model.cpp
@@ -1,6 +1,10 @@
+#include "vmapexport.h"
#include "model.h"
+#include "wmo.h"
+#include "mpq_libmpq04.h"
#include <cassert>
#include <algorithm>
+#include <cstdio>
Model::Model(std::string &filename) : filename(filename)
{
@@ -35,8 +39,8 @@ bool Model::open()
indices = new uint16[header.nBoundingTriangles];
f.read(indices,header.nBoundingTriangles*2);
f.close();
- }
- else
+ }
+ else
{
//printf("not included %s\n", filename.c_str());
f.close();
@@ -47,20 +51,22 @@ bool Model::open()
bool Model::ConvertToVMAPModel(char * outfilename)
{
- int N[] = {0x00000000};
+ int N[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
FILE * output=fopen(outfilename,"wb");
if(!output)
{
printf("Can't create the output file '%s'\n",outfilename);
return false;
}
- fwrite("VMAP002",8,1,output);
+ fwrite("VMAP003",8,1,output);
uint32 nVertices = 0;
nVertices = header.nBoundingVertices;
fwrite(&nVertices, sizeof(int), 1, output);
uint32 nofgroups = 1;
fwrite(&nofgroups,sizeof(uint32), 1, output);
- fwrite(N,4,1,output);
+ fwrite(N,4*3,1,output);// rootwmoid, flags, groupid
+ fwrite(N,sizeof(float),3*2,output);//bbox, only needed for WMO currently
+ fwrite(N,4,1,output);// liquidflags
fwrite("GRP ",4,1,output);
uint32 branches = 1;
int wsize;
@@ -115,12 +121,12 @@ Vec3D fixCoordSystem2(Vec3D v)
return Vec3D(v.x, v.z, v.y);
}
-ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName,const char*MapName, FILE *pDirfile)
+ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile)
{
float ff[3];
- f.read(&d1, 4);
+ f.read(&id, 4);
f.read(ff,12);
- pos = Vec3D(ff[0],ff[1],ff[2]);
+ pos = fixCoords(Vec3D(ff[0],ff[1],ff[2]));
f.read(ff,12);
rot = Vec3D(ff[0],ff[1],ff[2]);
f.read(&scale,4);
@@ -128,12 +134,15 @@ ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName,const char*Map
sc = scale / 1024.0f;
char tempname[512];
- sprintf(tempname, ".\\buildings\\%s", ModelInstName);
+ sprintf(tempname, "./Buildings/%s", ModelInstName);
FILE *input;
input = fopen(tempname, "r+b");
if(!input)
+ {
+ //printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
return;
+ }
fseek(input, 8, SEEK_SET); // get the correct no of vertices
int nVertices;
@@ -143,22 +152,36 @@ ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName,const char*Map
if(nVertices == 0)
return;
- if(pDirfile)
- {
- int realx1 = (int) ((float) pos.x / 533.333333f);
- int realy1 = (int) ((float) pos.z / 533.333333f);
- int realx2 = (int) ((float) pos.x / 533.333333f);
- int realy2 = (int) ((float) pos.z / 533.333333f);
-
- fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
- MapName,
- ModelInstName,
- (float) pos.x, (float) pos.y, (float) pos.z,
- (float) rot.x, (float) rot.y, (float) rot.z,
- sc,
- nVertices,
- realx1, realy1,
- realx2, realy2
- );
- }
+ uint16 adtId = 0;// not used for models
+ uint32 flags = MOD_M2;
+ if(tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
+ //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name
+ fwrite(&mapID, sizeof(uint32), 1, pDirfile);
+ fwrite(&tileX, sizeof(uint32), 1, pDirfile);
+ fwrite(&tileY, sizeof(uint32), 1, pDirfile);
+ fwrite(&flags, sizeof(uint32), 1, pDirfile);
+ fwrite(&adtId, sizeof(uint16), 1, pDirfile);
+ fwrite(&id, sizeof(uint32), 1, pDirfile);
+ fwrite(&pos, sizeof(float), 3, pDirfile);
+ fwrite(&rot, sizeof(float), 3, pDirfile);
+ fwrite(&sc, sizeof(float), 1, pDirfile);
+ uint32 nlen=strlen(ModelInstName);
+ fwrite(&nlen, sizeof(uint32), 1, pDirfile);
+ fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
+
+ /* int realx1 = (int) ((float) pos.x / 533.333333f);
+ int realy1 = (int) ((float) pos.z / 533.333333f);
+ int realx2 = (int) ((float) pos.x / 533.333333f);
+ int realy2 = (int) ((float) pos.z / 533.333333f);
+
+ fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
+ MapName,
+ ModelInstName,
+ (float) pos.x, (float) pos.y, (float) pos.z,
+ (float) rot.x, (float) rot.y, (float) rot.z,
+ sc,
+ nVertices,
+ realx1, realy1,
+ realx2, realy2
+ ); */
}
diff --git a/contrib/vmap_extractor_v2/vmapextract/model.h b/contrib/vmap_extractor_v2/vmapextract/model.h
index 2bcb20b1172..d1be46f3c13 100644
--- a/contrib/vmap_extractor_v2/vmapextract/model.h
+++ b/contrib/vmap_extractor_v2/vmapextract/model.h
@@ -1,13 +1,15 @@
#ifndef MODEL_H
#define MODEL_H
+#include "loadlib/loadlib.h"
#include "vec3d.h"
-#include "mpq.h"
+//#include "mpq.h"
#include "modelheaders.h"
#include <vector>
class Model;
class WMOInstance;
+class MPQFile;
Vec3D fixCoordSystem(Vec3D v);
@@ -38,13 +40,13 @@ class ModelInstance
public:
Model *model;
- int id;
+ uint32 id;
Vec3D pos, rot;
unsigned int d1, scale;
float w,sc;
ModelInstance() {}
- ModelInstance(MPQFile &f,const char* ModelInstName,const char*MapName, FILE *pDirfile);
+ ModelInstance(MPQFile &f,const char* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile);
};
diff --git a/contrib/vmap_extractor_v2/vmapextract/modelheaders.h b/contrib/vmap_extractor_v2/vmapextract/modelheaders.h
index 445ab3843e1..776a981ebd8 100644
--- a/contrib/vmap_extractor_v2/vmapextract/modelheaders.h
+++ b/contrib/vmap_extractor_v2/vmapextract/modelheaders.h
@@ -1,12 +1,12 @@
#ifndef MODELHEADERS_H
#define MODELHEADERS_H
-typedef unsigned char uint8;
+/* typedef unsigned char uint8;
typedef char int8;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned int uint32;
-typedef int int32;
+typedef int int32; */
#pragma pack(push,1)
diff --git a/contrib/vmap_extractor_v2/vmapextract/mpq.cpp b/contrib/vmap_extractor_v2/vmapextract/mpq.cpp
deleted file mode 100644
index 0d72f06a7da..00000000000
--- a/contrib/vmap_extractor_v2/vmapextract/mpq.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-#include "mpq.h"
-//#include <vector>
-#include "Stormlib.h"
-#define __STORMLIB_SELF__
-
-MPQArchiveSet gOpenArchives;
-
-//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-MPQArchive::MPQArchive(const char* filename)
-{
- BOOL succ = SFileOpenArchive(filename, 0, 0,&hMPQ);
- if (succ)
- printf("Opening %s\n", filename);
- else
- printf("Error!!!Not open archive %s\n", filename);
-}
-
-void MPQArchive::close()
-{
- SFileCloseArchive(hMPQ);
-}
-
-bool MPQArchiveSet::Open( std::vector<std::string> const& archiveNames )
-{
- for (size_t i=0; i < archiveNames.size(); ++i)
- {
- MPQArchive mpqarch(archiveNames[i].c_str());
- if(mpqarch.isOpen())
- archives.push_back(mpqarch);
- }
-
- return !archives.empty();
-}
-
-MPQArchiveSet::~MPQArchiveSet()
-{
- // close archives
- for (ArchiveSet::iterator ar_itr = archives.begin(); ar_itr != archives.end(); ++ar_itr)
- ar_itr->close();
-}
-
-MPQFile::MPQFile(const char* filename):
- eof(false),
- buffer(0),
- pointer(0),
- size(0)
-{
- for(ArchiveSet::const_iterator i=gOpenArchives.archives.begin(); i!=gOpenArchives.archives.end();++i)
- {
- HANDLE hFile = "";
- hMPQ = i->hMPQ;
- BOOL succ = SFileOpenFileEx(hMPQ,filename,0, &hFile);
- if (succ)
- {
- DWORD s = SFileGetFileSize(hFile, 0);
- if (!s)
- {
- eof = true;
- buffer = 0;
- return;
- }
- size = (size_t)s;
- buffer = new char[s];
- SFileReadFile(hFile, buffer, s, 0, 0);
- SFileCloseFile(hFile);
-
- eof = false;
- return;
- }
- }
-
- eof = true;
- buffer = 0;
-}
-
-MPQFile::~MPQFile()
-{
- close();
-}
-
-size_t MPQFile::read(void* dest, size_t bytes)
-{
- if (eof)
- return 0;
-
- size_t rpos = pointer + bytes;
- if (rpos > size)
- {
- bytes = size - pointer;
- eof = true;
- }
-
- memcpy(dest, &(buffer[pointer]), bytes);
-
- pointer = rpos;
-
- return bytes;
-}
-
-bool MPQFile::isEof()
-{
- return eof;
-}
-
-void MPQFile::seek(int offset)
-{
- pointer = offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::seekRelative(int offset)
-{
- pointer += offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::close()
-{
- if (buffer)
- delete[] buffer;
- buffer = 0;
- eof = true;
-}
-
-size_t MPQFile::getSize()
-{
- return size;
-}
-
-size_t MPQFile::getPos()
-{
- return pointer;
-}
-
-char* MPQFile::getBuffer()
-{
- return buffer;
-}
-
-char* MPQFile::getPointer()
-{
- return buffer + pointer;
-}
diff --git a/contrib/vmap_extractor_v2/vmapextract/mpq.h b/contrib/vmap_extractor_v2/vmapextract/mpq.h
deleted file mode 100644
index 0d1d1485135..00000000000
--- a/contrib/vmap_extractor_v2/vmapextract/mpq.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#define _CRT_SECURE_NO_DEPRECATE
-
-#ifndef MPQ_H
-#define MPQ_H
-
-#define __STORMLIB_SELF__
-
-#include <string.h>
-#include <ctype.h>
-#include <vector>
-#include <iostream>
-#include "Stormlib.h"
-
-using namespace std;
-
-typedef unsigned int uint32;
-
-class MPQArchive
-{
- public:
- HANDLE hMPQ;
- MPQArchive(const char* filename);
- void close();
- bool isOpen() const { return hMPQ != 0; }
-};
-
-typedef std::vector<MPQArchive> ArchiveSet;
-
-class MPQArchiveSet
-{
- public:
- MPQArchiveSet() {}
- ~MPQArchiveSet();
-
- bool Open(std::vector<std::string> const& archiveNames);
-
- ArchiveSet archives;
-};
-
-extern MPQArchiveSet gOpenArchives;
-
-class MPQFile
-{
- HANDLE hFile;
- HANDLE hMPQ;
- bool eof;
- char *buffer;
- size_t pointer,
- size;
-
- // disable copying
- //MPQFile(const MPQFile &f) {}
- //void operator=(const MPQFile &f) {}
-
-public:
- MPQFile(const char* filename);
- ~MPQFile();
- size_t read(void* dest, size_t bytes);
- size_t getSize();
- size_t getPos();
- char* getBuffer();
- char* getPointer();
- bool isEof();
- void seek(int offset);
- void seekRelative(int offset);
- void close();
-};
-
-inline void flipcc(char *fcc)
-{
- char t;
- t=fcc[0];
- fcc[0]=fcc[3];
- fcc[3]=t;
- t=fcc[1];
- fcc[1]=fcc[2];
- fcc[2]=t;
-}
-
-#endif
diff --git a/contrib/vmap_extractor_v2/vmapextract/mpq_libmpq.cpp b/contrib/vmap_extractor_v2/vmapextract/mpq_libmpq.cpp
new file mode 100644
index 00000000000..4aa59417f81
--- /dev/null
+++ b/contrib/vmap_extractor_v2/vmapextract/mpq_libmpq.cpp
@@ -0,0 +1,111 @@
+#include "mpq_libmpq04.h"
+#include <deque>
+#include <cstdio>
+
+ArchiveSet gOpenArchives;
+
+MPQArchive::MPQArchive(const char* filename)
+{
+ int result = libmpq__archive_open(&mpq_a, filename, -1);
+ printf("Opening %s\n", filename);
+ if(result) {
+ switch(result) {
+ case LIBMPQ_ERROR_OPEN :
+ printf("Error opening archive '%s': Does file really exist?\n", filename);
+ break;
+ case LIBMPQ_ERROR_FORMAT : /* bad file format */
+ printf("Error opening archive '%s': Bad file format\n", filename);
+ break;
+ case LIBMPQ_ERROR_SEEK : /* seeking in file failed */
+ printf("Error opening archive '%s': Seeking in file failed\n", filename);
+ break;
+ case LIBMPQ_ERROR_READ : /* Read error in archive */
+ printf("Error opening archive '%s': Read error in archive\n", filename);
+ break;
+ case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */
+ printf("Error opening archive '%s': Maybe not enough memory\n", filename);
+ break;
+ default:
+ printf("Error opening archive '%s': Unknown error\n", filename);
+ break;
+ }
+ return;
+ }
+ gOpenArchives.push_front(this);
+}
+
+void MPQArchive::close()
+{
+ //gOpenArchives.erase(erase(&mpq_a);
+ libmpq__archive_close(mpq_a);
+}
+
+MPQFile::MPQFile(const char* filename):
+ eof(false),
+ buffer(0),
+ pointer(0),
+ size(0)
+{
+ for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
+ {
+ mpq_archive *mpq_a = (*i)->mpq_a;
+
+ uint32 filenum;
+ if(libmpq__file_number(mpq_a, filename, &filenum)) continue;
+ libmpq__off_t transferred;
+ libmpq__file_unpacked_size(mpq_a, filenum, &size);
+
+ // HACK: in patch.mpq some files don't want to open and give 1 for filesize
+ if (size<=1) {
+ printf("warning: file %s has size %d; cannot read.\n", filename, size);
+ eof = true;
+ buffer = 0;
+ return;
+ }
+ buffer = new char[size];
+
+ //libmpq_file_getdata
+ libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
+ /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
+ return;
+
+ }
+ eof = true;
+ buffer = 0;
+}
+
+size_t MPQFile::read(void* dest, size_t bytes)
+{
+ if (eof) return 0;
+
+ size_t rpos = pointer + bytes;
+ if (rpos > size) {
+ bytes = size - pointer;
+ eof = true;
+ }
+
+ memcpy(dest, &(buffer[pointer]), bytes);
+
+ pointer = rpos;
+
+ return bytes;
+}
+
+void MPQFile::seek(int offset)
+{
+ pointer = offset;
+ eof = (pointer >= size);
+}
+
+void MPQFile::seekRelative(int offset)
+{
+ pointer += offset;
+ eof = (pointer >= size);
+}
+
+void MPQFile::close()
+{
+ if (buffer) delete[] buffer;
+ buffer = 0;
+ eof = true;
+}
diff --git a/contrib/vmap_extractor_v2/vmapextract/mpq_libmpq04.h b/contrib/vmap_extractor_v2/vmapextract/mpq_libmpq04.h
new file mode 100644
index 00000000000..ccbfe37cba7
--- /dev/null
+++ b/contrib/vmap_extractor_v2/vmapextract/mpq_libmpq04.h
@@ -0,0 +1,91 @@
+#define _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_WARNINGS
+
+#ifndef MPQ_H
+#define MPQ_H
+
+#include "loadlib/loadlib.h"
+#include "libmpq/mpq.h"
+#include <string.h>
+#include <ctype.h>
+#include <vector>
+#include <iostream>
+#include <deque>
+
+using namespace std;
+
+class MPQArchive
+{
+
+public:
+ mpq_archive_s *mpq_a;
+
+ MPQArchive(const char* filename);
+ void close();
+
+ void GetFileListTo(vector<string>& filelist) {
+ uint32 filenum;
+ if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return;
+ libmpq__off_t size, transferred;
+ libmpq__file_unpacked_size(mpq_a, filenum, &size);
+
+ char *buffer = new char[size];
+
+ libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
+
+ char seps[] = "\n";
+ char *token;
+
+ token = strtok( buffer, seps );
+ uint32 counter = 0;
+ while ((token != NULL) && (counter < size)) {
+ //cout << token << endl;
+ token[strlen(token) - 1] = 0;
+ string s = token;
+ filelist.push_back(s);
+ counter += strlen(token) + 2;
+ token = strtok(NULL, seps);
+ }
+
+ delete[] buffer;
+ }
+};
+typedef std::deque<MPQArchive*> ArchiveSet;
+
+class MPQFile
+{
+ //MPQHANDLE handle;
+ bool eof;
+ char *buffer;
+ libmpq__off_t pointer,size;
+
+ // disable copying
+ MPQFile(const MPQFile &f) {}
+ void operator=(const MPQFile &f) {}
+
+public:
+ MPQFile(const char* filename); // filenames are not case sensitive
+ ~MPQFile() { close(); }
+ size_t read(void* dest, size_t bytes);
+ size_t getSize() { return size; }
+ size_t getPos() { return pointer; }
+ char* getBuffer() { return buffer; }
+ char* getPointer() { return buffer + pointer; }
+ bool isEof() { return eof; }
+ void seek(int offset);
+ void seekRelative(int offset);
+ void close();
+};
+
+inline void flipcc(char *fcc)
+{
+ char t;
+ t=fcc[0];
+ fcc[0]=fcc[3];
+ fcc[3]=t;
+ t=fcc[1];
+ fcc[1]=fcc[2];
+ fcc[2]=t;
+}
+
+#endif
diff --git a/contrib/vmap_extractor_v2/vmapextract/vec3d.h b/contrib/vmap_extractor_v2/vmapextract/vec3d.h
index 40513552181..d2569bc133b 100644
--- a/contrib/vmap_extractor_v2/vmapextract/vec3d.h
+++ b/contrib/vmap_extractor_v2/vmapextract/vec3d.h
@@ -106,6 +106,12 @@ public:
in >> v.x >> v.y >> v.z;
return in;
}
+
+ friend std::ostream& operator<<(std::ostream& out, const Vec3D& v)
+ {
+ out << v.x << " " << v.y << " " << v.z;
+ return out;
+ }
operator float*()
{
diff --git a/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp b/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp
index a96a404f62d..07d5d31d418 100644
--- a/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp
+++ b/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp
@@ -12,27 +12,35 @@
/*****************************************************************************/
#define _CRT_SECURE_NO_DEPRECATE
-#include <io.h>
-#include <conio.h>
-#include <stdio.h>
-#include <windows.h>
-#include <mmsystem.h>
+#include <cstdio>
+#include <iostream>
#include <vector>
#include <list>
+#include <errno.h>
+#ifdef WIN32
+ #include <Windows.h>
+ #include <sys/stat.h>
+ #include <direct.h>
+ #define mkdir _mkdir
+#else
+ #include <sys/stat.h>
+#endif
+
+#undef min
+#undef max
-#define __STORMLIB_SELF__ // Don't use StormLib.lib
-#include "StormLib.h"
+//#pragma warning(disable : 4505)
+//#pragma comment(lib, "Winmm.lib")
-#pragma warning(disable : 4505)
-#pragma comment(lib, "Winmm.lib")
+#include <map>
//From Extractor
#include "adtfile.h"
#include "wdtfile.h"
#include "dbcfile.h"
-#include "mpq.h"
#include "wmo.h"
+#include "mpq_libmpq04.h"
//------------------------------------------------------------------------------
// Defines
@@ -40,10 +48,9 @@
#define MPQ_BLOCK_SIZE 0x1000
//-----------------------------------------------------------------------------
-// from extractor
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint32;
+
+extern ArchiveSet gOpenArchives;
+
typedef struct
{
char name[64];
@@ -51,26 +58,17 @@ typedef struct
}map_id;
map_id * map_ids;
-uint16 * areas;
-uint16 *areamax;
+uint16 *LiqType = 0;
uint32 map_count;
char output_path[128]=".";
char input_path[1024]=".";
bool hasInputPathParam = false;
-char tmp[512];
bool preciseVectorData = false;
-//char gamepath[1024];
-
-//Convert function
-//bool ConvertADT(char*,char*);
// Constants
//static const char * szWorkDirMaps = ".\\Maps";
-static const char * szWorkDirWmo = ".\\buildings";
-
-//static LPBYTE pbBuffer1 = NULL;
-//static LPBYTE pbBuffer2 = NULL;
+static const char * szWorkDirWmo = "./Buildings";
// Local testing functions
@@ -79,6 +77,15 @@ static void clreol()
printf("\r \r");
}
+void strToLower(char* str)
+{
+ while(*str)
+ {
+ *str=tolower(*str);
+ ++str;
+ }
+}
+
static const char * GetPlainName(const char * szFileName)
{
const char * szTemp;
@@ -88,56 +95,55 @@ static const char * GetPlainName(const char * szFileName)
return szFileName;
}
-static void ShowProcessedFile(const char * szFileName)
+// copied from contrib/extractor/System.cpp
+void ReadLiquidTypeTableDBC()
{
-/* not truncate file names in output
- char szLine[80];
- size_t nLength = strlen(szFileName);
-
- memset(szLine, 0x20, sizeof(szLine));
- szLine[sizeof(szLine)-1] = 0;
-
- if(nLength > sizeof(szLine)-1)
- nLength = sizeof(szLine)-1;
- memcpy(szLine, szFileName, nLength);
- printf("\r%s\n", szLine);
-*/
- printf("\r%s\n", szFileName);
+ printf("Read LiquidType.dbc file...");
+ DBCFile dbc("DBFilesClient\\LiquidType.dbc");
+ if(!dbc.open())
+ {
+ printf("Fatal error: Invalid LiquidType.dbc file format!\n");
+ exit(1);
+ }
+
+ size_t LiqType_count = dbc.getRecordCount();
+ size_t LiqType_maxid = dbc.getRecord(LiqType_count - 1).getUInt(0);
+ LiqType = new uint16[LiqType_maxid + 1];
+ memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16));
+
+ for(uint32 x = 0; x < LiqType_count; ++x)
+ LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
+
+ printf("Done! (%u LiqTypes loaded)\n", LiqType_count);
}
int ExtractWmo()
{
- char* szListFile = "";
- char szLocalFile[MAX_PATH] = "";
- BOOL bResult = FALSE;
+ char szLocalFile[1024] = "";
+ bool success=true;
//const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"};
- int nError = ERROR_SUCCESS;
- if(szListFile == NULL || *szListFile == 0)
- szListFile = NULL;
-
- for (ArchiveSet::const_iterator ar_itr = gOpenArchives.archives.begin(); ar_itr != gOpenArchives.archives.end(); ++ar_itr)
+ for (ArchiveSet::const_iterator ar_itr = gOpenArchives.begin(); ar_itr != gOpenArchives.end() && success; ++ar_itr)
{
- // Copy files from archive
- if(nError == ERROR_SUCCESS)
- {
- SFILE_FIND_DATA wf;
- HANDLE hFind = SFileFindFirstFile(ar_itr->hMPQ,"*.wmo*", &wf, szListFile);
- bResult = TRUE;
+ vector<string> filelist;
- while(hFind != NULL && bResult == TRUE)
+ (*ar_itr)->GetFileListTo(filelist);
+ for (vector<string>::iterator fname=filelist.begin(); fname != filelist.end() && success; ++fname)
+ {
+ bool file_ok=true;
+ if (fname->find(".wmo") != string::npos)
{
- ShowProcessedFile(wf.cFileName);
- SFileSetLocale(wf.lcLocale);
- sprintf(szLocalFile, "%s\\%s", szWorkDirWmo, GetPlainName(wf.cFileName));
+ // Copy files from archive
+ //std::cout << "found *.wmo file " << *fname << std::endl;
+ sprintf(szLocalFile, "%s/%s", szWorkDirWmo, GetPlainName(fname->c_str()));
fixnamen(szLocalFile,strlen(szLocalFile));
FILE * n;
if ((n = fopen(szLocalFile, "rb"))== NULL)
{
int p = 0;
//Select root wmo files
- const char * rchr = strrchr(GetPlainName(wf.cFileName),0x5f);
+ const char * rchr = strrchr(GetPlainName(fname->c_str()),0x5f);
if(rchr != NULL)
{
char cpy[4];
@@ -151,67 +157,67 @@ int ExtractWmo()
}
if(p != 3)
{
- //printf("RootWmo!\n");
- string s = wf.cFileName;
- WMORoot * froot = new WMORoot(s);
+ std::cout << "Extracting " << *fname << std::endl;
+ WMORoot * froot = new WMORoot(*fname);
if(!froot->open())
{
- printf("Not open RootWmo!!!\n");
- bResult = SFileFindNextFile(hFind, &wf);
+ printf("Couldn't open RootWmo!!!\n");
+ delete froot;
continue;
}
FILE *output=fopen(szLocalFile,"wb");
+ if(!output)
+ {
+ printf("couldn't open %s for writing!\n", szLocalFile);
+ success=false;
+ }
froot->ConvertToVMAPRootWmo(output);
int Wmo_nVertices = 0;
+ //printf("root has %d groups\n", froot->nGroups);
if(froot->nGroups !=0)
{
- for (int i=0; i<froot->nGroups; ++i)
+ for (uint32 i=0; i<froot->nGroups; ++i)
{
- char temp[MAX_PATH];
- strcpy(temp, wf.cFileName);
- temp[strlen(wf.cFileName)-4] = 0;
- char groupFileName[MAX_PATH];
+ char temp[1024];
+ strcpy(temp, fname->c_str());
+ temp[fname->length()-4] = 0;
+ char groupFileName[1024];
sprintf(groupFileName,"%s_%03d.wmo",temp, i);
- printf("%s\n",groupFileName);
- //printf("GroupWmo!\n");
+ //printf("Trying to open groupfile %s\n",groupFileName);
string s = groupFileName;
WMOGroup * fgroup = new WMOGroup(s);
if(!fgroup->open())
{
- printf("Not all open Group file for: %s\n",GetPlainName(wf.cFileName));
- bResult = SFileFindNextFile(hFind, &wf);
+ printf("Could not open all Group file for: %s\n",GetPlainName(fname->c_str()));
+ file_ok=false;
break;
}
- Wmo_nVertices += fgroup->ConvertToVMAPGroupWmo(output, preciseVectorData);
+
+ Wmo_nVertices += fgroup->ConvertToVMAPGroupWmo(output, froot, preciseVectorData);
+ delete fgroup;
}
}
fseek(output, 8, SEEK_SET); // store the correct no of vertices
fwrite(&Wmo_nVertices,sizeof(int),1,output);
fclose(output);
+ delete froot;
}
}
else
{
fclose(n);
}
- wf.dwFileFlags &= ~MPQ_FILE_HAS_EXTRA;
- wf.dwFileFlags &= ~MPQ_FILE_EXISTS;
- // Find the next file
- bResult = SFileFindNextFile(hFind, &wf);
}
// Delete the extracted file in the case of an error
- if(nError != ERROR_SUCCESS)
- DeleteFile(szLocalFile);
- // Close the search handle
- if(hFind != NULL)
- SFileFindClose(hFind);
+ if(!file_ok)
+ remove(szLocalFile);
}
}
- if(nError == ERROR_SUCCESS)
- printf("\nExtract wmo complete (No errors)\n");
+ if(success)
+ printf("\nExtract wmo complete (No (fatal) errors)\n");
- return nError;
+ return success;
}
void ExtractMapsFromMpq()
@@ -221,39 +227,14 @@ void ExtractMapsFromMpq()
void ParsMapFiles()
{
char fn[512];
- char id_filename[64];
+ //char id_filename[64];
char id[10];
for (unsigned int i=0; i<map_count; ++i)
{
sprintf(id,"%03u",map_ids[i].id);
sprintf(fn,"World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
WDTFile WDT(fn,map_ids[i].name);
- if(WDT.init(id))
- {
- for (int x=0; x<64; ++x)
- {
- for (int y=0; y<64; ++y)
- {
- if (ADTFile*ADT = WDT.GetMap(x,y))
- {
- sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!!
- ADT->init(id_filename);
- delete ADT;
- }
- }
- }
- }
- }
-}
-#if 0
-void ParsMapFiles()
-{
- char fn[512];
- for (unsigned int i=0; i<map_count; ++i)
- {
- sprintf(fn,"World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
- WDTFile WDT(fn,map_ids[i].name);
- if(WDT.init())
+ if(WDT.init(id, map_ids[i].id))
{
for (int x=0; x<64; ++x)
{
@@ -261,7 +242,8 @@ void ParsMapFiles()
{
if (ADTFile*ADT = WDT.GetMap(x,y))
{
- ADT->init();
+ //sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!!
+ ADT->init(map_ids[i].id, x, y);
delete ADT;
}
}
@@ -269,7 +251,6 @@ void ParsMapFiles()
}
}
}
-#endif
void getGamePath()
{
@@ -289,7 +270,7 @@ void getGamePath()
}
strcat(input_path,"Data\\");
#else
- strcpy(input_path,"data/");
+ strcpy(input_path,"Data/");
#endif
}
@@ -297,38 +278,29 @@ bool scan_patches(char* scanmatch, std::vector<std::string>& pArchiveNames)
{
int i;
char path[512];
- std::list<std::string> matches;
-
- WIN32_FIND_DATA ffData;
- HANDLE hFind;
for (i = 1; i <= 99; i++)
{
if (i != 1)
{
- sprintf(path, "%s-%d.mpq", scanmatch, i);
+ sprintf(path, "%s-%d.MPQ", scanmatch, i);
}
else
{
- sprintf(path, "%s.mpq", scanmatch);
+ sprintf(path, "%s.MPQ", scanmatch);
+ }
+#ifdef __linux__
+ if(FILE* h = fopen64(path, "rb"))
+#else
+ if(FILE* h = fopen(path, "rb"))
+#endif
+ {
+ fclose(h);
+ //matches.push_back(path);
+ pArchiveNames.push_back(path);
}
-
- hFind = INVALID_HANDLE_VALUE;
- hFind = FindFirstFile(path, &ffData);
- if (hFind == INVALID_HANDLE_VALUE) break;
- FindClose(hFind);
-
- matches.push_back(path);
- }
-
- matches.reverse();
- for (std::list<std::string>::iterator i = matches.begin(); i != matches.end(); ++i)
- {
- pArchiveNames.push_back(i->c_str());
}
- printf("\n");
-
return(true);
}
@@ -340,96 +312,75 @@ bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames)
printf("\nGame path: %s\n", input_path);
char path[512];
- std::vector<std::string> locales;
-
- // scan game directories
- WIN32_FIND_DATA ffData;
- HANDLE hFind;
- DWORD dwError;
-
- // first, scan for locales (4-letter directories)
- printf("Scanning for locales.\n");
- sprintf(path, "%s*.*", input_path);
- hFind = INVALID_HANDLE_VALUE;
- hFind = FindFirstFile(path, &ffData);
- if (hFind == INVALID_HANDLE_VALUE)
+ string in_path(input_path);
+ std::vector<std::string> locales, searchLocales;
+
+ searchLocales.push_back("enGB");
+ searchLocales.push_back("enUS");
+ searchLocales.push_back("deDE");
+ searchLocales.push_back("esES");
+ searchLocales.push_back("frFR");
+ searchLocales.push_back("koKR");
+ searchLocales.push_back("ruRU");
+
+ for (std::vector<std::string>::iterator i = searchLocales.begin(); i != searchLocales.end(); ++i)
{
- printf("\nCould not open data directory for reading. Aborting.\n");
- return(false);
- }
- do
- {
- if (ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- if (ffData.cFileName[0] != '.')
- {
- if (strlen(ffData.cFileName) == 4)
- {
- printf("Found locale: %s\n", ffData.cFileName);
- locales.push_back(ffData.cFileName);
- }
- }
- }
- } while (FindNextFile(hFind, &ffData) != 0);
- dwError = GetLastError();
- FindClose(hFind);
- if (dwError != ERROR_NO_MORE_FILES)
- {
- printf("\nError reading data directory while scanning locales. Aborting.\n");
- return(false);
+ std::string localePath = in_path + *i;
+ // check if locale exists:
+ struct stat status;
+ if (stat(localePath.c_str(), &status))
+ continue;
+ if ((status.st_mode & S_IFDIR) == 0)
+ continue;
+ printf("Found locale '%s'\n", i->c_str());
+ locales.push_back(*i);
}
printf("\n");
- if (locales.size() == 0)
+ // open locale expansion and common files
+ printf("Adding data files from locale directories.\n");
+ for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
{
- printf("Sorry, no locales found. Aborting.\n");
- return(false);
+ pArchiveNames.push_back(in_path + *i + "/locale-" + *i + ".MPQ");
+ pArchiveNames.push_back(in_path + *i + "/expansion-locale-" + *i + ".MPQ");
+ pArchiveNames.push_back(in_path + *i + "/lichking-locale-" + *i + ".MPQ");
}
+ // open expansion and common files
+ pArchiveNames.push_back(input_path + string("common.MPQ"));
+ pArchiveNames.push_back(input_path + string("common-2.MPQ"));
+ pArchiveNames.push_back(input_path + string("expansion.MPQ"));
+ pArchiveNames.push_back(input_path + string("lichking.MPQ"));
+
// now, scan for the patch levels in the core dir
- printf("Loading patch levels from data directory.\n");
+ printf("Scanning patch levels from data directory.\n");
sprintf(path, "%spatch", input_path);
if (!scan_patches(path, pArchiveNames))
return(false);
// now, scan for the patch levels in locale dirs
- printf("Loading patch levels from locale directories.\n");
+ printf("Scanning patch levels from locale directories.\n");
+ bool foundOne = false;
for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
{
printf("Locale: %s\n", i->c_str());
- sprintf(path, "%s%s\\patch-%s", input_path, i->c_str(), i->c_str());
- if (!scan_patches(path, pArchiveNames)) return(false);
+ sprintf(path, "%s%s/patch-%s", input_path, i->c_str(), i->c_str());
+ if(scan_patches(path, pArchiveNames))
+ foundOne = true;
}
- // open expansion and common files
- printf("Opening data files from data directory.\n");
- sprintf(path, "%slichking.mpq", input_path);
- pArchiveNames.push_back(path);
- sprintf(path, "%scommon-2.mpq", input_path);
- pArchiveNames.push_back(path);
- sprintf(path, "%sexpansion.mpq", input_path);
- pArchiveNames.push_back(path);
- sprintf(path, "%scommon.mpq", input_path);
- pArchiveNames.push_back(path);
printf("\n");
- // open locale expansion and common files
- printf("Opening data files from locale directories.\n");
- for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
+ if(!foundOne)
{
- printf("Locale: %s\n", i->c_str());
- sprintf(path, "%s%s\\lichking-locale-%s.mpq", input_path, i->c_str(), i->c_str());
- pArchiveNames.push_back(path);
- sprintf(path, "%s%s\\expansion-locale-%s.mpq", input_path, i->c_str(), i->c_str());
- pArchiveNames.push_back(path);
- sprintf(path, "%s%s\\locale-%s.mpq", input_path, i->c_str(), i->c_str());
- pArchiveNames.push_back(path);
- printf("\n");
+ printf("no locale found\n");
+ return false;
}
+
return true;
}
-bool processArgv(int argc, char ** argv, char*versionString)
+bool processArgv(int argc, char ** argv, const char *versionString)
{
bool result = true;
hasInputPathParam = false;
@@ -448,7 +399,7 @@ bool processArgv(int argc, char ** argv, char*versionString)
hasInputPathParam = true;
strcpy(input_path, argv[i+1]);
if (input_path[strlen(input_path) - 1] != '\\' || input_path[strlen(input_path) - 1] != '/')
- strcat(input_path, "\\");
+ strcat(input_path, "/");
++i;
}
else
@@ -484,7 +435,7 @@ bool processArgv(int argc, char ** argv, char*versionString)
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Main
-//
+//
// The program must be run with two command line arguments
//
// Arg1 - The source MPQ name (for testing reading and file find)
@@ -493,52 +444,47 @@ bool processArgv(int argc, char ** argv, char*versionString)
int main(int argc, char ** argv)
{
- //char tmp[512];
-// FILE* pDatei;
-// char tmp[512];
-// char tmp1[512];
- //char tmp2[512];
-// char tmp3[512];
-// char tmp4[512];
-// char szMpqName[MAX_PATH] = "";
-// char szListFile[MAX_PATH] = "";
- int nError = ERROR_SUCCESS;
- char *versionString = "V2.4 2007_07_12";
+ bool success=true;
+ const char *versionString = "V2.90 2010_05";
// Use command line arguments, when some
if(!processArgv(argc, argv, versionString))
return 1;
printf("Extract %s. Beginning work ....\n",versionString);
- // Set the lowest priority to allow running in the background
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Create the working directory
- if(nError == ERROR_SUCCESS)
- {
- //if(!CreateDirectory(szWorkDirMaps, NULL))
- // nError = GetLastError();
- if(!CreateDirectory(szWorkDirWmo, NULL))
- nError = GetLastError();
- if(nError == ERROR_ALREADY_EXISTS)
- nError = ERROR_SUCCESS;
- }
+ if(mkdir(szWorkDirWmo
+#ifdef __linux__
+ , 0711
+#endif
+ ))
+ success = (errno == EEXIST);
// prepare archive name list
std::vector<std::string> archiveNames;
fillArchiveNameVector(archiveNames);
- if(!gOpenArchives.Open(archiveNames))
+ for (size_t i=0; i < archiveNames.size(); ++i)
+ {
+ MPQArchive *archive = new MPQArchive(archiveNames[i].c_str());
+ if(!gOpenArchives.size() || gOpenArchives.front() != archive)
+ delete archive;
+ }
+
+ if(gOpenArchives.empty())
{
printf("FATAL ERROR: None MPQ archive found by path '%s'. Use -d option with proper path.\n",input_path);
return 1;
}
+ ReadLiquidTypeTableDBC();
// extract data
- ExtractWmo();
+ if(success)
+ success = ExtractWmo();
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//map.dbc
- if(nError == ERROR_SUCCESS)
+ if(success)
{
DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc");
if(!dbc->open())
@@ -556,18 +502,21 @@ int main(int argc, char ** argv)
printf("Map - %s\n",map_ids[x].name);
}
+
delete dbc;
ParsMapFiles();
delete [] map_ids;
- nError = ERROR_SUCCESS;
+ //nError = ERROR_SUCCESS;
}
clreol();
- if(nError != ERROR_SUCCESS)
+ if(!success)
{
printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData);
- _getch();
+ getchar();
}
- printf("Extract %s. Work complete. No errors.",versionString);
+ printf("Extract %s. Work complete. No errors.\n",versionString);
+ delete [] LiqType;
+ return 0;
}
diff --git a/contrib/vmap_extractor_v2/vmapextract/vmapexport.h b/contrib/vmap_extractor_v2/vmapextract/vmapexport.h
new file mode 100644
index 00000000000..625bc930882
--- /dev/null
+++ b/contrib/vmap_extractor_v2/vmapextract/vmapexport.h
@@ -0,0 +1,11 @@
+#ifndef VMAPEXPORT_H
+#define VMAPEXPORT_H
+
+enum ModelFlags
+{
+ MOD_M2 = 1,
+ MOD_WORLDSPAWN = 1<<1,
+ MOD_HAS_BOUND = 1<<2
+};
+
+#endif
diff --git a/contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp b/contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp
index 697f9b33b5b..7f81af72931 100644
--- a/contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp
+++ b/contrib/vmap_extractor_v2/vmapextract/wdtfile.cpp
@@ -2,6 +2,7 @@
#include "wdtfile.h"
#include "adtfile.h"
+#include <cstdio>
char * wdtGetPlainName(char * FileName)
{
@@ -17,7 +18,7 @@ WDTFile::WDTFile(char* file_name, char* file_name1):WDT(file_name)
filename.append(file_name1,strlen(file_name1));
}
-bool WDTFile::init(char *map_id)
+bool WDTFile::init(char *map_id, unsigned int mapID)
{
if (WDT.isEof())
{
@@ -26,14 +27,14 @@ bool WDTFile::init(char *map_id)
}
char fourcc[5];
- size_t size;
+ uint32 size;
- const char dirname[] = "buildings\\dir";
+ const char dirname[] = "Buildings/dir_bin";
FILE *dirfile;
dirfile = fopen(dirname, "ab");
if(!dirfile)
{
- printf("Can't open dirfile!'%s'\n");
+ printf("Can't open dirfile!'%s'\n", dirname);
return false;
}
@@ -86,7 +87,7 @@ bool WDTFile::init(char *map_id)
{
int id;
WDT.read(&id, 4);
- WMOInstance inst(WDT,gWmoInstansName[id].c_str(),gWMO_mapname.c_str(), dirfile);
+ WMOInstance inst(WDT,gWmoInstansName[id].c_str(),mapID, 65, 65, dirfile);
}
delete[] gWmoInstansName;
}
diff --git a/contrib/vmap_extractor_v2/vmapextract/wdtfile.h b/contrib/vmap_extractor_v2/vmapextract/wdtfile.h
index 0baef22f185..f3d71c41791 100644
--- a/contrib/vmap_extractor_v2/vmapextract/wdtfile.h
+++ b/contrib/vmap_extractor_v2/vmapextract/wdtfile.h
@@ -1,20 +1,19 @@
#ifndef WDTFILE_H
#define WDTFILE_H
-#define __STORMLIB_SELF__
-
-#include "mpq.h"
-#include "adtfile.h"
+#include "mpq_libmpq04.h"
#include "wmo.h"
#include <string>
#include "stdlib.h"
+class ADTFile;
+
class WDTFile
{
public:
WDTFile(char* file_name, char* file_name1);
~WDTFile(void);
- bool init(char *map_id);
+ bool init(char *map_id, unsigned int mapID);
string* gWmoInstansName;
int gnWMO, nMaps;
diff --git a/contrib/vmap_extractor_v2/vmapextract/wmo.cpp b/contrib/vmap_extractor_v2/vmapextract/wmo.cpp
index 4817e14c85b..508391be675 100644
--- a/contrib/vmap_extractor_v2/vmapextract/wmo.cpp
+++ b/contrib/vmap_extractor_v2/vmapextract/wmo.cpp
@@ -1,10 +1,18 @@
-#define __STORMLIB_SELF__
+#include "vmapexport.h"
#include "wmo.h"
-#include "Stormlib.h"
-#include "mpq.h"
+#include "vec3d.h"
+#include <cstdio>
+#include <cstdlib>
+#include <cassert>
+#include <map>
+#include <fstream>
+#undef min
+#undef max
+#include "mpq_libmpq04.h"
using namespace std;
+extern uint16 *LiqType;
WMORoot::WMORoot(std::string &filename) : filename(filename)
{
@@ -19,10 +27,8 @@ bool WMORoot::open()
return false;
}
- size_t size;
+ uint32 size;
char fourcc[5];
- bbcorn1[3] = 0;
- bbcorn2[3]= 0;
while (!f.isEof())
{
@@ -44,9 +50,10 @@ bool WMORoot::open()
f.read(&nDoodads, 4);
f.read(&nDoodadSets, 4);
f.read(&col, 4);
- f.read(&RootID, 4);
+ f.read(&RootWMOID, 4);
f.read(bbcorn1,12);
f.read(bbcorn2,12);
+ f.read(&liquidType, 4);
break;
}
/*
@@ -100,10 +107,11 @@ bool WMORoot::ConvertToVMAPRootWmo(FILE *pOutfile)
{
//printf("Convert RootWmo...\n");
- fwrite("VMAP002",1,8,pOutfile);
+ fwrite("VMAP003",1,8,pOutfile);
unsigned int nVectors = 0;
fwrite(&nVectors,sizeof(nVectors),1,pOutfile); // will be filled later
fwrite(&nGroups,4,1,pOutfile);
+ fwrite(&RootWMOID,4,1,pOutfile);
return true;
}
@@ -111,7 +119,8 @@ WMORoot::~WMORoot()
{
}
-WMOGroup::WMOGroup(std::string &filename) : filename(filename)
+WMOGroup::WMOGroup(std::string &filename) : filename(filename),
+ MOPY(0), MOVI(0), MoviEx(0), MOVT(0), MOBA(0), MobaEx(0), hlq(0), LiquEx(0), LiquBytes(0)
{
}
@@ -123,10 +132,8 @@ bool WMOGroup::open()
printf("No such file.\n");
return false;
}
- size_t size;
+ uint32 size;
char fourcc[5];
- bbcorn1[3] = 0;
- bbcorn2[3] = 0;
while (!f.isEof())
{
f.read(fourcc,4);
@@ -143,19 +150,20 @@ bool WMOGroup::open()
if (!strcmp(fourcc,"MOGP"))//header
{
- f.seekRelative(-4);
- f.read(&offsize, 4);
- f.read(&flag, 4);
- f.read(&flag1, 4);
- f.read(&Xid, 4);
+ f.read(&groupName, 4);
+ f.read(&descGroupName, 4);
+ f.read(&mogpFlags, 4);
f.read(bbcorn1, 12);
f.read(bbcorn2, 12);
- f.read(&Xid2, 4);
- f.read(&Xid3, 4);
- f.read(&zero1, 4);
- f.read(&Xflag, 4);
- f.read(&nTexture,4);
- f.read(&GroupID,4);
+ f.read(&moprIdx, 2);
+ f.read(&moprNItems, 2);
+ f.read(&nBatchA, 2);
+ f.read(&nBatchB, 2);
+ f.read(&nBatchC, 4);
+ f.read(&fogIdx, 4);
+ f.read(&liquidType, 4);
+ f.read(&groupWMOID,4);
+
}
else if (!strcmp(fourcc,"MOPY"))
{
@@ -190,26 +198,21 @@ bool WMOGroup::open()
else if (!strcmp(fourcc,"MLIQ"))
{
liquflags |= 1;
- WMOLiquidHeader hlq;
- f.read(&hlq, 0x1E);
- float ydir = -1.0f;
- hlq_xverts = hlq.xverts;
- hlq_yverts = hlq.yverts;
- int noVer = hlq.xverts * hlq.yverts;
- float tilesize = CHUNKSIZE / 8.0f;
- LiquEx_size = sizeof(float) * 3 * noVer;
- LiquEx = new float[sizeof(float) * 3 * noVer];
- int p = 0;
-
- for (int j=0; j<hlq.yverts; ++j)
- {
- for (int i=0; i<hlq.xverts; ++i)
- {
- LiquEx[p++] = hlq.pos_x + tilesize * i;
- LiquEx[p++] = hlq.pos_z;
- LiquEx[p++] = ydir * (hlq.pos_y + tilesize * j);
- }
- }
+ hlq = new WMOLiquidHeader;
+ f.read(hlq, 0x1E);
+ LiquEx_size = sizeof(WMOLiquidVert) * hlq->xverts * hlq->yverts;
+ LiquEx = new WMOLiquidVert[hlq->xverts * hlq->yverts];
+ f.read(LiquEx, LiquEx_size);
+ int nLiquBytes = hlq->xtiles * hlq->ytiles;
+ LiquBytes = new char[nLiquBytes];
+ f.read(LiquBytes, nLiquBytes);
+
+ /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
+ llog << filename;
+ llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2];
+ llog << "\nlpos: " << hlq->pos_x << ", " << hlq->pos_y << ", " << hlq->pos_z;
+ llog << "\nx-/yvert: " << hlq->xverts << "/" << hlq->yverts << " size: " << size << " expected size: " << 30 + hlq->xverts*hlq->yverts*8 + hlq->xtiles*hlq->ytiles << std::endl;
+ llog.close(); */
}
f.seek((int)nextpos);
}
@@ -217,11 +220,17 @@ bool WMOGroup::open()
return true;
}
-int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
+int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool pPreciseVectorData)
{
+ fwrite(&mogpFlags,sizeof(uint32),1,output);
+ fwrite(&groupWMOID,sizeof(uint32),1,output);
+ // group bound
+ fwrite(bbcorn1, sizeof(float), 3, output);
+ fwrite(bbcorn2, sizeof(float), 3, output);
+ fwrite(&liquflags,sizeof(uint32),1,output);
+ int nColTriangles = 0;
if(pPreciseVectorData)
{
- fwrite(&liquflags,sizeof(uint32),1,output);
char GRP[] = "GRP ";
fwrite(GRP,1,4,output);
@@ -232,7 +241,6 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
{
MobaEx[k++] = MOBA[i];
}
- delete [] MOBA;
int moba_size_grp = moba_batch*4+4;
fwrite(&moba_size_grp,4,1,output);
fwrite(&moba_batch,4,1,output);
@@ -291,21 +299,10 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
}
}
- if(LiquEx_size != 0)
- {
- int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
- fwrite(LIQU_h,4,4,output);
- fwrite(LiquEx,4,LiquEx_size/4,output);
- delete [] LiquEx;
- }
-
- return nTriangles;
+ nColTriangles = nTriangles;
}
else
{
- //printf("Convert GroupWmo...\n");
- //-------GRP -------------------------------------
- fwrite(&liquflags,sizeof(uint32),1,output);
char GRP[] = "GRP ";
fwrite(GRP,1,4,output);
int k = 0;
@@ -315,7 +312,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
{
MobaEx[k++] = MOBA[i];
}
- delete [] MOBA;
+
int moba_size_grp = moba_batch*4+4;
fwrite(&moba_size_grp,4,1,output);
fwrite(&moba_batch,4,1,output);
@@ -324,146 +321,106 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
//-------INDX------------------------------------
//-------MOPY--------
- int n = 0;
- int j = 0;
- MopyEx = new char[mopy_size];
- IndexExTr = new int[mopy_size];
- for (int i=0; i<mopy_size; i+=2)
+ MoviEx = new uint16[nTriangles*3]; // "worst case" size...
+ int *IndexRenum = new int[nVertices];
+ memset(IndexRenum, 0xFF, nVertices*sizeof(int));
+ for (int i=0; i<nTriangles; ++i)
{
// Skip no collision triangles
- if ((int)MOPY[i]&WMO_MATERIAL_NO_COLLISION)
+ if (MOPY[2*i]&WMO_MATERIAL_NO_COLLISION ||
+ !(MOPY[2*i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT)) )
continue;
- // Use only this triangles
- if ((int)MOPY[i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT))
+ // Use this triangle
+ for (int j=0; j<3; ++j)
{
- MopyEx[n] = MOPY[i];
- MopyEx[(n+1)] = MOPY[(i+1)];
- IndexExTr[j] = i/2;
- j+=1;
- n+=2;
+ IndexRenum[MOVI[3*i + j]] = 1;
+ MoviEx[3*nColTriangles + j] = MOVI[3*i + j];
}
+ ++nColTriangles;
}
- MopyEx_size = n;
- IndexExTr_size = j;
- delete [] MOPY;
- delete [] MopyEx;
- //---------MOVI-----------
- MoviEx = new uint16[IndexExTr_size*3];
- int m = 0;
- for (int i=0; i<IndexExTr_size; ++i)
+ // assign new vertex index numbers
+ int nColVertices = 0;
+ for (uint32 i=0; i<nVertices; ++i)
{
- int n = 0;
- n = IndexExTr[i]*3;
- for (int x=0; x<3; ++x)
+ if (IndexRenum[i] == 1)
{
- MoviEx[m] = MOVI[n];
- n++;
- m++;
+ IndexRenum[i] = nColVertices;
+ ++nColVertices;
}
}
- delete [] MOVI;
- MoviExSort = new uint16[IndexExTr_size*3];
- for(int y=0; y<IndexExTr_size*3; ++y)
- {
- MoviExSort[y]=MoviEx[y];
- }
-
- uint16 hold;
- for (int pass = 1; pass < IndexExTr_size*3; ++pass)
- {
- for (int i=0; i < IndexExTr_size*3-1; ++i)
- {
- if (MoviExSort[i] > MoviExSort[i+1])
- {
- hold = MoviExSort[i];
- MoviExSort[i] = MoviExSort[i+1];
- MoviExSort[i+1] = hold;
- }
- //double = 65535
- else
- if (MoviExSort[i] == MoviExSort[i+1])
- MoviExSort[i+1] = 65535;
- }
- }
- // double delet
- uint16 s = 0;
- for (int i=0; i < IndexExTr_size*3; ++i)
+ // translate triangle indices to new numbers
+ for (int i=0; i<3*nColTriangles; ++i)
{
- if (MoviExSort[i]!=65535)
- {
- MoviExSort[s] = MoviExSort[i];
- s++;
- }
- }
- MovtExSort = new uint16[s];
- for (int i=0; i < s; ++i)
- {
- MovtExSort[i] = MoviExSort[i];
+ assert(MoviEx[i] < nVertices);
+ MoviEx[i] = IndexRenum[MoviEx[i]];
}
- for (int i=0; i < IndexExTr_size*3; ++i)
- {
- uint16 b = MoviEx[i];
- for (uint16 x = 0; x < s; ++x)
- {
- if(MoviExSort[x] == b)
- {
- MoviEx[i] = x;
- break;
- }
- }
- }
- int INDX[] = {0x58444E49,IndexExTr_size*6+4,IndexExTr_size*3};
+ // write triangle indices
+ int INDX[] = {0x58444E49, nColTriangles*6+4, nColTriangles*3};
fwrite(INDX,4,3,output);
- fwrite(MoviEx,2,IndexExTr_size*3,output);
+ fwrite(MoviEx,2,nColTriangles*3,output);
- delete [] MoviEx;
- delete [] MoviExSort;
- delete [] IndexExTr;
-
- //----------VERT---------
- //-----MOVT----------
- int d = 0;
- MovtEx = new float[s*3];
- for (uint16 i=0; i<s; ++i)
- {
- int c=0;//!!!!data in MovtExSort[i] more uint16 in great group wmo files!!!!
- c = MovtExSort[i]*3;
- for (int y=0; y<3; ++y)
- {
- MovtEx[d] = MOVT[c];
- c++;
- d++;
- }
- }
- int VERT[] = {0x54524556,d*4+4,d*4/12};// "VERT"
+ // write vertices
+ int VERT[] = {0x54524556, nColVertices*3*sizeof(float)+4, nColVertices};// "VERT"
+ int check = 3*nColVertices;
fwrite(VERT,4,3,output);
- fwrite(MovtEx,4,d,output);
- //------LIQU------------------------
- if(LiquEx_size != 0)
- {
- int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
- fwrite(LIQU_h,4,4,output);
- fwrite(LiquEx,4,LiquEx_size/4,output);
- delete [] LiquEx;
- }
+ for (uint32 i=0; i<nVertices; ++i)
+ if(IndexRenum[i] >= 0)
+ check -= fwrite(MOVT+3*i, sizeof(float), 3, output);
- delete [] MOVT;
- delete [] MovtEx;
- delete [] MovtExSort;
+ assert(check==0);
- //---------------------------------------------
- return IndexExTr_size;
+ delete [] MoviEx;
+ delete [] IndexRenum;
}
+
+ //------LIQU------------------------
+ if(LiquEx_size != 0)
+ {
+ int LIQU_h[] = {0x5551494C, sizeof(WMOLiquidHeader) + LiquEx_size + hlq->xtiles*hlq->ytiles};// "LIQU"
+ fwrite(LIQU_h, 4, 2, output);
+
+ // according to WoW.Dev Wiki:
+ uint32 liquidEntry;
+ if (rootWMO->liquidType & 4)
+ liquidEntry = liquidType;
+ else if (liquidType == 15)
+ liquidEntry = 0;
+ else
+ liquidEntry = liquidType + 1;
+ // overwrite material type in header...
+ hlq->type = LiqType[liquidEntry];
+
+ /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
+ llog << filename;
+ llog << ":\nliquidEntry: " << liquidEntry << " type: " << hlq->type << " (root:" << rootWMO->liquidType << " group:" << liquidType << ")\n";
+ llog.close(); */
+
+ fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
+ // only need height values, the other values are unknown anyway
+ for (uint32 i = 0; i<LiquEx_size/sizeof(WMOLiquidVert); ++i)
+ fwrite(&LiquEx[i].height, sizeof(float), 1, output);
+ // todo: compress to bit field
+ fwrite(LiquBytes, 1, hlq->xtiles*hlq->ytiles, output);
+ }
+
+ return nColTriangles;
}
WMOGroup::~WMOGroup()
{
+ delete [] MOPY;
+ delete [] MOVI;
+ delete [] MOVT;
+ delete [] MOBA;
+ delete hlq;
+ delete [] LiquEx;
+ delete [] LiquBytes;
}
-WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName, FILE *pDirfile)
+WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile)
{
pos = Vec3D(0,0,0);
@@ -478,35 +435,23 @@ WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName,
f.read(ff,12);
pos3 = Vec3D(ff[0],ff[1],ff[2]);
f.read(&d2,4);
- f.read(&d3,4);
- doodadset = (d2 & 0xFFFF0000) >> 16;
-
- int realx1 = (int) ((float) pos2.x / 533.333333f);
- int realy1 = (int) ((float) pos2.z / 533.333333f);
- int realx2 = (int) ((float) pos3.x / 533.333333f);
- int realy2 = (int) ((float) pos3.z / 533.333333f);
-
- if(realx1 < 0)
- {
- realx1 +=20; realx2+=20;
- }
- if(realy1 < 0)
- {
- realy1 +=20; realy2+=20;
- } // hack to prevent neg. values
+ uint16 trash,adtId;
+ f.read(&adtId,2);
+ f.read(&trash,2);
//-----------add_in _dir_file----------------
char tempname[512];
- // const char dirname[] = "buildings\\dir";
-
- sprintf(tempname, "buildings\\%s", WmoInstName);
+ sprintf(tempname, "Buildings/%s", WmoInstName);
FILE *input;
input = fopen(tempname, "r+b");
if(!input)
+ {
+ printf("WMOInstance::WMOInstance: couldn't open %s\n", tempname);
return;
+ }
fseek(input, 8, SEEK_SET); // get the correct no of vertices
int nVertices;
@@ -516,24 +461,38 @@ WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName,
if(nVertices == 0)
return;
- /* FILE *dirfile;
- dirfile = fopen(dirname, "ab");
- if(!dirfile)
- {
- printf("Can't open dirfile!'%s'\n");
- return;
- }
- */
float x,z;
x = pos.x;
z = pos.z;
if(x==0 && z == 0)
{
- x = 533.33333f*32;
- z = 533.33333f*32;
+ pos.x = 533.33333f*32;
+ pos.z = 533.33333f*32;
}
-
- fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
+ pos = fixCoords(pos);
+ pos2 = fixCoords(pos2);
+ pos3 = fixCoords(pos3);
+
+ float scale = 1.0f;
+ uint32 flags = MOD_HAS_BOUND;
+ if(tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
+ //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
+ fwrite(&mapID, sizeof(uint32), 1, pDirfile);
+ fwrite(&tileX, sizeof(uint32), 1, pDirfile);
+ fwrite(&tileY, sizeof(uint32), 1, pDirfile);
+ fwrite(&flags, sizeof(uint32), 1, pDirfile);
+ fwrite(&adtId, sizeof(uint16), 1, pDirfile);
+ fwrite(&id, sizeof(uint32), 1, pDirfile);
+ fwrite(&pos, sizeof(float), 3, pDirfile);
+ fwrite(&rot, sizeof(float), 3, pDirfile);
+ fwrite(&scale, sizeof(float), 1, pDirfile);
+ fwrite(&pos2, sizeof(float), 3, pDirfile);
+ fwrite(&pos3, sizeof(float), 3, pDirfile);
+ uint32 nlen=strlen(WmoInstName);
+ fwrite(&nlen, sizeof(uint32), 1, pDirfile);
+ fwrite(WmoInstName, sizeof(char), nlen, pDirfile);
+
+ /* fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
MapName,
WmoInstName,
(float) x, (float) pos.y, (float) z,
@@ -541,7 +500,7 @@ WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName,
nVertices,
realx1, realy1,
realx2, realy2
- );
+ ); */
// fclose(dirfile);
}
diff --git a/contrib/vmap_extractor_v2/vmapextract/wmo.h b/contrib/vmap_extractor_v2/vmapextract/wmo.h
index 3000050c170..12979bc13d9 100644
--- a/contrib/vmap_extractor_v2/vmapextract/wmo.h
+++ b/contrib/vmap_extractor_v2/vmapextract/wmo.h
@@ -1,14 +1,12 @@
#ifndef WMO_H
#define WMO_H
-#define __STORMLIB_SELF__
#define TILESIZE (533.33333f)
#define CHUNKSIZE ((TILESIZE) / 16.0f)
-#include "Stormlib.h"
#include <string>
-#include "vec3d.h"
#include <set>
-#include "mpq.h"
+#include "vec3d.h"
+#include "loadlib/loadlib.h"
// MOPY flags
#define WMO_MATERIAL_NOCAMCOLLIDE 0x01
@@ -21,19 +19,18 @@
class WMOInstance;
class WMOManager;
+class MPQFile;
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-
+/* for whatever reason a certain company just can't stick to one coordinate system... */
+static inline Vec3D fixCoords(const Vec3D &v){ return Vec3D(v.z, v.x, v.y); }
class WMORoot
{
public:
- int nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, RootID;
+ uint32 nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, RootWMOID, liquidType;
unsigned int col;
- int bbcorn1[3];
- int bbcorn2[3];
+ float bbcorn1[3];
+ float bbcorn2[3];
WMORoot(std::string &filename);
~WMORoot();
@@ -45,66 +42,75 @@ private:
char outfilename;
};
+struct WMOLiquidHeader
+{
+ int xverts, yverts, xtiles, ytiles;
+ float pos_x;
+ float pos_y;
+ float pos_z;
+ short type;
+};
+
+struct WMOLiquidVert
+{
+ uint16 unk1;
+ uint16 unk2;
+ float height;
+};
+
class WMOGroup
{
public:
- int offsize,flag,flag1,Xid,Xid2,Xid3,zero1,Xflag,nTexture,GroupID;
- int mopy_size,moba_size,hlq_xverts,hlq_yverts;
- int MopyEx_size,IndexExTr_size,LiquEx_size;
+ // MOGP
+ int groupName, descGroupName, mogpFlags;
+ float bbcorn1[3];
+ float bbcorn2[3];
+ uint16 moprIdx;
+ uint16 moprNItems;
+ uint16 nBatchA;
+ uint16 nBatchB;
+ uint32 nBatchC, fogIdx, liquidType, groupWMOID;
+
+ int mopy_size,moba_size;
+ int LiquEx_size;
unsigned int nVertices; // number when loaded
int nTriangles; // number when loaded
- int bbcorn1[3];
- int bbcorn2[3];
- int * IndexExTr;
- char* MOPY;
- char* MopyEx;
- uint16* MOVI;
- uint16* MoviEx;
- uint16* MoviExSort;
- float* MOVT;
- float* MovtEx;
- uint16* MovtExSort;
- float* MONR;
- float* MonrEx;
- uint16* MOBA;
- int* MobaEx;
- float* LiquEx;
+ char *MOPY;
+ uint16 *MOVI;
+ uint16 *MoviEx;
+ float *MOVT;
+ uint16 *MOBA;
+ int *MobaEx;
+ WMOLiquidHeader *hlq;
+ WMOLiquidVert *LiquEx;
+ char *LiquBytes;
uint32 liquflags;
WMOGroup(std::string &filename);
~WMOGroup();
bool open();
- int ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData);
+ int ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool pPreciseVectorData);
private:
std::string filename;
char outfilename;
};
-struct WMOLiquidHeader
-{
- int xverts, yverts, xtiles, ytiles;
- float pos_x;
- float pos_y;
- float pos_z;
- short type;
-};
-
-class WMOInstance
+class WMOInstance
{
static std::set<int> ids;
public:
- string MapName;
+ std::string MapName;
int currx;
int curry;
WMOGroup *wmo;
Vec3D pos;
Vec3D pos2, pos3, rot;
- int indx,id, d2, d3;
+ uint32 indx,id, d2, d3;
int doodadset;
- WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName, FILE *pDirfile);
+ WMOInstance(MPQFile &f,const char* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile);
static void reset();
};
diff --git a/contrib/vmap_extractor_v2/win/VC100/vmapExtractor3.vcxproj b/contrib/vmap_extractor_v2/win/VC100/vmapExtractor3.vcxproj
new file mode 100644
index 00000000000..b0e42586b99
--- /dev/null
+++ b/contrib/vmap_extractor_v2/win/VC100/vmapExtractor3.vcxproj
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}</ProjectGuid>
+ <RootNamespace>vmapExtractor3</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\bin\$(Platform)_$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\bin\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\libmpq;..\..\..\libmpq\dep\include;..\..\misc%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>libmpq.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\libmpq\bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <AdditionalIncludeDirectories>..\..\..\libmpq;..\..\..\libmpq\dep\include;..\..\misc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>libmpq.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\..\libmpq\bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\vmapextract\adtfile.cpp" />
+ <ClCompile Include="..\..\vmapextract\dbcfile.cpp" />
+ <ClCompile Include="..\..\vmapextract\model.cpp" />
+ <ClCompile Include="..\..\vmapextract\mpq_libmpq.cpp" />
+ <ClCompile Include="..\..\vmapextract\vmapexport.cpp" />
+ <ClCompile Include="..\..\vmapextract\wdtfile.cpp" />
+ <ClCompile Include="..\..\vmapextract\wmo.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\vmapextract\adtfile.h" />
+ <ClInclude Include="..\..\vmapextract\dbcfile.h" />
+ <ClInclude Include="..\..\vmapextract\model.h" />
+ <ClInclude Include="..\..\vmapextract\modelheaders.h" />
+ <ClInclude Include="..\..\vmapextract\mpq_libmpq04.h" />
+ <ClInclude Include="..\..\vmapextract\vec3d.h" />
+ <ClInclude Include="..\..\vmapextract\vmapexport.h" />
+ <ClInclude Include="..\..\vmapextract\wdtfile.h" />
+ <ClInclude Include="..\..\vmapextract\wmo.h" />
+ <ClInclude Include="..\..\vmapextract\loadlib\loadlib.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/contrib/vmap_extractor_v2/win/vmapExtractor3_VC100.sln b/contrib/vmap_extractor_v2/win/vmapExtractor3_VC100.sln
new file mode 100644
index 00000000000..012fa6bcdc8
--- /dev/null
+++ b/contrib/vmap_extractor_v2/win/vmapExtractor3_VC100.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmapExtractor3", "VC100\vmapExtractor3.vcxproj", "{D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Debug|Win32.Build.0 = Debug|Win32
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Release|Win32.ActiveCfg = Release|Win32
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/vmap_extractor_v2/win/vmapExtractor3_VC90.sln b/contrib/vmap_extractor_v2/win/vmapExtractor3_VC90.sln
new file mode 100644
index 00000000000..0c42d1e90f0
--- /dev/null
+++ b/contrib/vmap_extractor_v2/win/vmapExtractor3_VC90.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmapExtractor3", "VC90\vmapExtractor3.vcproj", "{D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Debug|Win32.Build.0 = Debug|Win32
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Release|Win32.ActiveCfg = Release|Win32
+ {D4624B20-AC1E-4EE9-8C9C-0FB65EEE3393}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.h b/dep/include/bzip2/bzlib.h
index 323724394a2..c5b75d6d8ff 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.h
+++ b/dep/include/bzip2/bzlib.h
@@ -4,59 +4,19 @@
/*--- bzlib.h ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
#ifndef _BZLIB_H
@@ -262,8 +222,7 @@ BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
/*--
- Code contributed by Yoshioka Tsuneo
- (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
diff --git a/dep/include/g3dlite/G3D/AABox.h b/dep/include/g3dlite/G3D/AABox.h
index b1b1477fe9f..2e8da1f6098 100644
--- a/dep/include/g3dlite/G3D/AABox.h
+++ b/dep/include/g3dlite/G3D/AABox.h
@@ -1,14 +1,14 @@
/**
@file AABox.h
-
+
Axis-aligned box class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2004-01-10
- @edited 2006-02-10
+ @edited 2009-02-10
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -19,6 +19,7 @@
#include "G3D/Vector3.h"
#include "G3D/debug.h"
#include "G3D/Array.h"
+#include "G3D/Plane.h"
namespace G3D {
@@ -27,6 +28,7 @@ namespace G3D {
*/
class AABox {
private:
+ friend class Intersect;
/** Optional argument placeholder */
static int dummy;
@@ -42,7 +44,7 @@ public:
/**
Constructs a zero-area AABox at v.
*/
- inline AABox(const Vector3& v) {
+ inline explicit AABox(const Vector3& v) {
lo = hi = v;
}
@@ -65,6 +67,27 @@ public:
hi = high;
}
+ /**
+ Grows to include the bounds of a
+ */
+ inline void merge(const AABox& a) {
+ lo = lo.min(a.lo);
+ hi = hi.max(a.hi);
+ }
+
+ inline void merge(const Vector3& a) {
+ lo = lo.min(a);
+ hi = hi.max(a);
+ }
+
+ void serialize(class BinaryOutput& b) const;
+
+ void deserialize(class BinaryInput& b);
+
+ inline bool isFinite() const {
+ return lo.isFinite() && hi.isFinite();
+ }
+
inline const Vector3& low() const {
return lo;
}
@@ -76,20 +99,15 @@ public:
/**
The largest possible finite box.
*/
- static inline const AABox& maxFinite() {
- static const AABox b = AABox(Vector3::minFinite(), Vector3::maxFinite());
- return b;
- }
+ static const AABox& maxFinite();
- static inline const AABox& inf() {
- static const AABox b = AABox(-Vector3::inf(), Vector3::inf());
- return b;
- }
+ /** A large finite box. This is smaller than FLT_MAX
+ because it leaves room to add boxes together. */
+ static const AABox& large();
- static inline const AABox& zero() {
- static const AABox b = AABox(Vector3::zero(), Vector3::zero());
- return b;
- }
+ static const AABox& inf();
+
+ static const AABox& zero();
/**
Returns the centroid of the box.
@@ -98,36 +116,21 @@ public:
return (lo + hi) * 0.5;
}
+ Vector3 corner(int index) const;
+
/**
Distance from corner(0) to the next corner along axis a.
*/
- inline double extent(int a) const {
+ inline float extent(int a) const {
debugAssert(a < 3);
return hi[a] - lo[a];
}
+
inline Vector3 extent() const {
return hi - lo;
}
- /**
- @deprecated Use culledBy(Array<Plane>&)
- */
- bool culledBy(
- const class Plane* plane,
- int numPlanes,
- int32& cullingPlaneIndex,
- const uint32 testMask,
- uint32& childMask) const;
-
- /**
- @deprecated Use culledBy(Array<Plane>&)
- */
- bool culledBy(
- const class Plane* plane,
- int numPlanes,
- int32& cullingPlaneIndex = dummy,
- const uint32 testMask = 0xFFFFFF) const;
/**
Splits the box into two AABoxes along the specified axis. low contains
@@ -136,46 +139,57 @@ public:
*/
void split(const Vector3::Axis& axis, float location, AABox& low, AABox& high) const;
- /**
- Conservative culling test for up to 32 planes.
- Returns true if there exists a <CODE>plane[p]</CODE> for
+ /**
+ Conservative culling test for up to 32 planes.
+ Returns true if there exists a <CODE>plane[p]</CODE> for
which the entire object is in the negative half space
(opposite the plane normal).
- <CODE>testMask</CODE> and <CODE>childMask</CODE>
- are used for optimizing bounding volume hierarchies.
+ <CODE>testMask</CODE> and <CODE>childMask</CODE>
+ are used for optimizing bounding volume hierarchies.
The version of this method that produces childMask
is slower than the version without; it should only
be used for parent nodes.
- @param cullingPlaneIndex The index of the first plane for which
- the entire object is in the negative half-space. The function
- exits early when one plane is found. -1 when the function
- returns false (i.e. when no plane culls the whole object).
+ @param cullingPlaneIndex The index of the first plane for which
+ the entire object is in the negative half-space. The function
+ exits early when one plane is found. -1 when the function
+ returns false (i.e. when no plane culls the whole object).
- @param testMask If bit <I>p</I> is 0, the
- bounding volume automatically passes the culling test for
- <CODE>plane[p]</CODE> (i.e. it is known that the volume
- is entirely within the positive half space). The function
+ @param testMask If bit <I>p</I> is 0, the
+ bounding volume automatically passes the culling test for
+ <CODE>plane[p]</CODE> (i.e. it is known that the volume
+ is entirely within the positive half space). The function
must return false if testMask is 0 and test all planes
when testMask is -1 (0xFFFFFFFF).
@param childMask Test mask for the children of this volume.
-
- */
- bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex,
- const uint32 testMask,
+
+ */
+ bool culledBy(
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex,
+ const uint32 testMask,
uint32& childMask) const;
/**
Conservative culling test that does not produce a mask for children.
*/
- bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex = dummy,
- const uint32 testMask = -1) const;
+ bool culledBy(
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex = dummy,
+ const uint32 testMask = 0xFFFFFFFF) const;
+
+ /** less than or equal to containment */
+ inline bool contains(const AABox& other) const {
+ return
+ (other.hi.x <= hi.x) &&
+ (other.hi.y <= hi.y) &&
+ (other.hi.z <= hi.z) &&
+ (other.lo.x >= lo.x) &&
+ (other.lo.y >= lo.y) &&
+ (other.lo.z >= lo.z);
+ }
inline bool contains(
const Vector3& point) const {
@@ -188,16 +202,11 @@ public:
(point.z <= hi.z);
}
- /** @deprecated */
- inline float surfaceArea() const {
+ inline float area() const {
Vector3 diag = hi - lo;
return 2.0f * (diag.x * diag.y + diag.y * diag.z + diag.x * diag.z);
}
- inline float area() const {
- return surfaceArea();
- }
-
inline float volume() const {
Vector3 diag = hi - lo;
return diag.x * diag.y * diag.z;
@@ -207,9 +216,6 @@ public:
Vector3 randomSurfacePoint() const;
- /** @deprecated use Box constructor */
- class Box toBox() const;
-
/** Returns true if there is any overlap */
bool intersects(const AABox& other) const;
@@ -224,7 +230,7 @@ public:
return AABox(L, H);
}
- inline unsigned int hashCode() const {
+ inline size_t hashCode() const {
return lo.hashCode() + hi.hashCode();
}
@@ -236,6 +242,20 @@ public:
return !((lo == b.lo) && (hi == b.hi));
}
+ inline AABox operator+(const Vector3& v) const {
+ AABox out;
+ out.lo = lo + v;
+ out.hi = hi + v;
+ return out;
+ }
+
+ inline AABox operator-(const Vector3& v) const {
+ AABox out;
+ out.lo = lo - v;
+ out.hi = hi - v;
+ return out;
+ }
+
void getBounds(AABox& out) const {
out = *this;
}
@@ -243,12 +263,10 @@ public:
}
-/**
- Hashing function for use with Table.
- */
-inline unsigned int hashCode(const G3D::AABox& b) {
- return b.hashCode();
-}
+template <> struct HashTrait<G3D::AABox> {
+ static size_t hashCode(const G3D::AABox& key) { return key.hashCode(); }
+};
-#endif
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Any.h b/dep/include/g3dlite/G3D/Any.h
new file mode 100644
index 00000000000..49701202ca9
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Any.h
@@ -0,0 +1,570 @@
+/**
+ @file Any.h
+
+ @author Morgan McGuire, Shawn Yarbrough, and Corey Taylor
+ @maintainer Morgan McGuire
+
+ @created 2006-06-11
+ @edited 2009-12-16
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Any_h
+#define G3D_Any_h
+
+#include "G3D/platform.h"
+#include "G3D/Table.h"
+#include "G3D/Array.h"
+#include "G3D/AtomicInt32.h"
+#include <string>
+
+// needed for Token
+#include "G3D/TextInput.h"
+
+#ifdef verify
+#undef verify
+#endif
+
+namespace G3D {
+
+class TextOutput;
+
+/**
+\brief Easy loading and saving of human-readable configuration files.
+
+Encodes typed, structured data and can serialize it to a human
+readable format that is very similar to the Python language's data
+syntax. Well-suited for quickly creating human-readable file formats,
+especially since deserialization and serialization preserve comments and
+an Any can tell you what file and line it came from.
+
+The class is designed so that copying Anys generally is fast, even if
+it is a large array or table. This is because data is shared between
+copies until it is mutated, at which point an actual copy occurs.
+
+\section Example
+Sample File:
+<pre>
+{
+ shape = "round",
+
+ # in meters
+ radius = 3.7,
+
+ position = Vector3(1.0, -1.0, 0.0),
+ texture = { format = "RGB8", size = (320, 200)}
+}
+</pre>
+
+Sample code using:
+<pre>
+Any x;
+x.load("ball.txt");
+if (x["shape"].string() == "round") {
+ x["density"] = 3;
+}
+x.save("ball.txt");
+</pre>
+
+The custom serialization format was chosen to be terse, easy for
+humans to read, and easy for machines to parse. It was specifically
+chosen over formats like XML, YAML, JSON, S-expressions, and Protocol
+Buffers, although there is no reason you could not write readers and
+writers for G3D::Any that support those.
+
+G3D::Any assumes that structures do not contain cycles; it is an
+error to create a structure like:
+
+<pre>
+Any x(Any::ARRAY);
+x.array().append(x); // don't do this!
+</pre>
+
+although no exception will be thrown at runtime during that append.
+
+
+\section Parsing
+
+The primary use of Any is to create your own text file formats.
+The Vector3 constructor is a good example of how to use the Any::verify
+methods to provide good error checking while parsing such formats:
+
+<pre>
+Vector3::Vector3(const Any& any) {
+ any.verifyName("Vector3");
+ any.verifyType(Any::TABLE, Any::ARRAY);
+ any.verifySize(3);
+
+ if (any.type() == Any::ARRAY) {
+ x = any[0];
+ y = any[1];
+ z = any[2];
+ } else {
+ // Table
+ x = any["x"];
+ y = any["y"];
+ z = any["z"];
+ }
+}
+</pre>
+
+\section BNF
+Serialized format BNF:
+
+<pre>
+identifier ::= (letter | "_") (letter | digit | "_")*
+identifier-op ::= "::" | "->" | "."
+
+identifier-exp ::= [identifier-op] identifier (identifier-op identifier)*
+
+comment ::= "#" <any characters> "\n"
+separator ::= "," | ";"
+
+number ::= <legal C printf number format>
+string ::= <legal C double-quoted string; backslashes must be escaped>
+boolean ::= "True" | "False"
+none ::= "None"
+array ::= "(" [value ("," value)*] ")"
+pair ::= (identifier | string) "=" value
+table ::= "{" [pair (separator pair)*] "}"
+named-array ::= identifier-exp tuple
+named-table ::= identifier-exp dict
+
+value ::= [comment] (none | number | boolean | string | array | table | named-array | named-table)
+</pre>
+
+Except for single-line comments, whitespace is not significant.
+All parsing is case-insensitive.
+
+The deserializer allows the substitution of [] for () when writing
+tuples and ";" for ",".
+
+The serializer indents four spaces for each level of nesting.
+Tables are written with the keys in alphabetic order.
+*/
+class Any {
+public:
+
+ enum Type {NONE, BOOLEAN, NUMBER, STRING, ARRAY, TABLE};
+
+ static std::string toString(Type t);
+
+ /** Where an Any came from in a file. Useful for throwing parsing errors */
+ class Source {
+ public:
+ std::string filename;
+ int line;
+ int character;
+
+ Source() : line(0), character(0) {}
+
+ void set(const TextInput& ti, const Token& t) {
+ filename = ti.filename();
+ line = t.line();
+ character = t.character();
+ }
+ };
+
+ typedef Array<Any> AnyArray;
+ typedef Table<std::string, Any> AnyTable;
+
+private:
+
+ /** Called from deserialize() */
+ static void deserializeComment(TextInput& ti, Token& token, std::string& comment);
+
+ /** NONE, BOOLEAN, and NUMBER are stored directly in the Any */
+ union SimpleValue {
+ bool b;
+ double n;
+
+ inline SimpleValue() : n(0.0) {}
+ inline SimpleValue(bool x) : b(x) {}
+ inline SimpleValue(double x) : n(x) {}
+ };
+
+ class Data {
+ public:
+ /** ARRAY, TABLE, or STRING value only. NULL otherwise. */
+ union Value {
+ std::string* s;
+ Array<Any>* a;
+ AnyTable* t;
+ inline Value() : s(NULL) {}
+ };
+
+ // Needed so that the destructor knows what is in Value
+ // and can call its destructor.
+ Type type;
+
+ /** Always points to memory that is allocated with the Data, so
+ the destructor does not delete this. */
+ Value value;
+
+ std::string comment;
+
+ std::string name;
+
+ /** For STRING, ARRAY and TABLE types, m_value is shared between
+ multiple instances. Mutation is allowed only if the reference
+ count is exactly 1, otherwise the mutating instance must copy
+ the value. This is not used for other types.
+ */
+ AtomicInt32 referenceCount;
+
+ Source source;
+
+ private:
+
+ /** Called by create() */
+ inline Data(Type t) : type(t), referenceCount(1) {}
+
+ /** Called by destroy */
+ ~Data();
+
+ public:
+
+ /** Clones the argument */
+ static Data* create(const Data* d);
+ static Data* create(Type t);
+
+ /** Free d, invoking its destructor and freeing the memory for
+ the value. */
+ static void destroy(Data* d);
+
+ };
+
+ /** If not empty, this Any was created from operator[] on a table
+ and perhaps was not intended to exist. The name is needed to
+ format the error message if it is read from before it is
+ written to.
+
+ The source of a placeholder object is that of the parent
+ object until it is written.
+ */
+ std::string m_placeholderName;
+
+ Type m_type;
+ SimpleValue m_simpleValue;
+ mutable Data* m_data;
+
+ /** Called before every read operation to ensure that this object
+ is not a placeholder. */
+ void beforeRead() const;
+
+ /** Called before every write operation to wipe the placeholder
+ status. */
+ void beforeWrite();
+
+ /** Decrements the reference count (if there is one). If the
+ reference count is zero after decrement, calls delete on @a m_data
+ and sets it to NULL.
+ */
+ void dropReference();
+
+ /** Allocate the Data object if it does not exist */
+ void ensureData();
+
+ /** If m_data is not NULL, ensure that it has a unique reference
+ and contains a valid m_data. This has a race condition if two
+ threads are both trying to modify the same Any
+ simultaneously.*/
+ void ensureMutable();
+
+ /** Read an unnamed a TABLE or ARRAY. Token should be the open
+ paren token; it is the next token after the close on
+ return. Called from deserialize().*/
+ void deserializeBody(TextInput& ti, Token& token);
+
+ void deserialize(TextInput& ti, Token& token);
+
+ /** Read the name of a named Array or Table. */
+ static void deserializeName(TextInput& ti, Token& token, std::string& name);
+
+ /** Read until a comma is consumed or a close paren is hit, and
+ return that token. Considers the passed in token to be the first
+ value read. */
+ static void readUntilCommaOrClose(TextInput& ti, Token& token);
+
+ /** Construct an Any that is a proxy for a table fetch from \a data.
+ This proxy can be copied exactly once on return from operator[].*/
+ Any(const std::string& key, Data* data);
+
+ inline bool isPlaceholder() const {
+ return ! m_placeholderName.empty();
+ }
+
+public:
+
+ /** Base class for all Any exceptions.*/
+ class Exception {
+ public:
+ virtual ~Exception() {}
+ };
+
+ /** Thrown by operator[] when a key is not present in a const table. */
+ class KeyNotFound : public ParseError {
+ public:
+ std::string key;
+ };
+
+ /** Thrown by operator[] when an array index is not present. */
+ class IndexOutOfBounds : public Exception {
+ public:
+ int index;
+ int size;
+ inline IndexOutOfBounds() : index(0), size(0) {}
+ inline IndexOutOfBounds(int i, int s) : index(i), size(s) {}
+ };
+
+ /** NONE constructor */
+ Any();
+
+ /** Deserialize */
+ explicit Any(TextInput& t);
+
+ Any(const Any& x);
+
+ /** NUMBER constructor */
+ Any(double x);
+
+#ifdef G3D_32BIT
+ /** NUMBER constructor */
+ Any(int64 x);
+#endif // G3D_32BIT
+
+#if 0
+ /** NUMBER constructor */
+ Any(int32 x);
+#endif // 0
+
+ /** NUMBER constructor */
+ Any(long x);
+
+ /** NUMBER constructor */
+ Any(int x);
+
+ /** NUMBER constructor */
+ Any(short x);
+
+ /** BOOLEAN constructor */
+ Any(bool x);
+
+ /** STRING constructor */
+ Any(const std::string& x);
+
+ /** STRING constructor */
+ Any(const char* x);
+
+ /** \a t must be ARRAY or TABLE */
+ Any(Type t, const std::string& name = "");
+
+ ~Any();
+
+ /** Removes the comment and name */
+ Any& operator=(const Any& x);
+
+ /** Removes the comment and name */
+ Any& operator=(double x);
+
+ /** Removes the comment and name */
+ Any& operator=(int x);
+
+ /** Removes the comment and name */
+ Any& operator=(bool x);
+
+ /** Removes the comment and name */
+ Any& operator=(const std::string& x);
+
+ /** Removes the comment and name */
+ Any& operator=(const char* x);
+
+ /** \a t must be ARRAY, TABLE, or NONE. Removes the comment and name */
+ Any& operator=(Type t);
+
+ Type type() const;
+
+ /** Same as deserialize or load, but operates on a string instead
+ of a stream or file.
+
+ \sa deserialize, load
+ */
+ void parse(const std::string& src);
+
+ std::string unparse() const;
+
+ /** Comments appear before values when they are in serialized form.*/
+ const std::string& comment() const;
+ void setComment(const std::string& c);
+
+ /** True if this is the NONE value */
+ bool isNone() const;
+
+ /** Throws a ParseError exception if this is not a number */
+ double number() const;
+ const std::string& string() const;
+ bool boolean() const;
+
+ /** If this is named ARRAY or TABLE, returns the name. */
+ const std::string& name() const;
+
+ /** \brief Set the name used when serializing an ARRAY or TABLE.
+
+ Only legal for ARRAY or TABLE. The \a name must begin with a letter
+ and contain only letters, numbers, underscores and scope operators.
+
+ <pre>
+ a2z
+ hello
+ Foo::bar
+ color.red
+ this->that
+ __x
+ </pre>
+
+
+ The scope operators "::", "->", and
+ ".", may have spaces around them. The name may not
+ contain parentheses.
+ */
+ void setName(const std::string& name);
+
+ /** Number of elements if this is an ARRAY or TABLE */
+ int size() const;
+ int length() const;
+
+ /** For an array, returns the ith element */
+ const Any& operator[](int i) const;
+ Any& operator[](int i);
+
+ /** Directly exposes the underlying data structure for an ARRAY. */
+ const Array<Any>& array() const;
+ void append(const Any& v0);
+ void append(const Any& v0, const Any& v1);
+ void append(const Any& v0, const Any& v1, const Any& v2);
+ void append(const Any& v0, const Any& v1, const Any& v2, const Any& v3);
+
+ /** Directly exposes the underlying data structure for table.*/
+ const Table<std::string, Any>& table() const;
+
+ /** For a table, returns the element for \a key. Throws KeyNotFound
+ exception if the element does not exist.
+ */
+ const Any& operator[](const std::string& key) const;
+
+ // Needed to prevent the operator[](int) overload from catching
+ // string literals
+ inline const Any& operator[](const char* key) const {
+ return operator[](std::string(key));
+ }
+
+ /**
+ Fetch an element from a table. This can be used as:
+
+ <pre>
+ a["key"] = value; (create the key if it did not exist)
+ </pre>
+
+ or
+
+ <pre>
+ value = a["key"]; (throw an error if the key did not exist)
+ </pre>
+
+ <b>Note:</b>
+ In order to cause elements to be correctly created in the
+ first case while still providing "key not found" errors in the
+ second case, the Any returned is a special object that delays
+ the actual fetch until the following assignment or method
+ call. This means that in the event of an error, the exception
+ may be thrown from a line other than the actual fetch. Use
+ the Any::get() or the const Any::operator[]() methods to avoid
+ this behavior and ensure error-checking at fetch time.
+ */
+ Any& operator[](const std::string& key);
+
+ /** \copydoc Any::operator[](const std::string&) */
+ inline Any& operator[](const char* key) {
+ return operator[](std::string(key));
+ }
+
+ /** For a table, returns the element for key \a x and \a
+ defaultVal if it does not exist. */
+ const Any& get(const std::string& key, const Any& defaultVal) const;
+
+ /** Returns true if this key is in the TABLE. Illegal to call on an object that is not a TABLE. */
+ bool containsKey(const std::string& key) const;
+
+ /** For a table, assigns the element for key k. */
+ void set(const std::string& key, const Any& val);
+
+ /** for an ARRAY, resizes and returns the last element */
+ Any& next();
+
+
+ /** True if the Anys are exactly equal, ignoring comments. Applies deeply on arrays and tables. */
+ bool operator==(const Any& x) const;
+ bool operator!=(const Any& x) const;
+
+ operator int() const;
+ operator float() const;
+ operator double() const;
+ operator bool() const;
+ operator std::string() const;
+
+ /** Resize to \a n elements, where new elements are NIL
+ It is an error to call this method if this is not an Any::ARRAY */
+ void resize(int n);
+
+ /**
+ Clears all entries.
+ This must be a TABLE or ARRAY */
+ void clear();
+
+ /** Parse from a file.
+ \sa deserialize, parse */
+ void load(const std::string& filename);
+
+ /** Uses the serialize method. */
+ void save(const std::string& filename) const;
+
+ void serialize(TextOutput& to) const;
+ /** Parse from a stream.
+ \sa load, parse */
+ void deserialize(TextInput& ti);
+
+ const Source& source() const;
+
+ /** Throws a ParseError if \a value is false. Useful for quickly
+ creating parse rules in classes that deserialize from Any.
+ */
+ void verify(bool value, const std::string& message = "") const;
+
+ /** Verifies that the name begins with identifier \a n. It may contain
+ identifier operators after this */
+ void verifyName(const std::string& n) const;
+
+ /** Verifies that the type is \a t. */
+ void verifyType(Type t) const;
+
+ /** Throws an exception if the type is not \a t0 or \a t1. */
+ void verifyType(Type t0, Type t1) const;
+
+ /** Verifies that the size is between \a low and \a high, inclusive */
+ void verifySize(int low, int high) const;
+
+ /** Verifies that the size is exactly \a s */
+ void verifySize(int s) const;
+
+private:
+
+ void deserializeTable(TextInput& ti);
+ void deserializeArray(TextInput& ti,const std::string& term);
+
+}; // class Any
+
+} // namespace G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/AnyVal.h b/dep/include/g3dlite/G3D/AnyVal.h
new file mode 100644
index 00000000000..8c1bc72f206
--- /dev/null
+++ b/dep/include/g3dlite/G3D/AnyVal.h
@@ -0,0 +1,512 @@
+/**
+ @file AnyVal.h
+ @author Morgan McGuire
+ @created 2006-06-11
+ @edited 2008-07-14
+ */
+
+#ifndef G3D_ANYVAL_H
+#define G3D_ANYVAL_H
+
+#include "G3D/platform.h"
+#include <string>
+#include "G3D/Array.h"
+#include "G3D/TextInput.h"
+
+namespace G3D {
+// Forward declarations for G3D types
+class Vector2;
+class Vector3;
+class Vector4;
+class Color1;
+class Color3;
+class Color4;
+class Quat;
+class Matrix2;
+class Matrix3;
+class Matrix4;
+class CoordinateFrame;
+class TextInput;
+class TextOutput;
+class BinaryInput;
+class BinaryOutput;
+class Rect2D;
+class AABox;
+
+/**
+ \deprecated
+ <b>Use the G3D::Any class instead. This is only provided for
+ backwards compatibility to G3D 7.xx.</b>
+
+ A generic value, useful for defining property trees that can
+ be loaded from and saved to disk. The values are intentionally
+ restricted to a small set.
+
+ When written to files, the syntax is as follows. Note that you can
+ nest arrays and tables in order to create full tree (i.e., XML-like)
+ structures as configuration files:
+
+ <table>
+ <tr><td>NULL</td><td><code>Nil</code></td></tr>
+ <tr><td>double</td><td><i>The number in printf double format</i></td></tr>
+ <tr><td>bool</td><td><code>true</code> <i>or</i> <code>false</code></td></tr>
+ <tr><td>std::string</td><td><i>The string in double-quotes (</i><code>"</code><i>)</i></td></tr>
+ <tr><td>Rect2D</td><td><code>R(</code><i>x<sub>0</sub></i><code>,</code><i>y<sub>0</sub></i><code>,</code><i>x<sub>1</sub></i><code>,</code><i>y<sub>1</sub></i><code>)</code></td></tr>
+ <tr><td>Color1</td><td><code>C1(</code><i>value</i><code>)</code></td></tr>
+ <tr><td>Color3</td><td><code>C3(</code><i>r</i><code>,</code><i>g</i><code>,</code><i>b</i><code>)</code></td></tr>
+ <tr><td>Color4</td><td><code>C4(</code><i>r</i><code>,</code><i>g</i><code>,</code><i>b</i><code>,</code><i>a</i><code>)</code></td></tr>
+ <tr><td>Vector2</td><td><code>V2(</code><i>x</i><code>,</code><i>y</i><code>)</code></td></tr>
+ <tr><td>Vector3</td><td><code>V3(</code><i>x</i><code>,</code><i>y</i><code>,</code><i>z</i><code>)</code></td></tr>
+ <tr><td>Vector4</td><td><code>V4(</code><i>x</i><code>,</code><i>y</i><code>,</code><i>z</i><code>,</code><i>w</i><code>)</code></td></tr>
+ <tr><td>Quat</td><td><code>V(</code>x<code>,</code>y<code>,</code>z<code>,</code>w<code>)</code></td></tr>
+ <tr><td>AABox</td><td><code>AAB(</code>low Vector3<code>, </code>high Vector3<code>)</code></td></tr>
+ <tr><td>Matrix2</td><td><code>M2(</code>r0c0<code>, </code>r0c1<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r1c0<code>, </code>r1c1<code>)</code></td></tr>
+ <tr><td>Matrix3</td><td><code>M3(</code>r0c0<code>, </code>r0c1<code>, </code>r0c2<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r1c0<code>, </code>r1c1<code>, </code>r1c2<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r2c0<code>, </code>r2c1<code>, </code>r2c2<code>)</code></td></tr>
+ <tr><td>Matrix4</td><td><code>M4(</code>r0c0<code>, </code>r0c1<code>, </code>r0c2<code>, </code>r0c3<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r1c0<code>, </code>r1c1<code>, </code>r1c2<code>, </code>r1c3<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r2c0<code>, </code>r2c1<code>, </code>r2c2<code>, </code>r2c3<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r3c0<code>, </code>r3c1<code>, </code>r3c2<code>, </code>r3c3<code>)</code></td></tr>
+ <tr><td>CoordinateFrame</td><td><code>CF(</code>r0c0<code>, </code>r0c1<code>, </code>r0c2<code>, </code>r0c3<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r1c0<code>, </code>r1c1<code>, </code>r1c2<code>, </code>r1c3<code>,
+ <br>&nbsp;&nbsp;&nbsp;</code>r2c0<code>, </code>r2c1<code>, </code>r2c2<code>, </code>r2c3<code>)</code></td></tr>
+ <tr><td>CoordinateFrame</td><td><code>CF(V3(</code><i>x</i><code>, </code><i>y</i><code>, </code><i>z</i><code>), </code><i>yaw deg</i><code>, </code><i>pitch deg</i><code>, </code><i>optional roll deg</i><code>)</code></td></tr>
+
+ <tr><td>Array</td><td><code>[</code><i>element<sub>0</sub></i><code>, </code><i>element<sub>1</sub></i><code>, </code> ... <code>, </code><i>element<sub>n-1</sub></i><code>]</code></td></tr>
+ <tr><td>Table</td><td><code>{</code><i>symbol<sub>0</sub></i><code> = </code><i>value<sub>0</sub></i>
+ <br><code>&nbsp;</code><i>symbol<sub>1</sub></i><code> = </code><i>value<sub>1</sub></i>
+ <br><code>&nbsp;</code>...
+ <br><code>&nbsp;</code><i>symbol<sub>n-1</sub></i><code> = </code><i>value<sub>n-1</sub></i><code>}</code></td></tr>
+ </table>
+
+ See also boost::any for a more general purpose but slightly harder to use
+ "any" for C++.
+
+ The semantics of operator[] and the get() methods are slightly different;
+ operator[] acts more like a scripting language that automatically extends
+ arrays and tables instead of generating errors. get() has more strict semantics,
+ like a C++ class.
+
+ AnyVal uses copy-on-mutate, so that <code>AnyVal a = b</code> semantically copies <code>b</code> (like <code>int a = b</code> would), although in practice
+ it delays the copy until one is mutated so that it is still fast to "copy" large arrays and tables.
+
+ Reading example:
+ <pre>
+ AnyVal property = AnyVal::fromFile("c:/tmp/test.txt"));
+
+ Vector3 vel = property["angular velocity"]
+
+ <i>Using defaults to handle errors:
+ If there was no "enabled" value, this will return the default instead of failing</i>
+ bool enabled = property["enabled"].boolean(true);
+
+ </pre>
+
+ Writing to a file:
+ <pre>
+ AnyVal dict(AnyVal::TABLE);
+
+ dict["enabled"] = AnyVal(true);
+ dict["weight"] = 100;
+ dict["angular velocity"] = Vector3(1, -3, 4.5);
+
+ TextOutput t("c:/tmp/test.txt");
+ dict.serialize(t);
+ t.commit();
+ </pre>
+
+ Example of a data file:
+ <pre>
+ {
+ heights = [1, 17, 32]
+ model =
+ {
+ color = C3(1, 1, 1)
+ filename = "foo.md2"
+ }
+ position = V3(23, 14, 0)
+ name = "Elmer"
+ }
+ </pre>
+
+ <p>
+ <b>What's the difference from boost::any?</b>
+ <br>I think that AnyVal will be easier for novice C++ users. It addresses the problem that
+ even though G3D::TextInput makes reading configuration files extremely simple, many people
+ still don't use it. So AnyVal makes it ridiculously simple to read and write a tree of G3D
+ types to a file.
+
+ <i>AnyVal:</i>
+<pre>
+{
+AnyVal tree(TextInput("config.txt"));
+
+bool enabled = tree.get("enabled", false);
+Vector3 direction = tree.get("direction", Vector3::zero());
+...
+}
+</pre>
+
+<i>boost:</i>
+<pre>
+{
+bool enabled = false;
+Vector3 direction;
+Table<boost::any> tree;
+
+ ...write lots of file parsing code...
+
+ if (tree.containsKey("enabled")) {
+ const boost::any& val = tree["enabled"];
+ try {
+ enabled = any_cast<bool>(val);
+ } catch(const boost::bad_any_cast &) {
+ }
+ }
+
+ if (tree.containsKey("direction")) {
+ const boost::any& val = tree["direction"];
+ try {
+ direction = any_cast<Vector3>(val);
+ } catch(const boost::bad_any_cast &) {
+ }
+ }
+ ...
+}
+</pre>
+
+\deprecated
+ */
+class AnyVal {
+public:
+
+ /** Array and table values are all Any.*/
+ enum Type {
+ NIL,
+ NUMBER,
+ BOOLEAN,
+ STRING,
+ VECTOR2,
+ VECTOR3,
+ VECTOR4,
+ MATRIX2,
+ MATRIX3,
+ MATRIX4,
+ QUAT,
+ COORDINATEFRAME,
+ COORDINATEFRAME2D,
+ CFRAME = COORDINATEFRAME,
+ CFRAME2D = COORDINATEFRAME2D,
+ COLOR1,
+ COLOR3,
+ COLOR4,
+ RECT2D,
+ AABOX2D = RECT2D,
+ AABOX,
+ ARRAY,
+ TABLE};
+
+ /** Base class for all AnyVal exceptions.*/
+ class Exception {
+ public:
+ virtual ~Exception() {}
+ };
+
+ /** Thrown when an inappropriate operation is performed (e.g., operator[] on a number) */
+ class WrongType : public Exception {
+ public:
+ Type expected;
+ Type actual;
+ WrongType() : expected(NIL), actual(NIL) {}
+ WrongType(Type e, Type a) : expected(e), actual(a) {}
+ };
+
+ /** Thrown by operator[] when a key is not present. */
+ class KeyNotFound : public Exception {
+ public:
+ std::string key;
+ KeyNotFound() {}
+ KeyNotFound(const std::string& k) : key(k) {}
+ };
+
+ class IndexOutOfBounds : public Exception {
+ public:
+ int index;
+ int size;
+ IndexOutOfBounds() : index(0), size(0) {}
+ IndexOutOfBounds(int i, int s) : index(i), size(s) {}
+ };
+
+ /** Thrown when deserialize() when the input is incorrectly formatted. */
+ class CorruptText : public Exception {
+ public:
+ std::string message;
+
+ /** Token where the problem occurred.*/
+ G3D::Token token;
+
+ CorruptText() {}
+ CorruptText(const std::string& s, const G3D::Token& t) : message(s), token(t) {}
+ };
+
+private:
+
+ Type m_type;
+ void* m_value;
+
+ /** For table and array types, *m_value is shared between multiple
+ instances. Mutation is allowed only if the reference count is
+ exactly 1, otherwise the mutating instance must copy the
+ value. This is not used for other types.
+ */
+ int* m_referenceCount;
+
+ /** Decrements the reference count (if there is one). If the
+ reference count is zero or does not exist. Calls delete on @a
+ m_value and sets it to NULL.
+ */
+ void deleteValue();
+
+ /** Returns a copy of the value. */
+ void* copyValue() const;
+
+ /** Assumes isSharedType. Ensures that this has a unique reference */
+ void makeMutable();
+
+ /** True if this is a shared value between multiple instances. */
+ inline bool isShared() const {
+ return m_referenceCount && (*m_referenceCount > 1);
+ }
+
+ /** True when m_value is a double pointer */
+ inline bool isSharedType() const {
+ return (m_type == TABLE) || (m_type == ARRAY);
+ }
+
+public:
+
+ AnyVal();
+
+ /** Deserialize */
+ explicit AnyVal(G3D::TextInput& t);
+
+ static AnyVal fromFile(const std::string& filename);
+
+ void load(const std::string& filename);
+
+ void save(const std::string& filename) const;
+
+ ///** Deserialize */
+ //explicit AnyVal(G3D::BinaryInput& t);
+
+ /** Construct a number */
+ AnyVal(double);
+ AnyVal(int);
+
+ // Explicit to avoid ambiguity with the 'double' constructor
+ // when an integer type is constructed
+ AnyVal(bool);
+ AnyVal(const G3D::Vector2&);
+ AnyVal(const G3D::Vector3&);
+ AnyVal(const G3D::Vector4&);
+
+ AnyVal(const G3D::Color1&);
+ AnyVal(const G3D::Color3&);
+ AnyVal(const G3D::Color4&);
+
+ AnyVal(const std::string&);
+ AnyVal(const char*);
+
+ AnyVal(const G3D::Quat&);
+
+ AnyVal(const G3D::Rect2D&);
+ AnyVal(const G3D::AABox&);
+
+ AnyVal(const G3D::CoordinateFrame&);
+ AnyVal(const G3D::Matrix2&);
+ AnyVal(const G3D::Matrix3&);
+ AnyVal(const G3D::Matrix4&);
+
+ AnyVal(const AnyVal&);
+
+ AnyVal(Type arrayOrTable);
+
+ AnyVal& operator=(const AnyVal&);
+
+ /** Frees the underlying storage */
+ ~AnyVal();
+
+ Type type() const;
+
+ bool isNil() const {
+ return type() == NIL;
+ }
+
+ void serialize(G3D::TextOutput& t) const;
+ //void serialize(G3D::BinaryOutput& t) const;
+ void deserialize(G3D::TextInput& t);
+ //void deserialize(G3D::BinaryInput& t);
+
+ /** Array dereference. If the index is out of bounds, IndexOutOfBounds is thrown */
+ const AnyVal& operator[](int) const;
+
+ /** Extend this array by one element. */
+ void append(const AnyVal&);
+
+ /** If the index is out of bounds, the array is resized. If the index is negative,
+ IndexOutOfBounds is thrown.*/
+ AnyVal& operator[](int);
+
+ /** If @a i is out of bounds or this is not an ARRAY, defaultVal is returned.*/
+ const AnyVal& get(int i, const AnyVal& defaultVal) const;
+
+ /** If out of bounds, IndexOutOfBounds is thrown. */
+ const AnyVal& get(int i) const;
+
+ /** Returns defaultVal if this is not a TABLE or the key is not found. */
+ const AnyVal& get(const std::string& key, const AnyVal& defaultVal) const;
+
+ /** Throws KeyNotFound exception if the key is not present.*/
+ const AnyVal& get(const std::string& key) const;
+
+ /** Table reference */
+ const AnyVal& operator[](const std::string&) const;
+
+ /** Table reference. If the element does not exist, it is created. */
+ AnyVal& operator[](const std::string&);
+
+ /** Table reference */
+ const AnyVal& operator[](const char*) const;
+
+ /** Table reference. If the element does not exist, it is created. */
+ AnyVal& operator[](const char*);
+
+ /** If this value is not a number throws a WrongType exception. */
+ double number() const;
+
+ /** If this value is not a number, returns defaultVal. */
+ double number(double defaultVal) const;
+
+ operator double () const {
+ return number();
+ }
+
+ operator float () const {
+ return (float)number();
+ }
+
+ bool boolean() const;
+ bool boolean(bool b) const;
+
+ operator bool() const {
+ return boolean();
+ }
+
+ const std::string& string() const;
+ const std::string& string(const std::string& defaultVal) const;
+
+ operator const std::string& () const {
+ return string();
+ }
+
+ const G3D::Rect2D& rect2D() const;
+ const G3D::Rect2D& rect2D(const G3D::Rect2D& defaultVal) const;
+
+ operator const Rect2D& () const {
+ return rect2D();
+ }
+
+ const G3D::AABox& aabox() const;
+ const G3D::AABox& aabox(const G3D::AABox& defaultVal) const;
+
+ operator const AABox& () const {
+ return aabox();
+ }
+
+ const G3D::Vector2& vector2() const;
+ const G3D::Vector2& vector2(const G3D::Vector2& defaultVal) const;
+
+ operator const Vector2& () const {
+ return vector2();
+ }
+
+ const G3D::Vector3& vector3() const;
+ const G3D::Vector3& vector3(const G3D::Vector3& defaultVal) const;
+
+ operator const Vector3& () {
+ return vector3();
+ }
+
+ const G3D::Vector4& vector4() const;
+ const G3D::Vector4& vector4(const G3D::Vector4& defaultVal) const;
+
+ operator const Vector4& () const {
+ return vector4();
+ }
+
+ const G3D::Color1& color1() const;
+ const G3D::Color1& color1(const G3D::Color1& defaultVal) const;
+
+ const G3D::Color3& color3() const;
+ const G3D::Color3& color3(const G3D::Color3& defaultVal) const;
+
+ operator const Color3& () const {
+ return color3();
+ }
+
+ const G3D::Color4& color4() const;
+ const G3D::Color4& color4(const G3D::Color4& defaultVal) const;
+
+ operator const Color4& () const {
+ return color4();
+ }
+
+ const G3D::CoordinateFrame& coordinateFrame() const;
+ const G3D::CoordinateFrame& coordinateFrame(const G3D::CoordinateFrame& defaultVal) const;
+
+ operator const CoordinateFrame& () const {
+ return coordinateFrame();
+ }
+
+ const G3D::Matrix2& matrix2() const;
+ const G3D::Matrix2& matrix2(const G3D::Matrix2& defaultVal) const;
+
+ operator const Matrix2& () const {
+ return matrix2();
+ }
+
+ const G3D::Matrix3& matrix3() const;
+ const G3D::Matrix3& matrix3(const G3D::Matrix3& defaultVal) const;
+
+ operator const Matrix3& () const {
+ return matrix3();
+ }
+
+ const G3D::Matrix4& matrix4() const;
+ const G3D::Matrix4& matrix4(const G3D::Matrix4& defaultVal) const;
+
+ operator const Matrix4& () const {
+ return matrix4();
+ }
+
+ const G3D::Quat& quat() const;
+ const G3D::Quat& quat(const G3D::Quat& defaultVal) const;
+
+ operator const Quat& () const {
+ return quat();
+ }
+
+ std::string toString() const;
+
+ /** Number of elements for an array or table.*/
+ int size() const;
+
+ /** For a table, returns the keys. */
+ void getKeys(G3D::Array<std::string>&) const;
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/AreaMemoryManager.h b/dep/include/g3dlite/G3D/AreaMemoryManager.h
new file mode 100644
index 00000000000..d8d8f710359
--- /dev/null
+++ b/dep/include/g3dlite/G3D/AreaMemoryManager.h
@@ -0,0 +1,93 @@
+/**
+ @file AreaMemoryManager.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-01-20
+ @edited 2009-05-29
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+
+#ifndef G3D_AreaMemoryManager_h
+#define G3D_AreaMemoryManager_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Array.h"
+#include "G3D/MemoryManager.h"
+
+namespace G3D {
+
+/**
+ \brief Allocates memory in large blocks and then frees it as an area.
+
+ Useful for ensuring cache coherence and for reducing the time cost of
+ multiple allocations and deallocations.
+
+ <b>Not threadsafe</b>
+ */
+class AreaMemoryManager : public MemoryManager {
+private:
+
+ class Buffer {
+ private:
+ uint8* m_first;
+ size_t m_size;
+ size_t m_used;
+
+ public:
+
+ Buffer(size_t size);
+
+ ~Buffer();
+
+ /** Returns NULL if out of space */
+ void* alloc(size_t s);
+ };
+
+ size_t m_sizeHint;
+
+ /** The underlying array is stored in regular MemoryManager heap memory */
+ Array<Buffer*> m_bufferArray;
+
+ AreaMemoryManager(size_t sizeHint);
+
+public:
+
+ typedef ReferenceCountedPointer<AreaMemoryManager> Ref;
+
+ /**
+ \param sizeHint Total amount of memory expected to be allocated.
+ The allocator will allocate memory from the system in increments
+ of this size.
+ */
+ static AreaMemoryManager::Ref create(size_t sizeHint = 10 * 1024 * 1024);
+
+ /** Invokes deallocateAll. */
+ ~AreaMemoryManager();
+
+ size_t bytesAllocated() const;
+
+ /** Allocates memory out of the buffer pool.
+ @param s must be no larger than sizeHint */
+ virtual void* alloc(size_t s);
+
+ /** Ignored. */
+ virtual void free(void* x);
+
+ virtual bool isThreadsafe() const;
+
+ /** Deletes all previously allocated memory. Because delete is not
+ invoked on objects in this memory, it is not safe to simply
+ free memory containing C++ objects that expect their destructors
+ to be called. */
+ void deallocateAll();
+};
+
+typedef AreaMemoryManager CoherentAllocator;
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Array.h b/dep/include/g3dlite/G3D/Array.h
index 34401af40c4..cc9e1d9dd01 100644
--- a/dep/include/g3dlite/G3D/Array.h
+++ b/dep/include/g3dlite/G3D/Array.h
@@ -1,22 +1,23 @@
-/**
+/**
@file Array.h
-
+
@maintainer Morgan McGuire, graphics3d.com
@cite Portions written by Aaron Orenstein, a@orenstein.name
-
+
@created 2001-03-11
- @edited 2007-05-12
+ @edited 2009-05-29
- Copyright 2000-2007, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire, http://graphics.cs.williams.edu
All rights reserved.
*/
-#ifndef G3D_ARRAY_H
-#define G3D_ARRAY_H
+#ifndef G3D_Array_h
+#define G3D_Array_h
#include "G3D/platform.h"
#include "G3D/debug.h"
#include "G3D/System.h"
+#include "G3D/MemoryManager.h"
#ifdef G3D_DEBUG
// For formatting error messages
# include "G3D/format.h"
@@ -24,15 +25,16 @@
#include <vector>
#include <algorithm>
-#ifdef G3D_WIN32
+#ifdef _MSC_VER
# include <new>
-
+
# pragma warning (push)
// debug information too long
# pragma warning( disable : 4312)
# pragma warning( disable : 4786)
#endif
+
namespace G3D {
/**
@@ -46,7 +48,7 @@ const int SORT_INCREASING = 1;
const int SORT_DECREASING = -1;
/**
- Dynamic 1D array.
+ \brief Dynamic 1D array tuned for performance.
Objects must have a default constructor (constructor that
takes no arguments) in order to be used with this template.
@@ -56,19 +58,15 @@ const int SORT_DECREASING = -1;
Do not use with objects that overload placement <code>operator new</code>,
since the speed of Array is partly due to pooled allocation.
- If SSE is defined Arrays allocate the first element aligned to
- 16 bytes.
-
- Array is highly optimized compared to std::vector.
+ Array is highly optimized compared to std::vector.
Array operations are less expensive than on std::vector and for large
- amounts of data, Array consumes only 1.5x the total size of the
+ amounts of data, Array consumes only 1.5x the total size of the
data, while std::vector consumes 2.0x. The default
array takes up zero heap space. The first resize (or append)
operation grows it to a reasonable internal size so it is efficient
- to append to small arrays. Memory is allocated using
- System::alignedMalloc, which produces pointers aligned to 16-byte
- boundaries for use with SSE instructions and uses pooled storage for
- fast allocation. When Array needs to copy
+ to append to small arrays.
+
+ Then Array needs to copy
data internally on a resize operation it correctly invokes copy
constructors of the elements (the MSVC6 implementation of
std::vector uses realloc, which can create memory leaks for classes
@@ -79,24 +77,38 @@ const int SORT_DECREASING = -1;
To serialize an array, see G3D::serialize.
+ The template parameter MIN_ELEMENTS indicates the smallest number of
+ elements that will be allocated. The default of 10 is designed to avoid
+ the overhead of repeatedly allocating the array as it grows from 1, to 2, and so on.
+ If you are creating a lot of small Arrays, however, you may want to set this smaller
+ to reduce the memory cost. Once the array has been allocated, it will never
+ deallocate the underlying array unless MIN_ELEMENTS is set to 0, MIN_BYTES is 0, and the array
+ is empty.
+
Do not subclass an Array.
+
+ \sa G3D::SmallArray
*/
-template <class T>
+template <class T, int MIN_ELEMENTS = 10, size_t MIN_BYTES = 32>
class Array {
private:
/** 0...num-1 are initialized elements, num...numAllocated-1 are not */
- T* data;
+ T* data;
+
+ int num;
+ int numAllocated;
- int num;
- int numAllocated;
+ MemoryManager::Ref m_memoryManager;
- void init(int n, int a) {
- debugAssert(n <= a);
+ /** \param n Number of elements
+ */
+ void init(int n, const MemoryManager::Ref& m) {
+ m_memoryManager = m;
debugAssert(n >= 0);
this->num = 0;
this->numAllocated = 0;
data = NULL;
- if (a > 0) {
+ if (n > 0) {
resize(n);
} else {
data = NULL;
@@ -104,7 +116,7 @@ private:
}
void _copy(const Array &other) {
- init(other.num, other.num);
+ init(other.num, MemoryManager::create());
for (int i = 0; i < num; i++) {
data[i] = other.data[i];
}
@@ -118,28 +130,31 @@ private:
return (address >= data) && (address < data + num);
}
+
/** Only compiled if you use the sort procedure. */
static bool __cdecl compareGT(const T& a, const T& b) {
return a > b;
}
+
/**
- Allocates a new array of size numAllocated (not a parameter to the method)
+ Allocates a new array of size numAllocated (not a parameter to the method)
and then copies at most oldNum elements from the old array to it. Destructors are
called for oldNum elements of the old array.
*/
void realloc(int oldNum) {
T* oldData = data;
-
- // The allocation is separate from the constructor invocation because we don't want
+
+ // The allocation is separate from the constructor invocation because we don't want
// to pay for the cost of constructors until the newly allocated
- // elements are actually revealed to the application. They
+ // elements are actually revealed to the application. They
// will be constructed in the resize() method.
- data = (T*)System::alignedMalloc(sizeof(T) * numAllocated, 16);
+ data = (T*)m_memoryManager->alloc(sizeof(T) * numAllocated);
+ alwaysAssertM(data, "Memory manager returned NULL: out of memory?");
// Call the copy constructors
- {const int N = iMin(oldNum, numAllocated);
+ {const int N = G3D::min(oldNum, numAllocated);
const T* end = data + N;
T* oldPtr = oldData;
for (T* ptr = data; ptr < end; ++ptr, ++oldPtr) {
@@ -149,7 +164,7 @@ private:
const T* constructed = new (ptr) T(*oldPtr);
(void)constructed;
- debugAssertM(constructed == ptr,
+ debugAssertM(constructed == ptr,
"new returned a different address than the one provided by Array.");
}}
@@ -159,19 +174,31 @@ private:
ptr->~T();
}}
- System::alignedFree(oldData);
+ m_memoryManager->free(oldData);
}
public:
/**
- C++ STL style iterator variable. Call begin() to get
+ G3D C++ STL style iterator variable. Call begin() to get
the first iterator, pre-increment (++i) the iterator to get to
the next value. Use dereference (*i) to access the element.
*/
typedef T* Iterator;
+ /** G3D C++ STL style const iterator in same style as Iterator. */
typedef const T* ConstIterator;
+ /** stl porting compatibility helper */
+ typedef Iterator iterator;
+ /** stl porting compatibility helper */
+ typedef ConstIterator const_iterator;
+ /** stl porting compatibility helper */
+ typedef T value_type;
+ /** stl porting compatibility helper */
+ typedef int size_type;
+ /** stl porting compatibility helper */
+ typedef int difference_type;
+
/**
C++ STL style iterator method. Returns the first iterator element.
Do not change the size of the array while iterating.
@@ -196,43 +223,80 @@ public:
}
/**
- The array returned is only valid until the next append() or resize call, or
- the Array is deallocated.
+ The array returned is only valid until the next append() or resize call, or
+ the Array is deallocated.
*/
T* getCArray() {
return data;
}
/**
- The array returned is only valid until the next append() or resize call, or
- the Array is deallocated.
+ The array returned is only valid until the next append() or resize call, or
+ the Array is deallocated.
*/
const T* getCArray() const {
return data;
}
- /** Creates a zero length array (no heap allocation occurs until resize). */
- Array() {
- init(0, 0);
- }
+ /** Creates a zero length array (no heap allocation occurs until resize). */
+ Array() : num(0) {
+ init(0, MemoryManager::create());
+ debugAssert(num >= 0);
+ }
+
+
+ /** Creates an array containing v0. */
+ Array(const T& v0) {
+ init(1, MemoryManager::create());
+ (*this)[0] = v0;
+ }
+
+ /** Creates an array containing v0 and v1. */
+ Array(const T& v0, const T& v1) {
+ init(2, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ }
+
+ /** Creates an array containing v0...v2. */
+ Array(const T& v0, const T& v1, const T& v2) {
+ init(3, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ (*this)[2] = v2;
+ }
+
+ /** Creates an array containing v0...v3. */
+ Array(const T& v0, const T& v1, const T& v2, const T& v3) {
+ init(4, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ (*this)[2] = v2;
+ (*this)[3] = v3;
+ }
+
+ /** Creates an array containing v0...v4. */
+ Array(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) {
+ init(5, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ (*this)[2] = v2;
+ (*this)[3] = v3;
+ (*this)[4] = v4;
+ }
- /**
- Creates an array of size.
- */
- Array(int size) {
- init(size, size);
- }
/**
Copy constructor
*/
- Array(const Array& other) {
+ Array(const Array& other) : num(0) {
_copy(other);
+ debugAssert(num >= 0);
}
/**
Destructor does not delete() the objects if T is a pointer type
- (e.g. T = int*) instead, it deletes the <B>pointers themselves</B> and
+ (e.g. T = int*) instead, it deletes the <B>pointers themselves</B> and
leaves the objects. Call deleteAll if you want to dealocate
the objects referenced. Do not call deleteAll if <CODE>T</CODE> is not a pointer
type (e.g. do call Array<Foo*>::deleteAll, do <B>not</B> call Array<Foo>::deleteAll).
@@ -242,36 +306,44 @@ public:
for (int i = 0; i < num; i++) {
(data + i)->~T();
}
-
- System::alignedFree(data);
+
+ m_memoryManager->free(data);
// Set to 0 in case this Array is global and gets referenced during app exit
data = NULL;
- num = 0;
+ num = 0;
numAllocated = 0;
}
/**
- Removes all elements. Use resize(0, false) or fastClear if you want to
+ Removes all elements. Use resize(0, false) or fastClear if you want to
remove all elements without deallocating the underlying array
so that future append() calls will be faster.
*/
- void clear() {
- resize(0);
+ void clear(bool shrink = true) {
+ resize(0, shrink);
}
- /** resize(0, false) */
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ clear();
+ debugAssert(data == NULL);
+ m_memoryManager = m;
+ }
+
+ /** resize(0, false)
+ @deprecated*/
void fastClear() {
- resize(0, false);
+ clear(false);
}
/**
Assignment operator.
*/
Array& operator=(const Array& other) {
- resize(other.num);
- for (int i = 0; i < num; ++i) {
+ debugAssert(num >= 0);
+ resize(other.num); for (int i = 0; i < num; ++i) {
data[i] = other[i];
}
+ debugAssert(num >= 0);
return *this;
}
@@ -283,6 +355,10 @@ public:
return *this;
}
+ inline MemoryManager::Ref memoryManager() const {
+ return m_memoryManager;
+ }
+
/**
Number of elements in the array.
*/
@@ -302,26 +378,13 @@ public:
Swaps element index with the last element in the array then
shrinks the array by one.
*/
- void fastRemove(int index) {
+ void fastRemove(int index, bool shrinkIfNecessary = false) {
debugAssert(index >= 0);
debugAssert(index < num);
data[index] = data[num - 1];
- resize(size() - 1);
- }
-
- /**
- Resizes, calling the default constructor for
- newly created objects and shrinking the underlying
- array as needed (and calling destructors as needed).
- */
- void resize(int n) {
- resize(n, true);
+ resize(size() - 1, shrinkIfNecessary);
}
- /** Resizes without shrinking the underlying array */
- void fastResize(int n) {
- resize(n, false);
- }
/**
Inserts at the specified index and shifts all other elements up by one.
@@ -338,20 +401,34 @@ public:
/** @param shrinkIfNecessary if false, memory will never be
reallocated when the array shrinks. This makes resizing much
- faster but can waste memory. */
- void resize(int n, bool shrinkIfNecessary) {
- int oldNum = num;
- num = n;
-
- // Call the destructors on newly hidden elements if there are any
- for (int i = num; i < oldNum; ++i) {
- (data + i)->~T();
- }
+ faster but can waste memory.
+ */
+ void resize(int n, bool shrinkIfNecessary = true) {
+ debugAssert(n >= 0);
+ if (num == n) {
+ return;
+ }
- // Once allocated, always maintain 10 elements or 32 bytes, whichever is higher.
- static const int minSize = iMax(10, 32 / sizeof(T));
+ int oldNum = num;
+ num = n;
- if (num > numAllocated) {
+ // Call the destructors on newly hidden elements if there are any
+ for (int i = num; i < oldNum; ++i) {
+ (data + i)->~T();
+ }
+
+ // Once allocated, always maintain MIN_ELEMENTS elements or 32 bytes, whichever is higher.
+ const int minSize = std::max(MIN_ELEMENTS, (int)(MIN_BYTES / sizeof(T)));
+
+ if ((MIN_ELEMENTS == 0) && (MIN_BYTES == 0) && (n == 0) && shrinkIfNecessary) {
+ // Deallocate the array completely
+ numAllocated = 0;
+ m_memoryManager->free(data);
+ data = NULL;
+ return;
+ }
+
+ if (num > numAllocated) {
// Grow the underlying array
if (numAllocated == 0) {
@@ -360,7 +437,7 @@ public:
debugAssert(oldNum == 0);
realloc(oldNum);
} else {
-
+
if (num < minSize) {
// Grow to at least the minimum size
numAllocated = minSize;
@@ -375,7 +452,7 @@ public:
float growFactor = 3.0;
- size_t oldSizeBytes = numAllocated * sizeof(T);
+ int oldSizeBytes = numAllocated * sizeof(T);
if (oldSizeBytes > 400000) {
// Avoid bloat
growFactor = 1.5;
@@ -417,7 +494,7 @@ public:
in the array.
*/
inline void append(const T& value) {
-
+
if (num < numAllocated) {
// This is a simple situation; just stick it in the next free slot using
// the copy constructor.
@@ -437,8 +514,11 @@ public:
}
}
+
inline void append(const T& v1, const T& v2) {
if (inArray(&v1) || inArray(&v2)) {
+ // Copy into temporaries so that the references won't break when
+ // the array resizes.
T t1 = v1;
T t2 = v2;
append(t1, t2);
@@ -449,12 +529,14 @@ public:
new (data + num + 1) T(v2);
num += 2;
} else {
+ // Resize the array. Note that neither value is already in the array.
resize(num + 2, DONT_SHRINK_UNDERLYING_ARRAY);
data[num - 2] = v1;
data[num - 1] = v2;
}
}
+
inline void append(const T& v1, const T& v2, const T& v3) {
if (inArray(&v1) || inArray(&v2) || inArray(&v3)) {
T t1 = v1;
@@ -476,6 +558,7 @@ public:
}
}
+
inline void append(const T& v1, const T& v2, const T& v3, const T& v4) {
if (inArray(&v1) || inArray(&v2) || inArray(&v3) || inArray(&v4)) {
T t1 = v1;
@@ -560,33 +643,51 @@ public:
pop();
}
- /**
+ /**
"The member function returns the storage currently allocated to hold the controlled
- sequence, a value at least as large as size()"
+ sequence, a value at least as large as size()"
For compatibility with std::vector.
*/
int capacity() const {
return numAllocated;
}
- /**
- "The member function returns a reference to the first element of the controlled sequence,
- which must be non-empty."
+ /**
+ "The member function returns a reference to the first element of the controlled sequence,
+ which must be non-empty."
For compatibility with std::vector.
*/
T& front() {
return (*this)[0];
}
- /**
- "The member function returns a reference to the first element of the controlled sequence,
- which must be non-empty."
+ /**
+ "The member function returns a reference to the first element of the controlled sequence,
+ which must be non-empty."
For compatibility with std::vector.
*/
const T& front() const {
return (*this)[0];
}
+ /**
+ "The member function returns a reference to the last element of the controlled sequence,
+ which must be non-empty."
+ For compatibility with std::vector.
+ */
+ T& back() {
+ return (*this)[size()-1];
+ }
+
+ /**
+ "The member function returns a reference to the last element of the controlled sequence,
+ which must be non-empty."
+ For compatibility with std::vector.
+ */
+ const T& back() const {
+ return (*this)[size()-1];
+ }
+
/**
Removes the last element and returns it. By default, shrinks the underlying array.
*/
@@ -604,6 +705,7 @@ public:
resize(num - 1, shrinkUnderlyingArrayIfNecessary);
}
+
/**
"The member function swaps the controlled sequences between *this and str."
Note that this is slower than the optimal std implementation.
@@ -616,6 +718,7 @@ public:
*this = temp;
}
+
/**
Performs bounds checks in debug mode
*/
@@ -626,7 +729,7 @@ public:
}
inline T& operator[](unsigned int n) {
- debugAssertM(((int)n < num), format("Array index out of bounds. n = %d, size() = %d", n, num));
+ debugAssertM(n < (unsigned int)num, format("Array index out of bounds. n = %d, size() = %d", n, num));
return data[n];
}
@@ -705,13 +808,13 @@ public:
/** Returns element middleIndex() */
inline const T& middle() const {
debugAssertM(num > 0, "Array is empty");
- return data[num >> 1];
+ return data[num >> 1];
}
/** Returns element middleIndex() */
inline T& middle() {
debugAssertM(num > 0, "Array is empty");
- return data[num >> 1];
+ return data[num >> 1];
}
/**
@@ -727,6 +830,19 @@ public:
/**
Returns the index of (the first occurance of) an index or -1 if
+ not found. Searches from the right.
+ */
+ int rfindIndex(const T& value) const {
+ for (int i = num -1 ; i >= 0; --i) {
+ if (data[i] == value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ Returns the index of (the first occurance of) an index or -1 if
not found.
*/
int findIndex(const T& value) const {
@@ -773,14 +889,14 @@ public:
element[0] = element[count];
++element;
}
-
+
resize(num - count);
}
void remove(int index, int count = 1) {
debugAssert((index >= 0) && (index < num));
debugAssert((count > 0) && (index + count <= num));
-
+
remove(begin() + index, count);
}
@@ -789,7 +905,7 @@ public:
*/
void reverse() {
T temp;
-
+
int n2 = num / 2;
for (int i = 0; i < n2; ++i) {
temp = data[num - 1 - i];
@@ -807,7 +923,7 @@ public:
}
</PRE>
- Note that for pointer arrays, the <CODE>const</CODE> must come
+ Note that for pointer arrays, the <CODE>const</CODE> must come
<I>after</I> the class name, e.g., <CODE>Array<MyClass*></CODE> uses:
<PRE>
@@ -815,13 +931,28 @@ public:
return elem1->x < elem2->x;
}
</PRE>
+
+ or a functor, e.g.,
+ <pre>
+bool
+less_than_functor::operator()( const double& lhs, const double& rhs ) const
+{
+return( lhs < rhs? true : false );
+}
+</pre>
*/
- void sort(bool (__cdecl *lessThan)(const T& elem1, const T& elem2)) {
+ // void sort(bool (__cdecl *lessThan)(const T& elem1, const T& elem2)) {
+ // std::sort(data, data + num, lessThan);
+ //}
+ template<class LessThan>
+ void sort(const LessThan& lessThan) {
+ // Using std::sort, which according to http://www.open-std.org/JTC1/SC22/WG21/docs/D_4.cpp
+ // was 2x faster than qsort for arrays around size 2000 on intel core2 with gcc
std::sort(data, data + num, lessThan);
}
/**
- Sorts the array in increasing order using the > or < operator. To
+ Sorts the array in increasing order using the > or < operator. To
invoke this method on Array<T>, T must override those operator.
You can overide these operators as follows:
<code>
@@ -880,8 +1011,8 @@ public:
};
/** The output arrays are resized with fastClear() so that if they are already of the same size
- as this array no memory is allocated during partitioning.
-
+ as this array no memory is allocated during partitioning.
+
@param comparator A function, or class instance with an overloaded operator() that compares
two elements of type <code>T</code> and returns 0 if they are equal, -1 if the second is smaller,
and 1 if the first is smaller (i.e., following the conventions of std::string::compare). For example:
@@ -900,7 +1031,7 @@ public:
*/
template<typename Comparator>
void partition(
- const T& partitionElement,
+ const T& partitionElement,
Array<T>& ltArray,
Array<T>& eqArray,
Array<T>& gtArray,
@@ -935,7 +1066,7 @@ public:
Uses < and == on elements to perform a partition. See partition().
*/
void partition(
- const T& partitionElement,
+ const T& partitionElement,
Array<T>& ltArray,
Array<T>& eqArray,
Array<T>& gtArray) const {
@@ -943,7 +1074,7 @@ public:
partition(partitionElement, ltArray, eqArray, gtArray, typename Array<T>::DefaultComparator());
}
- /**
+ /**
Paritions the array into those below the median, those above the median, and those elements
equal to the median in expected O(n) time using quickselect. If the array has an even
number of different elements, the median for partition purposes is the largest value
@@ -953,8 +1084,8 @@ public:
@param comparator see parition() for a discussion.*/
template<typename Comparator>
void medianPartition(
- Array<T>& ltMedian,
- Array<T>& eqMedian,
+ Array<T>& ltMedian,
+ Array<T>& eqMedian,
Array<T>& gtMedian,
Array<T>& tempArray,
const Comparator& comparator) const {
@@ -978,7 +1109,7 @@ public:
{
// Two element array; median is the smaller
int c = comparator(first(), last());
-
+
switch (c) {
case -1:
// first was bigger
@@ -1003,14 +1134,14 @@ public:
// All other cases use a recursive randomized median
- // Number of values less than all in the current arrays
+ // Number of values less than all in the current arrays
int ltBoost = 0;
- // Number of values greater than all in the current arrays
+ // Number of values greater than all in the current arrays
int gtBoost = 0;
// For even length arrays, force the gt array to be one larger than the
- // lt array:
+ // lt array:
// [1 2 3] size = 3, choose half = (s + 1) /2
//
int lowerHalfSize, upperHalfSize;
@@ -1049,7 +1180,7 @@ public:
if ((L >= lowerHalfSize) &&
(U >= upperHalfSize)) {
- // x must be the partition median
+ // x must be the partition median
break;
} else if (L < lowerHalfSize) {
@@ -1058,10 +1189,10 @@ public:
ltBoost += lt->size() + eq->size();
// The new gt array will be the old source array, unless
- // that was the this pointer (i.e., unless we are on the
+ // that was the this pointer (i.e., unless we are on the
// first iteration)
Array<T>* newGt = (source == this) ? extra : const_cast<Array<T>*>(source);
-
+
// Now set up the gt array as the new source
source = gt;
gt = newGt;
@@ -1072,10 +1203,10 @@ public:
gtBoost += gt->size() + eq->size();
// The new lt array will be the old source array, unless
- // that was the this pointer (i.e., unless we are on the
+ // that was the this pointer (i.e., unless we are on the
// first iteration)
Array<T>* newLt = (source == this) ? extra : const_cast<Array<T>*>(source);
-
+
// Now set up the lt array as the new source
source = lt;
lt = newLt;
@@ -1092,19 +1223,20 @@ public:
}
/**
- Computes a median partition using the default comparator and a dynamically allocated temporary
+ Computes a median partition using the default comparator and a dynamically allocated temporary
working array. If the median is not in the array, it is chosen to be the largest value smaller
than the true median.
*/
void medianPartition(
- Array<T>& ltMedian,
- Array<T>& eqMedian,
+ Array<T>& ltMedian,
+ Array<T>& eqMedian,
Array<T>& gtMedian) const {
Array<T> temp;
medianPartition(ltMedian, eqMedian, gtMedian, temp, DefaultComparator());
}
+
/** Redistributes the elements so that the new order is statistically independent
of the original order. O(n) time.*/
void randomize() {
@@ -1119,8 +1251,10 @@ public:
}
}
+
};
+
/** Array::contains for C-arrays */
template<class T> bool contains(const T* array, int len, const T& e) {
for (int i = len - 1; i >= 0; --i) {
@@ -1133,9 +1267,8 @@ template<class T> bool contains(const T* array, int len, const T& e) {
} // namespace
+#ifdef _MSC_VER
+# pragma warning (pop)
#endif
-#ifdef G3D_WIN32
-# pragma warning (push)
#endif
-
diff --git a/dep/include/g3dlite/G3D/AtomicInt32.h b/dep/include/g3dlite/G3D/AtomicInt32.h
new file mode 100644
index 00000000000..2d63f998355
--- /dev/null
+++ b/dep/include/g3dlite/G3D/AtomicInt32.h
@@ -0,0 +1,164 @@
+/**
+ @file AtomicInt32.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2005-09-01
+ @edited 2006-06-21
+ */
+#ifndef G3D_ATOMICINT32_H
+#define G3D_ATOMICINT32_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+
+#if defined(G3D_OSX)
+# include <libkern/OSAtomic.h>
+#endif
+
+namespace G3D {
+
+/**
+ An integer that may safely be used on different threads without
+ external locking.
+
+ On Win32, Linux, FreeBSD, and Mac OS X this is implemented without locks.
+
+ <B>BETA API</B> This is unsupported and may change
+ */
+class AtomicInt32 {
+private:
+# if defined(G3D_WIN32)
+ volatile long m_value;
+# elif defined(G3D_OSX)
+ int32_t m_value;
+# else
+ volatile int32 m_value;
+# endif
+
+
+public:
+
+ /** Initial value is undefined. */
+ AtomicInt32() {}
+
+ /** Atomic set */
+ explicit AtomicInt32(const int32 x) {
+ m_value = x;
+ }
+
+ /** Atomic set */
+ AtomicInt32(const AtomicInt32& x) {
+ m_value = x.m_value;
+ }
+
+ /** Atomic set */
+ const AtomicInt32& operator=(const int32 x) {
+ m_value = x;
+ return *this;
+ }
+
+ /** Atomic set */
+ void operator=(const AtomicInt32& x) {
+ m_value = x.m_value;
+ }
+
+ /** Returns the current value */
+ int32 value() const {
+ return m_value;
+ }
+
+ /** Returns the old value, before the add. */
+ int32 add(const int32 x) {
+# if defined(G3D_WIN32)
+
+ return InterlockedExchangeAdd(&m_value, x);
+
+# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
+
+ int32 old;
+ asm volatile ("lock; xaddl %0,%1"
+ : "=r"(old), "=m"(m_value) /* outputs */
+ : "0"(x), "m"(m_value) /* inputs */
+ : "memory", "cc");
+ return old;
+
+# elif defined(G3D_OSX)
+
+ int32 old = m_value;
+ OSAtomicAdd32(x, &m_value);
+ return old;
+
+# endif
+ }
+
+ /** Returns old value. */
+ int32 sub(const int32 x) {
+ return add(-x);
+ }
+
+ void increment() {
+# if defined(G3D_WIN32)
+ // Note: returns the newly incremented value
+ InterlockedIncrement(&m_value);
+# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
+ add(1);
+# elif defined(G3D_OSX)
+ // Note: returns the newly incremented value
+ OSAtomicIncrement32(&m_value);
+# endif
+ }
+
+ /** Returns zero if the result is zero after decrement, non-zero otherwise.*/
+ int32 decrement() {
+# if defined(G3D_WIN32)
+ // Note: returns the newly decremented value
+ return InterlockedDecrement(&m_value);
+# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
+ unsigned char nz;
+
+ asm volatile ("lock; decl %1;\n\t"
+ "setnz %%al"
+ : "=a" (nz)
+ : "m" (m_value)
+ : "memory", "cc");
+ return nz;
+# elif defined(G3D_OSX)
+ // Note: returns the newly decremented value
+ return OSAtomicDecrement32(&m_value);
+# endif
+ }
+
+
+ /** Atomic test-and-set: if <code>*this == comperand</code> then <code>*this := exchange</code> else do nothing.
+ In both cases, returns the old value of <code>*this</code>.
+
+ Performs an atomic comparison of this with the Comperand value.
+ If this is equal to the Comperand value, the Exchange value is stored in this.
+ Otherwise, no operation is performed.
+
+ Under VC6 the sign bit may be lost.
+ */
+ int32 compareAndSet(const int32 comperand, const int32 exchange) {
+# if defined(G3D_WIN32)
+ return InterlockedCompareExchange(&m_value, exchange, comperand);
+# elif defined(G3D_LINUX) || defined(G3D_FREEBSD) || defined(G3D_OSX)
+ // Based on Apache Portable Runtime
+ // http://koders.com/c/fid3B6631EE94542CDBAA03E822CA780CBA1B024822.aspx
+ int32 ret;
+ asm volatile ("lock; cmpxchgl %1, %2"
+ : "=a" (ret)
+ : "r" (exchange), "m" (m_value), "0"(comperand)
+ : "memory", "cc");
+ return ret;
+
+ // Note that OSAtomicCompareAndSwap32 does not return a useful value for us
+ // so it can't satisfy the cmpxchgl contract.
+# endif
+ }
+
+};
+
+} // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/BinaryFormat.h b/dep/include/g3dlite/G3D/BinaryFormat.h
new file mode 100644
index 00000000000..f6719a1c540
--- /dev/null
+++ b/dep/include/g3dlite/G3D/BinaryFormat.h
@@ -0,0 +1,140 @@
+/**
+ @file BinaryFormat.h
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @author 2005-06-03
+ @edited 2005-06-03
+
+ Copyright 2000-2005, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_BINARYFORMAT_H
+#define G3D_BINARYFORMAT_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+class Vector2;
+class Vector2int16;
+class Vector3;
+class Vector3int16;
+class Vector4;
+class Vector4int16;
+class Color3;
+class Color3uint8;
+class Color4;
+class Color4uint8;
+
+/**
+ Some values like float16 and int128 have no current CPU data structure that implements them but are useful
+ for file formats and for GPUs.
+
+ CHUNK_BINFMT data follows the protocol.
+ */
+// Must be packed int 16 bits for the chunk reader
+// We can't name these just "INT8" etc. because some libraries #define names like that
+enum BinaryFormat {
+ FIRST_BINFMT = 1000,
+
+ BOOL8_BINFMT,
+ UINT8_BINFMT, INT8_BINFMT, UINT16_BINFMT, INT16_BINFMT, UINT32_BINFMT, INT32_BINFMT, UINT64_BINFMT, INT64_BINFMT, UINT128_BINFMT, INT128_BINFMT,
+ FLOAT16_BINFMT, FLOAT32_BINFMT, FLOAT64_BINFMT,
+ VECTOR2_BINFMT, VECTOR2INT16_BINFMT,
+ VECTOR3_BINFMT, VECTOR3INT16_BINFMT,
+ VECTOR4_BINFMT, VECTOR4INT16_BINFMT,
+ COLOR3_BINFMT, COLOR3UINT8_BINFMT, COLOR3INT16_BINFMT,
+ COLOR4_BINFMT, COLOR4UINT8_BINFMT, COLOR4INT16_BINFMT,
+ STRING_BINFMT, STRINGEVEN_BINFMT, STRING8_BINFMT, STRING16_BINFMT, STRING32_BINFMT,
+
+ CHUNK_BINFMT,
+
+ CUSTOM_BINFMT,
+
+ LAST_BINFMT
+};
+
+}
+
+/** A macro that maps G3D types to format constants.
+ (e.g. binaryFormatOf(Vector3) == VECTOR3_BINFMT).
+*/
+// This implementation is designed to meet the following constraints:
+// 1. Work around the many MSVC++ partial template bugs
+// 2. Work for primitive types (e.g. int)
+#define binaryFormatOf(T) (G3D::_internal::_BinaryFormat<T>::x())
+
+namespace G3D {
+namespace _internal {
+
+
+template<class T> class _BinaryFormat {
+public:
+ static BinaryFormat x() {
+ return CUSTOM_BINFMT;
+ }
+};
+}}
+
+
+/**
+ Macro to declare the underlying format (as will be returned by glFormatOf)
+ of a type. For example,
+
+ <PRE>
+ DECLARE_BINARYFORMATOF(Vector4, VECTOR4_BINFMT)
+ </PRE>
+
+ Use this so you can make vertex arrays of your own classes and not just
+ the standard ones.
+ */
+#define DECLARE_BINARYFORMATOF(CType, EnumType) \
+namespace G3D { \
+ namespace _internal { \
+ template<> class _BinaryFormat<CType> { \
+ public: \
+ static BinaryFormat x() { \
+ return EnumType; \
+ } \
+ }; \
+ } \
+}
+
+DECLARE_BINARYFORMATOF( bool, BOOL8_BINFMT )
+
+DECLARE_BINARYFORMATOF( uint8, UINT8_BINFMT )
+DECLARE_BINARYFORMATOF( int8, INT8_BINFMT )
+DECLARE_BINARYFORMATOF( uint16, UINT16_BINFMT )
+DECLARE_BINARYFORMATOF( int16, INT16_BINFMT )
+DECLARE_BINARYFORMATOF( uint32, UINT32_BINFMT )
+DECLARE_BINARYFORMATOF( int32, INT32_BINFMT )
+DECLARE_BINARYFORMATOF( uint64, UINT64_BINFMT )
+DECLARE_BINARYFORMATOF( int64, INT64_BINFMT )
+
+DECLARE_BINARYFORMATOF( float32, FLOAT32_BINFMT )
+DECLARE_BINARYFORMATOF( float64, FLOAT64_BINFMT )
+
+DECLARE_BINARYFORMATOF( Vector2, VECTOR2_BINFMT )
+DECLARE_BINARYFORMATOF( Vector2int16, VECTOR2INT16_BINFMT )
+DECLARE_BINARYFORMATOF( Vector3, VECTOR3_BINFMT )
+DECLARE_BINARYFORMATOF( Vector3int16, VECTOR3INT16_BINFMT )
+DECLARE_BINARYFORMATOF( Vector4, VECTOR4_BINFMT )
+DECLARE_BINARYFORMATOF( Vector4int16, VECTOR4INT16_BINFMT )
+
+DECLARE_BINARYFORMATOF( Color3, COLOR3_BINFMT )
+DECLARE_BINARYFORMATOF( Color3uint8, COLOR3UINT8_BINFMT )
+DECLARE_BINARYFORMATOF( Color4, COLOR4_BINFMT )
+DECLARE_BINARYFORMATOF( Color4uint8, COLOR4UINT8_BINFMT )
+
+namespace G3D {
+
+/** Returns -1 if the format is custom, otherwise the byte size
+ of a single element in this format.*/
+int32 byteSize(BinaryFormat f);
+
+
+} //G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/BinaryInput.h b/dep/include/g3dlite/G3D/BinaryInput.h
new file mode 100644
index 00000000000..1dac93ea55e
--- /dev/null
+++ b/dep/include/g3dlite/G3D/BinaryInput.h
@@ -0,0 +1,441 @@
+/**
+ @file BinaryInput.h
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2001-08-09
+ @edited 2006-07-19
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_BinaryInput_h
+#define G3D_BinaryInput_h
+
+#ifdef _MSC_VER
+// Disable conditional expression is constant, which occurs incorrectly on inlined functions
+# pragma warning(push)
+# pragma warning( disable : 4127 )
+#endif
+
+#include <assert.h>
+#include <string>
+#include <vector>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Color4.h"
+#include "G3D/Color3.h"
+#include "G3D/Vector4.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector2.h"
+#include "G3D/g3dmath.h"
+#include "G3D/debug.h"
+#include "G3D/System.h"
+
+
+namespace G3D {
+
+#if defined(G3D_WIN32) || defined(G3D_LINUX)
+ // Allow writing of integers to non-word aligned locations.
+ // This is legal on x86, but not on other platforms.
+ #define G3D_ALLOW_UNALIGNED_WRITES
+#endif
+
+/**
+ Sequential or random access byte-order independent binary file access.
+ Files compressed with zlib and beginning with an unsigned 32-bit int
+ size are transparently decompressed when the compressed = true flag is
+ specified to the constructor.
+
+ For every readX method there are also versions that operate on a whole
+ Array, std::vector, or C-array. e.g. readFloat32(Array<float32>& array, n)
+ These methods resize the array or std::vector to the appropriate size
+ before reading. For a C-array, they require the pointer to reference
+ a memory block at least large enough to hold <I>n</I> elements.
+
+ Most classes define serialize/deserialize methods that use BinaryInput,
+ BinaryOutput, TextInput, and TextOutput. There are text serializer
+ functions for primitive types (e.g. int, std::string, float, double) but not
+ binary serializers-- you <B>must</b> call the BinaryInput::readInt32 or
+ other appropriate function. This is because it would be very hard to
+ debug the error sequence: <CODE>serialize(1.0, bo); ... float f; deserialize(f, bi);</CODE>
+ in which a double is serialized and then deserialized as a float.
+ */
+class BinaryInput {
+private:
+
+ // The initial buffer will be no larger than this, but
+ // may grow if a large memory read occurs. 50 MB
+ enum {INITIAL_BUFFER_LENGTH = 50000000};
+
+ /**
+ is the file big or little endian
+ */
+ G3DEndian m_fileEndian;
+ std::string m_filename;
+
+ bool m_swapBytes;
+
+ /** Next position to read from in bitString during readBits. */
+ int m_bitPos;
+
+ /** Bits currently being read by readBits.
+ Contains at most 8 (low) bits. Note that
+ beginBits/readBits actually consumes one extra byte, which
+ will be restored by writeBits.*/
+ uint32 m_bitString;
+
+ /** 1 when between beginBits and endBits, 0 otherwise. */
+ int m_beginEndBits;
+
+ /** When operating on huge files, we cannot load the whole file into memory.
+ This is the file position to which buffer[0] corresponds.
+ */
+ int64 m_alreadyRead;
+
+ /**
+ Length of the entire file, in bytes.
+ For the length of the buffer, see bufferLength
+ */
+ int64 m_length;
+
+ /** Length of the array referenced by buffer. May go past the end of the file!*/
+ int64 m_bufferLength;
+ uint8* m_buffer;
+
+ /**
+ Next byte in file, relative to buffer.
+ */
+ int64 m_pos;
+
+ /**
+ When true, the buffer is freed in the destructor.
+ */
+ bool m_freeBuffer;
+
+ /** Ensures that we are able to read at least minLength from startPosition (relative
+ to start of file). */
+ void loadIntoMemory(int64 startPosition, int64 minLength = 0);
+
+ /** Verifies that at least this number of bytes can be read.*/
+ inline void prepareToRead(int64 nbytes) {
+ debugAssertM(m_length > 0, m_filename + " not found or corrupt.");
+ debugAssertM(m_pos + nbytes + m_alreadyRead <= m_length, "Read past end of file.");
+
+ if (m_pos + nbytes > m_bufferLength) {
+ loadIntoMemory(m_pos + m_alreadyRead, nbytes);
+ }
+ }
+
+ // Not implemented on purpose, don't use
+ BinaryInput(const BinaryInput&);
+ BinaryInput& operator=(const BinaryInput&);
+ bool operator==(const BinaryInput&);
+
+ /** Buffer is compressed; replace it with a decompressed version */
+ void decompress();
+public:
+
+ /** false, constant to use with the copyMemory option */
+ static const bool NO_COPY;
+
+ /**
+ If the file cannot be opened, a zero length buffer is presented.
+ Automatically opens files that are inside zipfiles.
+
+ @param compressed Set to true if and only if the file was
+ compressed using BinaryOutput's zlib compression. This has
+ nothing to do with whether the input is in a zipfile.
+ */
+ BinaryInput(
+ const std::string& filename,
+ G3DEndian fileEndian,
+ bool compressed = false);
+
+ /**
+ Creates input stream from an in memory source.
+ Unless you specify copyMemory = false, the data is copied
+ from the pointer, so you may deallocate it as soon as the
+ object is constructed. It is an error to specify copyMemory = false
+ and compressed = true.
+
+ To decompress part of a file, you can follow the following paradigm:
+
+ <PRE>
+ BinaryInput master(...);
+
+ // read from master to point where compressed data exists.
+
+ BinaryInput subset(master.getCArray() + master.getPosition(),
+ master.length() - master.getPosition(),
+ master.endian(), true, true);
+
+ // Now read from subset (it is ok for master to go out of scope)
+ </PRE>
+ */
+ BinaryInput(
+ const uint8* data,
+ int64 dataLen,
+ G3DEndian dataEndian,
+ bool compressed = false,
+ bool copyMemory = true);
+
+ virtual ~BinaryInput();
+
+ /** Change the endian-ness of the file. This only changes the
+ interpretation of the file for future read calls; the
+ underlying data is unmodified.*/
+ void setEndian(G3DEndian endian);
+
+ G3DEndian endian() const {
+ return m_fileEndian;
+ }
+
+ std::string getFilename() const {
+ return m_filename;
+ }
+
+ /**
+ Returns a pointer to the internal memory buffer.
+ May throw an exception for huge files.
+ */
+ const uint8* getCArray() const {
+ if (m_alreadyRead > 0) {
+ throw "Cannot getCArray for a huge file";
+ }
+ return m_buffer;
+ }
+
+ /**
+ Performs bounds checks in debug mode. [] are relative to
+ the start of the file, not the current position.
+ Seeks to the new position before reading (and leaves
+ that as the current position)
+ */
+ inline uint8 operator[](int64 n) {
+ setPosition(n);
+ return readUInt8();
+ }
+
+ /**
+ Returns the length of the file in bytes.
+ */
+ inline int64 getLength() const {
+ return m_length;
+ }
+
+ inline int64 size() const {
+ return getLength();
+ }
+
+ /**
+ Returns the current byte position in the file,
+ where 0 is the beginning and getLength() - 1 is the end.
+ */
+ inline int64 getPosition() const {
+ return m_pos + m_alreadyRead;
+ }
+
+ /**
+ Sets the position. Cannot set past length.
+ May throw a char* when seeking backwards more than 10 MB on a huge file.
+ */
+ inline void setPosition(int64 p) {
+ debugAssertM(p <= m_length, "Read past end of file");
+ m_pos = p - m_alreadyRead;
+ if ((m_pos < 0) || (m_pos > m_bufferLength)) {
+ loadIntoMemory(m_pos + m_alreadyRead);
+ }
+ }
+
+ /**
+ Goes back to the beginning of the file.
+ */
+ inline void reset() {
+ setPosition(0);
+ }
+
+ inline int8 readInt8() {
+ prepareToRead(1);
+ return m_buffer[m_pos++];
+ }
+
+ inline bool readBool8() {
+ return (readInt8() != 0);
+ }
+
+ inline uint8 readUInt8() {
+ prepareToRead(1);
+ return ((uint8*)m_buffer)[m_pos++];
+ }
+
+ uint16 inline readUInt16() {
+ prepareToRead(2);
+
+ m_pos += 2;
+ if (m_swapBytes) {
+ uint8 out[2];
+ out[0] = m_buffer[m_pos - 1];
+ out[1] = m_buffer[m_pos - 2];
+ return *(uint16*)out;
+ } else {
+ #ifdef G3D_ALLOW_UNALIGNED_WRITES
+ return *(uint16*)(&m_buffer[m_pos - 2]);
+ #else
+ uint8 out[2];
+ out[0] = m_buffer[m_pos - 2];
+ out[1] = m_buffer[m_pos - 1];
+ return *(uint16*)out;
+ #endif
+ }
+
+ }
+
+ inline int16 readInt16() {
+ uint16 a = readUInt16();
+ return *(int16*)&a;
+ }
+
+ inline uint32 readUInt32() {
+ prepareToRead(4);
+
+ m_pos += 4;
+ if (m_swapBytes) {
+ uint8 out[4];
+ out[0] = m_buffer[m_pos - 1];
+ out[1] = m_buffer[m_pos - 2];
+ out[2] = m_buffer[m_pos - 3];
+ out[3] = m_buffer[m_pos - 4];
+ return *(uint32*)out;
+ } else {
+ #ifdef G3D_ALLOW_UNALIGNED_WRITES
+ return *(uint32*)(&m_buffer[m_pos - 4]);
+ #else
+ uint8 out[4];
+ out[0] = m_buffer[m_pos - 4];
+ out[1] = m_buffer[m_pos - 3];
+ out[2] = m_buffer[m_pos - 2];
+ out[3] = m_buffer[m_pos - 1];
+ return *(uint32*)out;
+ #endif
+ }
+ }
+
+
+ inline int32 readInt32() {
+ uint32 a = readUInt32();
+ return *(int32*)&a;
+ }
+
+ uint64 readUInt64();
+
+ inline int64 readInt64() {
+ uint64 a = readUInt64();
+ return *(int64*)&a;
+ }
+
+ inline float32 readFloat32() {
+ union {
+ uint32 a;
+ float32 b;
+ };
+ a = readUInt32();
+ return b;
+ }
+
+ inline float64 readFloat64() {
+ union {
+ uint64 a;
+ float64 b;
+ };
+ a = readUInt64();
+ return b;
+ }
+
+ void readBytes(void* bytes, int64 n);
+
+ /**
+ Reads an n character string. The string is not
+ required to end in NULL in the file but will
+ always be a proper std::string when returned.
+ */
+ std::string readString(int64 n);
+
+ /**
+ Reads until NULL or the end of the file is encountered.
+ */
+ std::string readString();
+
+ /**
+ Reads until NULL or the end of the file is encountered.
+ If the string has odd length (including NULL), reads
+ another byte.
+ */
+ std::string readStringEven();
+
+
+ std::string readString32();
+
+ Vector4 readVector4();
+ Vector3 readVector3();
+ Vector2 readVector2();
+
+ Color4 readColor4();
+ Color3 readColor3();
+
+ /**
+ Skips ahead n bytes.
+ */
+ inline void skip(int64 n) {
+ setPosition(m_pos + m_alreadyRead + n);
+ }
+
+ /**
+ Returns true if the position is not at the end of the file
+ */
+ inline bool hasMore() const {
+ return m_pos + m_alreadyRead < m_length;
+ }
+
+ /** Prepares for bit reading via readBits. Only readBits can be
+ called between beginBits and endBits without corrupting the
+ data stream. */
+ void beginBits();
+
+ /** Can only be called between beginBits and endBits */
+ uint32 readBits(int numBits);
+
+ /** Ends bit-reading. */
+ void endBits();
+
+# define DECLARE_READER(ucase, lcase)\
+ void read##ucase(lcase* out, int64 n);\
+ void read##ucase(std::vector<lcase>& out, int64 n);\
+ void read##ucase(Array<lcase>& out, int64 n);
+
+ DECLARE_READER(Bool8, bool)
+ DECLARE_READER(UInt8, uint8)
+ DECLARE_READER(Int8, int8)
+ DECLARE_READER(UInt16, uint16)
+ DECLARE_READER(Int16, int16)
+ DECLARE_READER(UInt32, uint32)
+ DECLARE_READER(Int32, int32)
+ DECLARE_READER(UInt64, uint64)
+ DECLARE_READER(Int64, int64)
+ DECLARE_READER(Float32, float32)
+ DECLARE_READER(Float64, float64)
+# undef DECLARE_READER
+};
+
+
+}
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/dep/include/g3dlite/G3D/BinaryOutput.h b/dep/include/g3dlite/G3D/BinaryOutput.h
new file mode 100644
index 00000000000..d81ec56a67b
--- /dev/null
+++ b/dep/include/g3dlite/G3D/BinaryOutput.h
@@ -0,0 +1,421 @@
+/**
+ @file BinaryOutput.h
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2001-08-09
+ @edited 2008-01-24
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_BINARYOUTPUT_H
+#define G3D_BINARYOUTPUT_H
+
+#include "G3D/platform.h"
+#include <assert.h>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include "G3D/Color4.h"
+#include "G3D/Color3.h"
+#include "G3D/Vector4.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector2.h"
+#include "G3D/g3dmath.h"
+#include "G3D/debug.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/System.h"
+
+#ifdef _MSC_VER
+# pragma warning (push)
+// Conditional is constant (wrong in inline)
+# pragma warning (disable : 4127)
+#endif
+namespace G3D {
+
+/**
+ Sequential or random access byte-order independent binary file access.
+
+ The compress() call can be used to compress with zlib.
+
+ Any method call can trigger an out of memory error (thrown as char*)
+ when writing to "<memory>" instead of a file.
+
+ Compressed writing and seeking backwards is not supported for huge files
+ (i.e., BinaryOutput may have to dump the contents to disk if they
+ exceed available RAM).
+ */
+class BinaryOutput {
+private:
+ std::string m_filename;
+
+ bool m_committed;
+
+ /** 0 outside of beginBits...endBits, 1 inside */
+ int m_beginEndBits;
+
+ /** The current string of bits being built up by beginBits...endBits.
+ This string is treated semantically, as if the lowest bit was
+ on the left and the highest was on the right.*/
+ int8 m_bitString;
+
+ /** Position (from the lowest bit) currently used in bitString.*/
+ int m_bitPos;
+
+ // True if the file endianess does not match the machine endian
+ bool m_swapBytes;
+
+ G3DEndian m_fileEndian;
+
+ uint8* m_buffer;
+
+ /** Size of the elements used */
+ int m_bufferLen;
+
+ /** Underlying size of memory allocaded */
+ int m_maxBufferLen;
+
+ /** Next byte in file */
+ int m_pos;
+
+ /** is this initialized? */
+ bool m_init;
+
+ /** Number of bytes already written to the file.*/
+ size_t m_alreadyWritten;
+
+ bool m_ok;
+
+ void reserveBytesWhenOutOfMemory(size_t bytes);
+
+ void reallocBuffer(size_t bytes, size_t oldBufferLen);
+
+ /**
+ Make sure at least bytes can be written, resizing if
+ necessary.
+ */
+ inline void reserveBytes(int bytes) {
+ debugAssert(bytes > 0);
+ size_t oldBufferLen = (size_t)m_bufferLen;
+
+ m_bufferLen = iMax(m_bufferLen, (m_pos + bytes));
+ if (m_bufferLen > m_maxBufferLen) {
+ reallocBuffer(bytes, oldBufferLen);
+ }
+ }
+
+ // Not implemented on purpose, don't use
+ BinaryOutput(const BinaryOutput&);
+ BinaryOutput& operator=(const BinaryOutput&);
+ bool operator==(const BinaryOutput&);
+
+public:
+
+ /**
+ You must call setEndian() if you use this (memory) constructor.
+ */
+ BinaryOutput();
+
+ /**
+ Doesn't actually open the file; commit() does that.
+ Use "<memory>" as the filename if you're going to commit
+ to memory.
+ */
+ BinaryOutput(
+ const std::string& filename,
+ G3DEndian fileEndian);
+
+ ~BinaryOutput();
+
+ /** Compresses the data in the buffer in place,
+ preceeding it with a little-endian uint32 indicating
+ the uncompressed size.
+
+ Call immediately before commit().
+
+ Cannot be used for huge files (ones where the data
+ was already written to disk)-- will throw char*.
+ */
+ void compress();
+
+ /** True if no errors have been encountered.*/
+ bool ok() const;
+
+ /**
+ Returns a pointer to the internal memory buffer.
+ */
+ inline const uint8* getCArray() const {
+ return m_buffer;
+ }
+
+ void setEndian(G3DEndian fileEndian);
+
+ G3DEndian endian() const {
+ return m_fileEndian;
+ }
+
+ std::string getFilename() const {
+ return m_filename;
+ }
+
+ /**
+ Write the bytes to disk. It is ok to call this
+ multiple times; it will just overwrite the previous file.
+
+ Parent directories are created as needed if they do
+ not exist.
+
+ <B>Not</B> called from the destructor; you must call
+ it yourself.
+
+ @param flush If true (default) the file is ready for reading when the method returns, otherwise
+ the method returns immediately and writes the file in the background.
+ */
+ void commit(bool flush = true);
+
+ /**
+ Write the bytes to memory (which must be of
+ at least size() bytes).
+ */
+ void commit(uint8*);
+
+ /**
+ A memory BinaryOutput may be reset so that it can be written to again
+ without allocating new memory. The underlying array will not be deallocated,
+ but the reset structure will act like a newly intialized one.
+ */
+ void reset();
+
+
+ inline int length() const {
+ return (int)m_bufferLen + (int)m_alreadyWritten;
+ }
+
+ inline int size() const {
+ return length();
+ }
+
+ /**
+ Sets the length of the file to n, padding
+ with 0's past the current end. Does not
+ change the position of the next byte to be
+ written unless n < size().
+
+ Throws char* when resetting a huge file to be shorter
+ than its current length.
+ */
+ inline void setLength(int n) {
+ n = n - (int)m_alreadyWritten;
+
+ if (n < 0) {
+ throw "Cannot resize huge files to be shorter.";
+ }
+
+ if (n < m_bufferLen) {
+ m_pos = n;
+ }
+ if (n > m_bufferLen) {
+ reserveBytes(n - m_bufferLen);
+ }
+ }
+
+ /**
+ Returns the current byte position in the file,
+ where 0 is the beginning and getLength() - 1 is the end.
+ */
+ inline int64 position() const {
+ return (int64)m_pos + (int64)m_alreadyWritten;
+ }
+
+
+ /**
+ Sets the position. Can set past length, in which case
+ the file is padded with zeros up to one byte before the
+ next to be written.
+
+ May throw a char* exception when seeking backwards on a huge file.
+ */
+ inline void setPosition(int64 p) {
+ p = p - (int64)m_alreadyWritten;
+
+ if (p > m_bufferLen) {
+ setLength((int)(p + (int64)m_alreadyWritten));
+ }
+
+ if (p < 0) {
+ throw "Cannot seek more than 10 MB backwards on huge files.";
+ }
+
+ m_pos = (int)p;
+ }
+
+
+ void writeBytes(
+ const void* b,
+ int count) {
+
+ reserveBytes(count);
+ debugAssert(m_pos >= 0);
+ debugAssert(m_bufferLen >= count);
+ System::memcpy(m_buffer + m_pos, b, count);
+ m_pos += count;
+ }
+
+ /**
+ Writes a signed 8-bit integer to the current position.
+ */
+ inline void writeInt8(int8 i) {
+ reserveBytes(1);
+ m_buffer[m_pos] = *(uint8*)&i;
+ m_pos++;
+ }
+
+ inline void writeBool8(bool b) {
+ writeInt8(b ? 1 : 0);
+ }
+
+ inline void writeUInt8(uint8 i) {
+ reserveBytes(1);
+ m_buffer[m_pos] = i;
+ m_pos++;
+ }
+
+ void writeUInt16(uint16 u);
+
+ inline void writeInt16(int16 i) {
+ writeUInt16(*(uint16*)&i);
+ }
+
+ void writeUInt32(uint32 u);
+
+ inline void writeInt32(int32 i) {
+ debugAssert(m_beginEndBits == 0);
+ writeUInt32(*(uint32*)&i);
+ }
+
+ void writeUInt64(uint64 u);
+
+ inline void writeInt64(int64 i) {
+ writeUInt64(*(uint64*)&i);
+ }
+
+ inline void writeFloat32(float32 f) {
+ debugAssert(m_beginEndBits == 0);
+ union {
+ float32 a;
+ uint32 b;
+ };
+ a = f;
+ writeUInt32(b);
+ }
+
+ inline void writeFloat64(float64 f) {
+ union {
+ float64 a;
+ uint64 b;
+ };
+ a = f;
+ writeUInt64(b);
+ }
+
+ /**
+ Write a string with NULL termination.
+ */
+ inline void writeString(const std::string& s) {
+ writeString(s.c_str());
+ }
+
+ void writeString(const char* s);
+
+ /**
+ Write a string, ensuring that the total length
+ including NULL is even.
+ */
+ void writeStringEven(const std::string& s) {
+ writeStringEven(s.c_str());
+ }
+
+ void writeStringEven(const char* s);
+
+
+ void writeString32(const char* s);
+
+ /**
+ Write a string with a 32-bit length field in front
+ of it.
+ */
+ void writeString32(const std::string& s) {
+ writeString32(s.c_str());
+ }
+
+ void writeVector4(const Vector4& v);
+
+ void writeVector3(const Vector3& v);
+
+ void writeVector2(const Vector2& v);
+
+ void writeColor4(const Color4& v);
+
+ void writeColor3(const Color3& v);
+
+ /**
+ Skips ahead n bytes.
+ */
+ inline void skip(int n) {
+ if (m_pos + n > m_bufferLen) {
+ setLength((int)m_pos + (int)m_alreadyWritten + n);
+ }
+ m_pos += n;
+ }
+
+ /** Call before a series of BinaryOutput::writeBits calls. Only writeBits
+ can be called between beginBits and endBits without corrupting the stream.*/
+ void beginBits();
+
+ /** Write numBits from bitString to the output stream. Bits are numbered from
+ low to high.
+
+ Can only be
+ called between beginBits and endBits. Bits written are semantically
+ little-endian, regardless of the actual endian-ness of the system. That is,
+ <CODE>writeBits(0xABCD, 16)</CODE> writes 0xCD to the first byte and
+ 0xAB to the second byte. However, if used with BinaryInput::readBits, the ordering
+ is transparent to the caller.
+ */
+ void writeBits(uint32 bitString, int numBits);
+
+ /** Call after a series of BinaryOutput::writeBits calls. This will
+ finish out with zeros the last byte into which bits were written.*/
+ void endBits();
+
+
+# define DECLARE_WRITER(ucase, lcase)\
+ void write##ucase(const lcase* out, int n);\
+ void write##ucase(const std::vector<lcase>& out, int n);\
+ void write##ucase(const Array<lcase>& out, int n);
+
+ DECLARE_WRITER(Bool8, bool)
+ DECLARE_WRITER(UInt8, uint8)
+ DECLARE_WRITER(Int8, int8)
+ DECLARE_WRITER(UInt16, uint16)
+ DECLARE_WRITER(Int16, int16)
+ DECLARE_WRITER(UInt32, uint32)
+ DECLARE_WRITER(Int32, int32)
+ DECLARE_WRITER(UInt64, uint64)
+ DECLARE_WRITER(Int64, int64)
+ DECLARE_WRITER(Float32, float32)
+ DECLARE_WRITER(Float64, float64)
+# undef DECLARE_WRITER
+
+};
+
+}
+
+#ifdef _MSC_VER
+# pragma warning (pop)
+#endif
+
+#endif
diff --git a/dep/include/g3dlite/G3D/BoundsTrait.h b/dep/include/g3dlite/G3D/BoundsTrait.h
new file mode 100644
index 00000000000..15e1418010c
--- /dev/null
+++ b/dep/include/g3dlite/G3D/BoundsTrait.h
@@ -0,0 +1,20 @@
+/**
+ @file BoundsTrait.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2008-10-01
+ @edited 2008-10-01
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_BOUNDSTRAIT_H
+#define G3D_BOUNDSTRAIT_H
+
+#include "G3D/platform.h"
+
+template<typename Value>
+struct BoundsTrait{};
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/Box.h b/dep/include/g3dlite/G3D/Box.h
index 3ac3c61d0f6..82af9125b05 100644
--- a/dep/include/g3dlite/G3D/Box.h
+++ b/dep/include/g3dlite/G3D/Box.h
@@ -1,13 +1,13 @@
/**
@file Box.h
-
+
Box class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
@created 2001-06-02
- @edited 2006-01-05
+ @edited 2007-06-05
Copyright 2000-2006, Morgan McGuire.
All rights reserved.
@@ -26,7 +26,8 @@ namespace G3D {
class CoordinateFrame;
/**
- An arbitrary 3D box, useful as a bounding box.
+ An arbitrary 3D box, useful as a bounding box.
+
To construct a box from a coordinate frame, center and extent, use the idiom:
@@ -42,7 +43,7 @@ private:
/**
<PRE>
3 2 7 6
-
+
0 1 4 5
front back (seen through front)
@@ -54,7 +55,7 @@ private:
Unit axes.
*/
Vector3 _axis[3];
-
+
Vector3 _center;
/**
@@ -83,10 +84,17 @@ public:
const Vector3& min,
const Vector3& max);
+ static Box inf();
+
+ Box(class BinaryInput& b);
+
Box(const class AABox& b);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
/**
- Returns the object to world transformation for
+ Returns the object to world transformation for
this box. localFrame().worldToObject(...) takes
objects into the space where the box axes are
(1,0,0), (0,1,0), (0,0,1). Note that there
@@ -103,18 +111,6 @@ public:
return _center;
}
- inline Vector3 getCenter() const {
- return center();
- }
-
- /**
- Returns a corner (0 <= i < 8)
- @deprecated
- */
- inline Vector3 getCorner(int i) const {
- debugAssert(i < 8);
- return _corner[i];
- }
inline Vector3 corner(int i) const {
debugAssert(i < 8);
@@ -153,65 +149,34 @@ public:
Vector3& v2,
Vector3& v3) const;
-/**
- @deprecated Use culledBy(Array<Plane>&)
- */
- bool culledBy(
- const class Plane* plane,
- int numPlanes,
- int32& cullingPlaneIndex,
- const uint32 testMask,
- uint32& childMask) const;
-
- /**
- @deprecated Use culledBy(Array<Plane>&)
- */
- bool culledBy(
- const class Plane* plane,
- int numPlanes,
- int32& cullingPlaneIndex = dummy,
- const uint32 testMask = -1) const;
- /**
+ /**
See AABox::culledBy
- */
- bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex,
- const uint32 testMask,
- uint32& childMask) const;
+ */
+ bool culledBy
+ (
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex,
+ const uint32 testMask,
+ uint32& childMask) const;
/**
Conservative culling test that does not produce a mask for children.
*/
- bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex = dummy,
- const uint32 testMask = -1) const;
+ bool culledBy
+ (
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex = dummy,
+ const uint32 testMask = -1) const;
bool contains(
const Vector3& point) const;
- /** @deprecated */
- float surfaceArea() const;
-
- inline float area() const {
- return surfaceArea();
- }
+ float area() const;
float volume() const;
- void getRandomSurfacePoint(Vector3& P, Vector3& N = Vector3::dummy) const;
-
- /**
- @deprecated
- Uniformly distributed on the surface.
- */
- inline Vector3 randomSurfacePoint() const {
- Vector3 V;
- getRandomSurfacePoint(V);
- return V;
- }
+ void getRandomSurfacePoint(Vector3& P, Vector3& N = Vector3::ignore()) const;
/**
Uniformly distributed on the interior (includes surface)
@@ -219,9 +184,12 @@ public:
Vector3 randomInteriorPoint() const;
void getBounds(class AABox&) const;
+
+ bool isFinite() const {
+ return G3D::isFinite(_volume);
+ }
};
}
#endif
-
diff --git a/dep/include/g3dlite/G3D/Box2D.h b/dep/include/g3dlite/G3D/Box2D.h
new file mode 100644
index 00000000000..80accad89dd
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Box2D.h
@@ -0,0 +1,121 @@
+/**
+ @file Box2D.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-06-02
+ @edited 2008-12-27
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Box2D_h
+#define G3D_Box2D_h
+
+#include "G3D/platform.h"
+#include "G3D/Vector2.h"
+
+namespace G3D {
+
+class CoordinateFrame;
+typedef class CoordinateFrame CFrame;
+class Rect2D;
+typedef class Rect2D AABox2D;
+
+/**
+ 2D oriented box
+ @cite http://www.flipcode.com/archives/2D_OBB_Intersection.shtml
+ */
+class Box2D {
+private:
+ /** Corners of the box, where 0 is the lower left. */
+ Vector2 m_corner[4];
+
+ /** Two edges of the box extended away from corner[0], with length
+ = 1 / extentSquared */
+ Vector2 m_axisin[2];
+
+ /** Two edges of the box extended away from corner[0], with unit length */
+ Vector2 m_axis[2];
+
+ /** Centroid of the box */
+ Vector2 m_center;
+
+ /** origin[a] = m_corner[0].dot(m_axisin[a]); */
+ float origin[2];
+
+ /** Surface area */
+ float m_area;
+
+ Vector2 m_extent;
+
+ /** Returns true if other overlaps one dimension of this. */
+ bool overlaps1Way(const Box2D& other) const;
+
+
+ /** Updates the axes after the m_corners move. Assumes the
+ m_corners actually form a rectangle. */
+ void computeAxes();
+
+public:
+
+ /**
+ @param center World-space center
+ @param w Width along object-space x-axis
+ @param h Height along object-space y-axis
+ @param angle Counter-clockwise angle from object-space x-axis in radians
+ */
+ Box2D(const Vector2& center = Vector2(0, 0), float w = 0, float h = 0, float angle = 0);
+
+ Box2D(const AABox2D& b);
+
+ Box2D(const Vector2& min, const Vector2& max);
+
+ /** Transform @a b by @a frame, discarding the Z components, and
+ compute the new box.*/
+ Box2D(const CFrame& frame, Box2D& b);
+
+ inline bool contains(const Vector2& v) const {
+ // Take to object space:
+ const Vector2& p = v - m_center;
+ float x = p.dot(m_axisin[0]);
+ float y = p.dot(m_axisin[1]);
+
+ // Must be within extent/2 on both axes in object space
+ return (abs(x) <= 0.5f) && (abs(y) <= 0.5f);
+ }
+
+ /** @brief Distance from corner(0) to the next corner along the box's local axis a. */
+ inline const Vector2& extent() const {
+ return m_extent;
+ }
+
+ /** @brief Unit length vector along axis @a a */
+ inline const Vector2& axis(int a) const {
+ debugAssert(a == 0 || a == 1);
+ return m_axis[a];
+ }
+
+ /** @brief Surface area */
+ inline float area() const {
+ return m_area;
+ }
+
+ inline const Vector2& corner(int i) const {
+ debugAssert(i >=0 && i <= 3);
+ return m_corner[i];
+ }
+
+ inline const Vector2& center() const {
+ return m_center;
+ }
+
+ /** Returns true if the intersection of the boxes is non-empty. */
+ inline bool overlaps(const Box2D& other) const {
+ return overlaps1Way(other) && other.overlaps1Way(*this);
+ }
+};
+
+} // G3D
+#endif
diff --git a/dep/include/g3dlite/G3D/BumpMapPreprocess.h b/dep/include/g3dlite/G3D/BumpMapPreprocess.h
new file mode 100644
index 00000000000..955f99e61b2
--- /dev/null
+++ b/dep/include/g3dlite/G3D/BumpMapPreprocess.h
@@ -0,0 +1,61 @@
+/**
+ \file BumpMapPreprocess.h
+
+ \maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ \created 2010-01-28
+ \edited 2010-01-28
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_BumpMapPreprocess_h
+#define G3D_BumpMapPreprocess_h
+
+#include "G3D/platform.h"
+
+namespace G3D {
+class Any;
+
+/**
+Not in the BumpMap class to avoid a circular dependency between Texture and BumpMap.
+G3D::GImage::computeNormalMap().
+*/
+class BumpMapPreprocess {
+public:
+
+ /** If true, the elevations are box filtered after computing normals
+ and before uploading, which produces better results for parallax offset mapping
+ Defaults to false. */
+ bool lowPassFilter;
+
+ /** Height of the maximum ("white") value, in pixels, for the purpose of computing normals.
+ A value of 255 means that a 255 x 255 bump image with a full black-to-white gradient
+ will produce a 45-degree ramp (this also results in "cubic" voxels).
+ A negative value means to set zExtentPixels to -zExtentPixels * max(width, height).
+ The default is -0.02.
+ */
+ float zExtentPixels;
+
+ /** After computing normals, scale the height by |N.z|, a trick that reduces texture swim in steep areas for parallax offset
+ mapping. Defaults to false.*/
+ bool scaleZByNz;
+
+ BumpMapPreprocess() : lowPassFilter(false), zExtentPixels(-0.02f), scaleZByNz(false) {}
+
+ BumpMapPreprocess(const Any& any);
+
+ operator Any() const;
+
+ bool operator==(const BumpMapPreprocess& other) const {
+ return
+ (lowPassFilter == other.lowPassFilter) &&
+ (zExtentPixels == other.zExtentPixels) &&
+ (scaleZByNz == other.scaleZByNz);
+ }
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Capsule.h b/dep/include/g3dlite/G3D/Capsule.h
new file mode 100644
index 00000000000..baeea3aa82b
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Capsule.h
@@ -0,0 +1,90 @@
+/**
+ @file Capsule.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-02-07
+ @edited 2005-08-20
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_CAPSULE_H
+#define G3D_CAPSULE_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Vector3.h"
+
+namespace G3D {
+
+class Line;
+class AABox;
+/**
+ A shape formed by extruding a sphere along a line segment.
+ */
+class Capsule {
+private:
+ Vector3 p1;
+ Vector3 p2;
+
+ float _radius;
+public:
+
+
+ /** Uninitialized */
+ Capsule();
+ Capsule(class BinaryInput& b);
+ Capsule(const Vector3& _p1, const Vector3& _p2, float _r);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ /** The line down the center of the capsule */
+ Line axis() const;
+
+ inline float radius() const {
+ return _radius;
+ }
+
+ /** Argument may be 0 or 1 */
+ inline Vector3 point(int i) const {
+ debugAssert(i == 0 || i == 1);
+ return (i == 0) ? p1 : p2;
+ }
+
+ /** Distance between the sphere centers. The total extent of the cylinder is
+ 2r + h. */
+ inline float height() const {
+ return (p1 - p2).magnitude();
+ }
+
+ inline Vector3 center() const {
+ return (p1 + p2) / 2.0;
+ }
+
+ /** Get a reference frame in which the center of mass is the origin and Y is the axis of the capsule.*/
+ void getReferenceFrame(class CoordinateFrame& cframe) const;
+
+ /**
+ Returns true if the point is inside the capsule or on its surface.
+ */
+ bool contains(const Vector3& p) const;
+
+ float volume() const;
+
+ float area() const;
+
+ /** Get axis aligned bounding box */
+ void getBounds(AABox& out) const;
+
+ /** Random world space point with outward facing normal. */
+ void getRandomSurfacePoint(Vector3& P, Vector3& N) const;
+
+ /** Point selected uniformly at random over the volume. */
+ Vector3 randomInteriorPoint() const;
+};
+
+} // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/CollisionDetection.h b/dep/include/g3dlite/G3D/CollisionDetection.h
index 5e95498ffed..c8fcf5534c2 100644
--- a/dep/include/g3dlite/G3D/CollisionDetection.h
+++ b/dep/include/g3dlite/G3D/CollisionDetection.h
@@ -1,19 +1,21 @@
/**
@file CollisionDetection.h
+
Moving collision detection for simple primitives.
- @author Morgan McGuire, matrix@graphics3d.com
+ @author Morgan McGuire, http://graphics.cs.williams.edu
@cite Spherical collision based on Paul Nettle's
ftp://ftp.3dmaileffects.com/pub/FluidStudios/CollisionDetection/Fluid_Studios_Generic_Collision_Detection_for_Games_Using_Ellipsoids.pdf
and comments by Max McGuire. Ray-sphere intersection by Eric Haines.
Box-Box intersection written by Kevin Egan.
Thanks to Max McGuire of Iron Lore for various bug fixes.
+ Box-Triangle by Tomas Akenine-Moller
@created 2001-11-19
- @edited 2006-01-10
+ @edited 2008-12-19
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -31,26 +33,27 @@
namespace G3D {
+
/**
Collision detection primitives and tools for building
higher order collision detection schemes.
These routines provide <I>moving</I> and static collision detection.
Moving collision detection allows the calculation of collisions that
- occur during a period of time -- as opposed to the intersection of
+ occur during a period of time -- as opposed to the intersection of
two static bodies.
-
+
Moving collision detection routines detect collisions between
- <I>only</I> static primitives and moving spheres or points. Since the
+ <I>only</I> static primitives and moving spheres or points. Since the
reference frame can be user defined, these functions can be used to
detect the collision between two moving bodies by subtracting
- the velocity vector of one object from the velocity vector of the
- sphere or point the detection is to occur with. This unified
+ the velocity vector of one object from the velocity vector of the
+ sphere or point the detection is to occur with. This unified
velocity vector will act as if both objects are moving simultaneously.
Collisions are detected for single-sided objects only. That is,
no collision is detected when <I>leaving</I> a primitive or passing
- through a plane or triangle opposite the normal... except for the
+ through a plane or triangle opposite the normal... except for the
point-sphere calculation or when otherwise noted.
For a sphere, the collision location returned is the point in world
@@ -66,17 +69,17 @@ namespace G3D {
<table>
<tr><td></td><td><b>Vector3</b></td><td><b>LineSegment</b></td><td><b>Ray *</b></td><td><b>Line</b></td><td><b>Plane</b></td><td><b>Triangle</b></td><td><b>Sphere</b></td><td><b>Cylinder</b></td><td><b>Capsule</b></td><td><b>AABox</b></td><td><b>Box</b></td></tr>
- <tr><td><b>Vector3</b></td><td>Vector3::operator== Vector3::fuzzyEq G3D::distance</td><td bgcolor=#C0C0C0 colspan=10 ></td></tr>
- <tr><td><b>LineSegment</b></td><td>LineSegment::closestPoint LineSegment::distance CollisionDetection::closestPointOnLineSegment</td><td></td><td bgcolor=#C0C0C0 colspan=9 ></td></tr>
+ <tr><td><b>Vector3</b></td><td>\link Vector3::operator== V3::==\endlink \link Vector3::fuzzyEq V3::fuzzy \endlink \link G3D::distance distance \endlink</td><td bgcolor=#C0C0C0 colspan=10 ></td></tr>
+ <tr><td><b>LineSegment</b></td><td>\link LineSegment::closestPoint LS::closestPoint\endlink \link LineSegment::distance LS::distance\endlink \link CollisionDetection::closestPointOnLineSegment CD\endlink</td><td></td><td bgcolor=#C0C0C0 colspan=9 ></td></tr>
<tr><td><b>Ray *</b></td><td>Ray::closestPoint Ray::distance</td><td></td><td></td><td bgcolor=#C0C0C0 colspan=8 ></td></tr>
- <tr><td><b>Line</b></td><td>Line::closestPoint Line::distance</td><td></td><td>CollisionDetection::closestPointsBetweenLineAndLine</td><td></td><td bgcolor=#C0C0C0 colspan=7 ></td></tr>
+ <tr><td><b>Line</b></td><td>Line::closestPoint Line::distance</td><td></td><td>\link CollisionDetection::closestPointsBetweenLineAndLine CD\endlink</td><td></td><td bgcolor=#C0C0C0 colspan=7 ></td></tr>
<tr><td><b>Plane</b></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=6 ></td></tr>
<tr><td><b>Triangle</b></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=5 ></td></tr>
- <tr><td><b>Sphere</b></td><td>Sphere::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=4 ></td></tr>
+ <tr><td><b>Sphere</b></td><td>Sphere::contains</td><td></td><td>\link CollisionDetection::collisionTimeForMovingPointFixedSphere CD \endlink, \link Ray::intersectionTime R::time\endlink</td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=4 ></td></tr>
<tr><td><b>Cylinder</b></td><td>Cylinder::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=3 ></td></tr>
<tr><td><b>Capsule</b></td><td>Capsule::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=2 ></td></tr>
- <tr><td><b>AABox</b></td><td>AABox::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=1 ></td></tr>
- <tr><td><b>Box</b></td><td>Box::contains</td><td>(treat as Ray)</td><td>CollisionDetection::collisionTimeForMovingPointFixedBox</td><td>(treat as Ray)</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedPlane</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedPlane</td><td>CollisionDetection::penetrationDepthForFixedSphereFixedBox</td><td>None (use OPCODE)</td><td>CollisionDetection::movingSpherePassesThroughFixedBox</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedBox</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedBox</td></tr>
+ <tr><td><b>AABox</b></td><td>AABox::contains</td><td></td><td></td><td></td><td></td><td>\link CollisionDetection::fixedSolidBoxIntersectsFixedTriangle CD\endlink</td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=1 ></td></tr>
+ <tr><td><b>Box</b></td><td>Box::contains</td><td>(treat as Ray)</td><td>\link CollisionDetection::collisionTimeForMovingPointFixedBox CD\endlink</td><td>(treat as Ray)</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedPlane CD \endlink</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedPlane CD\endlink</td><td>\link CollisionDetection::penetrationDepthForFixedSphereFixedBox CD\endlink</td><td>None (use OPCODE)</td><td>\link CollisionDetection::movingSpherePassesThroughFixedBox CD \endlink</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedBox CD\endlink</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedBox CD\endlink</td></tr>
</table>
<p>
@@ -84,28 +87,31 @@ namespace G3D {
<i>* Note: Moving collision detection against certain primitives is equivalent to static collision
detection against a bigger primitive. Ray, Line Segment == ``moving Point''; Capsule ==``moving Sphere''; Plane == ``moving Line''</i>
+
+ @deprecated Routines moving to the G3D::Intersect class in G3D 8.0
*/
class CollisionDetection {
private:
- /**
- Default parameter if value passed to a function as reference is
- not to be calculated. Must be explicitly supported by function.
- */
- static Vector3 ignore;
+ /**
+ Default parameter if value passed to a function as reference is
+ not to be calculated. Must be explicitly supported by function.
+ */
+ static Vector3 ignore;
- /**
- Default parameter if value passed to a function as reference is
- not to be calculated. Must be explicitly supported by function.
- */
+ /**
+ Default parameter if value passed to a function as reference is
+ not to be calculated. Must be explicitly supported by function.
+ */
static bool ignoreBool;
- /**
- Default parameter if value passed to a function as reference is
- not to be calculated. Must be explicitly supported by function.
- */
+ /**
+ Default parameter if value passed to a function as reference is
+ not to be calculated. Must be explicitly supported by function.
+ */
static Array<Vector3> ignoreArray;
+
// Static class!
CollisionDetection() {}
virtual ~CollisionDetection() {}
@@ -117,32 +123,32 @@ public:
Does not return normalized vector in the edge-edge case
(indices 6 through 15).
- @param separatingAxisIndex Separating axis.
- @param box1 Box 1.
- @param box2 Box 2.
+ @param separatingAxisIndex Separating axis.
+ @param box1 Box 1.
+ @param box2 Box 2.
- @return Axis that separates the two boxes.
- */
+ @return Axis that separates the two boxes.
+ */
static Vector3 separatingAxisForSolidBoxSolidBox(
const int separatingAxisIndex,
const Box & box1,
const Box & box2);
/**
- Tests whether two boxes have axes that are parallel to
- each other. If they are, axis1 and axis2 are set to be
- the parallel axes for both box1 and box2 respectively.
-
- @param ca Dot products of each of the boxes axes
- @param epsilon Fudge factor (small unit by which the dot
- products may vary and still be considered
- zero).
- @param axis1 Parallel Axis 1. [Post Condition]
- @param axis2 Parallel Axis 2. [Post Condition]
-
- @return true - If boxes have a parallel axis
- @return false - otherwise.
- */
+ Tests whether two boxes have axes that are parallel to
+ each other. If they are, axis1 and axis2 are set to be
+ the parallel axes for both box1 and box2 respectively.
+
+ @param ca Dot products of each of the boxes axes
+ @param epsilon Fudge factor (small unit by which the dot
+ products may vary and still be considered
+ zero).
+ @param axis1 Parallel Axis 1. [Post Condition]
+ @param axis2 Parallel Axis 2. [Post Condition]
+
+ @return true - If boxes have a parallel axis
+ @return false - otherwise.
+ */
static bool parallelAxisForSolidBoxSolidBox(
const double* ca,
const double epsilon,
@@ -157,15 +163,15 @@ public:
penetrationDepthForFixedSphereFixedBox() for more details
@param separatingAxisIndex
- @param a Box 1's bounding sphere vector
- @param b Box 2's bounding sphere vector
- @param D Vector between Box 1 and Box 2's center points
- @param c Pointer to array of dot products of the axes of Box 1
- and Box 2.
- @param ca Pointer to array of unsigned dot products of the axes
- of Box 1 and Box 2.
- @param ad Pointer to array of dot products of Box 1 axes and D.
- @param bd Pointer to array of dot products of Box 2 axes and D.
+ @param a Box 1's bounding sphere vector
+ @param b Box 2's bounding sphere vector
+ @param D Vector between Box 1 and Box 2's center points
+ @param c Pointer to array of dot products of the axes of Box 1
+ and Box 2.
+ @param ca Pointer to array of unsigned dot products of the axes
+ of Box 1 and Box 2.
+ @param ad Pointer to array of dot products of Box 1 axes and D.
+ @param bd Pointer to array of dot products of Box 2 axes and D.
@return Projected distance between the two boxes along the
specified separating axis.
@@ -180,41 +186,42 @@ public:
const double* ad,
const double* bd);
- /**
- Creates a set of standard information about two boxes in order to
- solve for their collision. This information includes a vector to
- the radius of the bounding sphere for each box, the vector between
- each boxes' center and a series of dot products between differing
- important vectors. These dot products include those between the axes
- of both boxes (signed and unsigned values), and the dot products
- between all the axes of box1 and the boxes' center vector and box2
- and the boxes' center vector.
-
- @pre The following space requirements must be met:
- - c[] 9 elements
- - ca[] 9 elements
- - ad[] 3 elements
- - bd[] 3 elements
-
- @cite dobted from David Eberly's papers, variables used in this function
+
+ /**
+ Creates a set of standard information about two boxes in order to
+ solve for their collision. This information includes a vector to
+ the radius of the bounding sphere for each box, the vector between
+ each boxes' center and a series of dot products between differing
+ important vectors. These dot products include those between the axes
+ of both boxes (signed and unsigned values), and the dot products
+ between all the axes of box1 and the boxes' center vector and box2
+ and the boxes' center vector.
+
+ @pre The following space requirements must be met:
+ - c[] 9 elements
+ - ca[] 9 elements
+ - ad[] 3 elements
+ - bd[] 3 elements
+
+ @cite dobted from David Eberly's papers, variables used in this function
correspond to variables used in pages 6 and 7 in the pdf
http://www.magic-software.com/Intersection.html
http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf
@note Links are out-dated. (Kept to preserve origin and authorship)
- @param box1 Box 1
- @param box2 Box 2
- @param a Box 1's bounding sphere vector
- @param b Box 2's bounding sphere vector
- @param D Vector between Box 1 and Box 2's center points
- @param c Pointer to array of dot products of the axes of Box 1
- and Box 2.
- @param ca Pointer to array of unsigned dot products of the axes
- of Box 1 and Box 2.
- @param ad Pointer to array of dot products of Box 1 axes and D.
- @param bd Pointer to array of dot products of Box 2 axes and D.
- */
+ @param box1 Box 1
+ @param box2 Box 2
+ @param a Box 1's bounding sphere vector
+ @param b Box 2's bounding sphere vector
+ @param D Vector between Box 1 and Box 2's center points
+ @param c Pointer to array of dot products of the axes of Box 1
+ and Box 2.
+ @param ca Pointer to array of unsigned dot products of the axes
+ of Box 1 and Box 2.
+ @param ad Pointer to array of dot products of Box 1 axes and D.
+ @param bd Pointer to array of dot products of Box 2 axes and D.
+ */
static void fillSolidBoxSolidBoxInfo(
const Box & box1,
const Box & box2,
@@ -226,70 +233,70 @@ public:
double* ad,
double* bd);
- /**
- Performs a simple bounding sphere check between two boxes to determine
- whether these boxes could <i>possibly</i> intersect. This is a very
- cheap operation (three dot products, two sqrts and a few others). If
- it returns true, an intersection is possible, but not necessarily
- guaranteed.
-
- @param a Vector from box A's center to an outer vertex
- @param b Vector from box B's center to an outer vertex
- @param D Distance between the centers of the two boxes
-
- @return true - if possible intersection
- @return false - otherwise (This does not guarantee an intersection)
- */
+ /**
+ Performs a simple bounding sphere check between two boxes to determine
+ whether these boxes could <i>possibly</i> intersect. This is a very
+ cheap operation (three dot products, two sqrts and a few others). If
+ it returns true, an intersection is possible, but not necessarily
+ guaranteed.
+
+ @param a Vector from box A's center to an outer vertex
+ @param b Vector from box B's center to an outer vertex
+ @param D Distance between the centers of the two boxes
+
+ @return true - if possible intersection
+ @return false - otherwise (This does not guarantee an intersection)
+ */
static bool conservativeBoxBoxTest(
const Vector3 & a,
const Vector3 & b,
const Vector3 & D);
- /**
- Determines whether two fixed solid boxes intersect.
+ /**
+ Determines whether two fixed solid boxes intersect.
@note To speed up collision detection, the lastSeparatingAxis from
the previous time step can be passed in and that plane can be
checked first. If the separating axis was not saved, or if the
two boxes intersected then lastSeparatingAxis should equal -1.
- @cite Adobted from David Eberly's papers, variables used in this function
+ @cite Adobted from David Eberly's papers, variables used in this function
correspond to variables used in pages 6 and 7 in the pdf
http://www.magic-software.com/Intersection.html
http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf
- @param box1 Box 1.
- @param box2 Box 2.
- @param lastSeparatingAxis Last separating axis.
- (optimization - see note)
+ @param box1 Box 1.
+ @param box2 Box 2.
+ @param lastSeparatingAxis Last separating axis.
+ (optimization - see note)
- @return true - Intersection.
- @return false - otherwise.
- */
+ @return true - Intersection.
+ @return false - otherwise.
+ */
static bool fixedSolidBoxIntersectsFixedSolidBox(
const Box& box1,
const Box& box2,
const int lastSeparatingAxis = -1);
/**
- Calculates the closest points on two lines with each other. If the
- lines are parallel then using the starting point, else calculate the
- closest point on each line to the other.
-
- @note This is very similiar to calculating the intersection of two lines.
- Logically then, the two points calculated would be identical if calculated
- with inifinite precision, but with the finite precision of floating point
- calculations, these values could (will) differ as the line slope approaches
- zero or inifinity.
-
- @cite variables and algorithm based on derivation at the following website:
- http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm
-
- @param line1 Line 1.
- @param line2 Line 2.
- @param closest1 Closest point on line 1.
- @param closest2 Closest point on line 2.
- */
+ Calculates the closest points on two lines with each other. If the
+ lines are parallel then using the starting point, else calculate the
+ closest point on each line to the other.
+
+ @note This is very similiar to calculating the intersection of two lines.
+ Logically then, the two points calculated would be identical if calculated
+ with inifinite precision, but with the finite precision of floating point
+ calculations, these values could (will) differ as the line slope approaches
+ zero or inifinity.
+
+ @cite variables and algorithm based on derivation at the following website:
+ http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm
+
+ @param line1 Line 1.
+ @param line2 Line 2.
+ @param closest1 Closest point on line 1.
+ @param closest2 Closest point on line 2.
+ */
static void closestPointsBetweenLineAndLine(
const Line & line1,
const Line & line2,
@@ -297,7 +304,7 @@ public:
Vector3 & closest2);
/**
- Calculates the depth of penetration between two fixed boxes.
+ Calculates the depth of penetration between two fixed boxes.
Contact normal faces away from box1 and into box2. If there is
contact, only one contact point is returned. The minimally
violated separating plane is computed
@@ -308,26 +315,26 @@ public:
the contact point is the midpoint of the smallest line
segment between the two edge lines
- @note This is very similiar to calculating the intersection of two lines.
- Logically then, the two points calculated would be identical if calculated
- with inifinite precision, but with the finite precision of floating point
- calculations, these values could (will) differ as the line slope approaches
- zero or inifinity.
+ @note This is very similiar to calculating the intersection of two lines.
+ Logically then, the two points calculated would be identical if calculated
+ with inifinite precision, but with the finite precision of floating point
+ calculations, these values could (will) differ as the line slope approaches
+ zero or inifinity.
- @cite adobted from David Eberly's papers, variables used in this function
+ @cite adobted from David Eberly's papers, variables used in this function
correspond to variables used in pages 6 and 7 in the pdf
http://www.magic-software.com/Intersection.html
http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf
- @param box1 Box 1
- @param box2 Box 2
- @param contactPoints Contact point between boxes. [Post Condition]
- @param contactNormals Surface normal at contact point. [Post Condition]
- @param lastSeparatingAxis Last separating axis. (Used for optimization)
+ @param box1 Box 1
+ @param box2 Box 2
+ @param contactPoints Contact point between boxes. [Post Condition]
+ @param contactNormals Surface normal at contact point. [Post Condition]
+ @param lastSeparatingAxis Last separating axis. (Used for optimization)
- @return Depth of penetration between the two boxes. If there is no
- intersection between the boxes, then a negative value is returned.
- */
+ @return Depth of penetration between the two boxes. If there is no
+ intersection between the boxes, then a negative value is returned.
+ */
static float penetrationDepthForFixedBoxFixedBox(
const Box& box1,
const Box& box2,
@@ -336,21 +343,21 @@ public:
const int lastSeparatingAxis = -1);
/**
- Calculates the depth of penetration between two fixed spheres as well
- as the deepest point of Sphere A that penetrates Sphere B. The normal
+ Calculates the depth of penetration between two fixed spheres as well
+ as the deepest point of Sphere A that penetrates Sphere B. The normal
returned points <B>away</B> from the object A, although it may
represent a perpendicular to either the faces of object B or object A
depending on their relative orientations.
- @param sphereA Fixed Sphere A.
- @param sphereB Fixed Sphere B.
- @param contactPoints Sphere A's deepest point that penetrates Sphere B.
- [Post Condition]
- @param contactNormals Normal at penetration point. [Post Condition]
+ @param sphereA Fixed Sphere A.
+ @param sphereB Fixed Sphere B.
+ @param contactPoints Sphere A's deepest point that penetrates Sphere B.
+ [Post Condition]
+ @param contactNormals Normal at penetration point. [Post Condition]
- @return Depth of penetration. If there is no intersection between the
- objects then the depth will be a negative value.
- */
+ @return Depth of penetration. If there is no intersection between the
+ objects then the depth will be a negative value.
+ */
static float penetrationDepthForFixedSphereFixedSphere(
const class Sphere& sphereA,
const Sphere& sphereB,
@@ -358,127 +365,125 @@ public:
Array<Vector3>& contactNormals = ignoreArray);
/**
- Calculates the depth of penetration between a fixed sphere and a fixed
- box as well as the deepest point of the sphere that penetrates the box
- and the normal at that intersection.
-
- @note There are three possible intersections between a sphere and box.
- - Sphere completely contained in the box
- - Sphere intersects one edge
- - Sphere intersects one vertex
-
- The contact point and contact normal vary for each of these situations.
- - Sphere contained in Box:
- - Normal is based on side of least penetration (as is the depth calculation).
- - Point is based on center of sphere
- - Sphere intersects one edge
- - Normal is based on vector from the box center to the point of depth.
- - Point is closest point to the sphere on the line
- - Sphere intersects one vertex
- - Normal is based on vector from the box center to the vertex of penetration.
- - Point is vertex of penetration.
+ Calculates the depth of penetration between a fixed sphere and a fixed
+ box as well as the deepest point of the sphere that penetrates the box
+ and the normal at that intersection.
+
+ @note There are three possible intersections between a sphere and box.
+ - Sphere completely contained in the box
+ - Sphere intersects one edge
+ - Sphere intersects one vertex
+
+ The contact point and contact normal vary for each of these situations.
+ - Sphere contained in Box:
+ - Normal is based on side of least penetration (as is the depth calculation).
+ - Point is based on center of sphere
+ - Sphere intersects one edge
+ - Normal is based on vector from the box center to the point of depth.
+ - Point is closest point to the sphere on the line
+ - Sphere intersects one vertex
+ - Normal is based on vector from the box center to the vertex of penetration.
+ - Point is vertex of penetration.
@cite Adapted from Jim Arvo's method in Graphics Gems
See also http://www.win.tue.nl/~gino/solid/gdc2001depth.pdf
- @param sphere Fixed Sphere.
- @param box Fixed Box.
- @param contactPoints Sphere point that penetrates the box. [Post Condition]
- @param contactNormals Normal at the penetration point. [Post Condition]
+ @param sphere Fixed Sphere.
+ @param box Fixed Box.
+ @param contactPoints Sphere point that penetrates the box. [Post Condition]
+ @param contactNormals Normal at the penetration point. [Post Condition]
- @return Depth of penetration. If there is no intersection between the
- objects then the depth will be a negative value.
- */
+ @return Depth of penetration. If there is no intersection between the
+ objects then the depth will be a negative value.
+ */
static float penetrationDepthForFixedSphereFixedBox(
const Sphere& sphere,
const Box& box,
Array<Vector3>& contactPoints,
Array<Vector3>& contactNormals = ignoreArray);
- /**
- Calculates the depth of penetration between a Fixed Sphere and a Fixed
- Plane as well as the deepest point of the sphere that penetrates the plane
- and the plane normal at that intersection.
-
- @param sphere Fixed Sphere.
- @param plane Fixed Plane.
- @param contactPoints Sphere point that penetrates the plane.
- [Post Condition]
- @param contactNormals Normal at penetration point. [Post Condition]
-
- @return Depth of penetration. If there is no intersection between the
- objects then the depth will be a negative value.
- */
+ /**
+ Calculates the depth of penetration between a Fixed Sphere and a Fixed
+ Plane as well as the deepest point of the sphere that penetrates the plane
+ and the plane normal at that intersection.
+
+ @param sphereA Fixed Sphere.
+ @param planeB Fixed Plane.
+ @param contactPoints Sphere point that penetrates the plane.
+ [Post Condition]
+ @param contactNormals Normal at penetration point. [Post Condition]
+
+ @return Depth of penetration. If there is no intersection between the
+ objects then the depth will be a negative value.
+ */
static float penetrationDepthForFixedSphereFixedPlane(
const Sphere& sphereA,
const class Plane& planeB,
Array<Vector3>& contactPoints,
Array<Vector3>& contactNormals = ignoreArray);
- /**
- Calculates the depth of penetration between a fixed box and a fixed
- plane as well as the vertexes of the box that penetrate the plane
- and the plane normals at those intersections.
-
- @param box Fixed Box.
- @param plane Fixed Plane.
- @param contactPoints Box points that penetrate the plane.
- [Post Condition]
- @param contactNormals Normals at penetration points [Post Condition]
-
- @return Depth of penetration. If there is no intersection between the
- objects then the depth will be a negative value.
- */
+ /**
+ Calculates the depth of penetration between a fixed box and a fixed
+ plane as well as the vertexes of the box that penetrate the plane
+ and the plane normals at those intersections.
+
+ @param box Fixed Box.
+ @param plane Fixed Plane.
+ @param contactPoints Box points that penetrate the plane.
+ [Post Condition]
+ @param contactNormals Normals at penetration points [Post Condition]
+
+ @return Depth of penetration. If there is no intersection between the
+ objects then the depth will be a negative value.
+ */
static float penetrationDepthForFixedBoxFixedPlane(
const Box& box,
const Plane& plane,
Array<Vector3>& contactPoints,
Array<Vector3>& contactNormals = ignoreArray);
- /**
- Calculates time between the intersection of a moving point and a fixed
- plane.
-
- @note This is only a one sided collision test. The side defined by
- the plane's surface normal is the only one tested. For a two sided
- collision, call the function once for each side's surface normal.
-
- @param point Moving point.
- @param velocity Point's velocity.
- @param plane Fixed plane.
- @param location Location of collision. [Post Condition]
- (Infinite vector on no collision)
- @param outNormal Plane's surface normal. [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ plane.
+
+ @note This is only a one sided collision test. The side defined by
+ the plane's surface normal is the only one tested. For a two sided
+ collision, call the function once for each side's surface normal.
+
+ @param point Moving point.
+ @param velocity Point's velocity.
+ @param plane Fixed plane.
+ @param location Location of collision. [Post Condition]
+ (Infinite vector on no collision)
+ @param outNormal Plane's surface normal. [Post Condition]
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingPointFixedPlane(
- const Vector3& point,
- const Vector3& velocity,
- const class Plane& plane,
- Vector3& outLocation,
+ const Vector3& point,
+ const Vector3& velocity,
+ const class Plane& plane,
+ Vector3& outLocation,
Vector3& outNormal = ignore);
- /**
- Calculates time between the intersection of a moving point and a fixed
- triangle.
-
- @note This is only a one sided collision test. The side defined by
- the triangle's surface normal is the only one tested. For a two sided
- collision, call the function once for each side's surface normal.
-
- @param orig Moving point.
- @param dir Point's velocity.
- @param v0 Triangle vertex 1.
- @param v1 Triangle vertex 2.
- @param v2 Triangle vertex 3
- @param location Location of collision. [Post Condition]
- (Infinite vector on no collision)
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ triangle.
+
+ @note This is only a one sided collision test. The side defined by
+ the triangle's surface normal is the only one tested. For a two sided
+ collision, call the function once for each side's surface normal.
+
+ @param orig Moving point.
+ @param dir Point's velocity.
+ @param v0 Triangle vertex 1.
+ @param v1 Triangle vertex 2.
+ @param v2 Triangle vertex 3
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
inline static float collisionTimeForMovingPointFixedTriangle(
const Vector3& orig,
const Vector3& dir,
@@ -488,25 +493,25 @@ public:
return Ray::fromOriginAndDirection(orig, dir).intersectionTime(v0, v1, v2);
}
- /**
- Calculates time between the intersection of a moving point and a fixed
- triangle.
-
- @note This is only a one sided collision test. The side defined by
- the triangle's surface normal is the only one tested. For a two sided
- collision, call the function once for each side's surface normal.
-
- @param orig Moving point.
- @param dir Point's velocity.
- @param v0 Triangle vertex 1.
- @param v1 Triangle vertex 2.
- @param v2 Triangle vertex 3
- @param location Location of collision. [Post Condition]
- (Infinite vector on no collision)
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ triangle.
+
+ @note This is only a one sided collision test. The side defined by
+ the triangle's surface normal is the only one tested. For a two sided
+ collision, call the function once for each side's surface normal.
+
+ @param orig Moving point.
+ @param dir Point's velocity.
+ @param v0 Triangle vertex 1.
+ @param v1 Triangle vertex 2.
+ @param v2 Triangle vertex 3
+ @param location Location of collision. [Post Condition]
+ (Infinite vector on no collision)
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
inline static float collisionTimeForMovingPointFixedTriangle(
const Vector3& orig,
const Vector3& dir,
@@ -515,30 +520,30 @@ public:
const Vector3& v2,
Vector3& location) {
float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2);
- if (t < inf()) {
+ if (t < finf()) {
location = orig + dir * t;
}
return t;
}
- /**
- Calculates time between the intersection of a moving point and a fixed
- triangle.
-
- @note This is only a one sided collision test. The side defined by
- the triangle's surface normal is the only one tested. For a two sided
- collision, call the function once for each side's surface normal.
-
- @param orig Moving point.
- @param dir Point's velocity.
- @param tri Fixed triangle.
- @param location Location of collision. [Post Condition]
- (Infinite vector on no collision)
- @param normal Triangle's surface normal. [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ triangle.
+
+ @note This is only a one sided collision test. The side defined by
+ the triangle's surface normal is the only one tested. For a two sided
+ collision, call the function once for each side's surface normal.
+
+ @param orig Moving point.
+ @param dir Point's velocity.
+ @param tri Fixed triangle.
+ @param location Location of collision. [Post Condition]
+ (Infinite vector on no collision)
+ @param normal Triangle's surface normal. [Post Condition]
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
inline static float collisionTimeForMovingPointFixedTriangle(
const Vector3& orig,
const Vector3& dir,
@@ -548,34 +553,34 @@ public:
float t = collisionTimeForMovingPointFixedTriangle(
orig, dir, tri.vertex(0), tri.vertex(1), tri.vertex(2));
-
- if ((t < inf()) && (&location != &ignore)) {
+
+ if ((t < finf()) && (&location != &ignore)) {
location = orig + dir * t;
normal = tri.normal();
}
return t;
}
- /**
- Calculates time between the intersection of a moving point and a fixed
- triangle.
-
- @note This is only a one sided collision test. The side defined by
- the triangle's surface normal is the only one tested. For a two sided
- collision, call the function once for each side's surface normal.
-
- @param orig Moving point.
- @param dir Point's velocity.
- @param v0 Triangle vertex 1.
- @param v1 Triangle vertex 2.
- @param v2 Triangle vertex 3
- @param location Location of collision. [Post Condition]
- (Infinite vector on no collision)
- @param normal Triangle's surface normal. [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ triangle.
+
+ @note This is only a one sided collision test. The side defined by
+ the triangle's surface normal is the only one tested. For a two sided
+ collision, call the function once for each side's surface normal.
+
+ @param orig Moving point.
+ @param dir Point's velocity.
+ @param v0 Triangle vertex 1.
+ @param v1 Triangle vertex 2.
+ @param v2 Triangle vertex 3
+ @param location Location of collision. [Post Condition]
+ (Infinite vector on no collision)
+ @param normal Triangle's surface normal. [Post Condition]
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
inline static float collisionTimeForMovingPointFixedTriangle(
const Vector3& orig,
const Vector3& dir,
@@ -585,570 +590,616 @@ public:
Vector3& location,
Vector3& normal) {
float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2);
- if (t < inf()) {
+ if (t < finf()) {
location = orig + dir * t;
- normal = (v2 - v0).cross(v1 - v0).direction();
+ normal = (v1 - v0).cross(v2 - v0).direction();
}
return t;
}
/**
- Unlike other methods, does not support an output normal.
If the ray origin is inside the box, returns inf() but inside
is set to true.
<B>Beta API</B>
@cite Andrew Woo, from "Graphics Gems", Academic Press, 1990
- @cite Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)
+ @cite Optimized code by Pierre Terdiman, 2000 (~20-30% faster on Celeron 500)
@cite Epsilon value added by Klaus Hartmann
@cite http://www.codercorner.com/RayAABB.cpp
*/
static float collisionTimeForMovingPointFixedAABox(
- const Vector3& point,
- const Vector3& velocity,
+ const Vector3& point,
+ const Vector3& velocity,
const class AABox& box,
- Vector3& outLocation,
+ Vector3& outLocation,
bool& inside = ignoreBool,
Vector3& outNormal = ignore);
/**
- Calculates time between the intersection of a moving point and a fixed
- Axis-Aligned Box (AABox).
+ Calculates time between the intersection of a moving point and a fixed
+ Axis-Aligned Box (AABox).
- @note Avoids the sqrt from collisionTimeForMovingPointFixedAABox.
+ @note Avoids the sqrt from collisionTimeForMovingPointFixedAABox.
- @param point Moving point.
- @param velocity Sphere's velocity.
- @param box Fixed AAbox.
- @param location Location of collision. [Post Condition]
- @param Inside Does the ray originate inside the box? [Post Condition]
- @param normal Box's surface normal to collision [Post Condition]
+ @param point Moving point.
+ @param velocity Sphere's velocity.
+ @param box Fixed AAbox.
+ @param location Location of collision. [Post Condition]
+ @param Inside Does the ray originate inside the box? [Post Condition]
+ @param normal Box's surface normal to collision [Post Condition]
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static bool collisionLocationForMovingPointFixedAABox(
- const Vector3& point,
- const Vector3& velocity,
+ const Vector3& point,
+ const Vector3& velocity,
const class AABox& box,
- Vector3& outLocation,
+ Vector3& outLocation,
bool& inside = ignoreBool,
Vector3& normal = ignore);
- /**
- Calculates time between the intersection of a moving point and a fixed
- sphere.
- @note When ray is starts inside the rectangle, the exiting intersection
- is detected.
+ /**
+ @brief Calculates intersection of a ray and a static
+ Axis-Aligned Box (AABox).
- @param point Moving point.
- @param velocity Point's velocity.
- @param Sphere Fixed Sphere.
- @param location Location of collision. [Post Condition]
- @param outNormal Sphere's surface normal to collision [Post Condition]
+ @note Avoids the sqrt from collisionTimeForMovingPointFixedAABox;
+ early-out branches and operations optimized for Intel Core2 architecture.
+
+ @param invDir 1/dir
+ @param location Location of collision. [Post Condition]
+ @param inside Does the ray originate inside the box? [Post Condition]
- @return Time til collision. If there is no collision then the return
- value will be inf().
+ @return True if the ray hits the box
*/
+ static bool __fastcall rayAABox(
+ const Ray& ray,
+ const Vector3& invDir,
+ const AABox& box,
+ const Vector3& boxCenter,
+ float boundingRadiusSquared,
+ Vector3& location,
+ bool& inside);
+
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ sphere.
+
+ @note When ray is starts inside the rectangle, the exiting intersection
+ is detected.
+
+ @param point Moving point.
+ @param velocity Point's velocity.
+ @param sphere Fixed Sphere.
+ @param outLocation Location of collision. [Post Condition]
+ @param outNormal Sphere's surface normal to collision [Post Condition]
+ \param solid If true, rays inside the sphere immediately intersect (good for collision detection). If false, they hit the opposite side of the sphere (good for ray tracing).
+
+ @return Time until collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingPointFixedSphere(
- const Vector3& point,
- const Vector3& velocity,
- const class Sphere& sphere,
- Vector3& outLocation,
- Vector3& outNormal = ignore);
+ const Vector3& point,
+ const Vector3& velocity,
+ const class Sphere& sphere,
+ Vector3& outLocation,
+ Vector3& outNormal = ignore,
+ bool solid = false);
/**
- Calculates time between the intersection of a moving point and a fixed
- box.
+ Calculates time between the intersection of a moving point and a fixed
+ box.
- @note If the point is already inside the box, no collision: inf is returned.
+ @note If the point is already inside the box, no collision: inf is returned.
- @param point Moving point.
- @param velocity Sphere's velocity.
- @param box Fixed box.
- @param location Position of collision. [Post Condition]
- @param outNormal Box's surface normal to collision [Post Condition]
+ @param point Moving point.
+ @param velocity Sphere's velocity.
+ @param box Fixed box.
+ @param location Position of collision. [Post Condition]
+ @param outNormal Box's surface normal to collision [Post Condition]
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingPointFixedBox(
- const Vector3& point,
- const Vector3& velocity,
- const class Box& box,
- Vector3& outLocation,
+ const Vector3& point,
+ const Vector3& velocity,
+ const class Box& box,
+ Vector3& outLocation,
Vector3& outNormal = ignore);
- /**
- Calculates time between the intersection of a moving point and a fixed
- rectangle defined by the points v0, v1, v2, & v3.
-
- @note This is only a one sided collision test. The side defined by
- the rectangle's surface normal is the only one tested. For a two sided
- collision, call the function once for each side's surface normal.
-
- @param point Moving point.
- @param velocity Sphere's velocity.
- @param v0 Rectangle vertex 1.
- @param v1 Rectangle vertex 2.
- @param v2 Rectangle vertex 3
- @param v3 Rectangle vertex 4.
- @param location Location of collision [Post Condition]
- @param outNormal Rectangle's surface normal. [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ rectangle defined by the points v0, v1, v2, & v3.
+
+ @note This is only a one sided collision test. The side defined by
+ the rectangle's surface normal is the only one tested. For a two sided
+ collision, call the function once for each side's surface normal.
+
+ @param point Moving point.
+ @param velocity Sphere's velocity.
+ @param v0 Rectangle vertex 1.
+ @param v1 Rectangle vertex 2.
+ @param v2 Rectangle vertex 3
+ @param v3 Rectangle vertex 4.
+ @param location Location of collision [Post Condition]
+ @param outNormal Rectangle's surface normal. [Post Condition]
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingPointFixedRectangle(
- const Vector3& point,
- const Vector3& velocity,
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- Vector3& outLocation,
+ const Vector3& point,
+ const Vector3& velocity,
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ Vector3& outLocation,
Vector3& outNormal = ignore);
- /**
- Calculates time between the intersection of a moving point and a fixed
- capsule.
+ /**
+ Calculates time between the intersection of a moving point and a fixed
+ capsule.
+
+ @param point Moving point.
+ @param velocity Point's velocity.
+ @param capsule Fixed capsule.
+ @param outLocation Location of collision. [Post Condition]
+ @param outNormal Capsule's surface normal to collision [Post Condition]
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
+ static float collisionTimeForMovingPointFixedCapsule(
+ const Vector3& point,
+ const Vector3& velocity,
+ const class Capsule& capsule,
+ Vector3& outLocation,
+ Vector3& outNormal = ignore);
- @param point Moving point.
- @param velocity Point's velocity.
- @param capsule Fixed capsule.
- @param location Location of collision. [Post Condition]
- @param outNormal Capsule's surface normal to collision [Post Condition]
+ /**
+ Calculates time between the intersection of a moving sphere and a fixed
+ triangle.
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
- static float collisionTimeForMovingPointFixedCapsule(
- const Vector3& point,
- const Vector3& velocity,
- const class Capsule& capsule,
- Vector3& outLocation,
- Vector3& outNormal = ignore);
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param plane Fixed Plane.
+ @param outLocation Location of collision -- not center position of sphere
+ at the collision time. [Post Condition]
+ @param outNormal Box's surface normal to collision [Post Condition]
- /**
- Calculates time between the intersection of a moving sphere and a fixed
- triangle.
-
- @param sphere Moving sphere.
- @param velocity Sphere's velocity.
- @param plane Fixed Plane.
- @param location Location of collision -- not center position of sphere
- at the collision time. [Post Condition]
- @param outNormal Box's surface normal to collision [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingSphereFixedPlane(
- const class Sphere& sphere,
- const Vector3& velocity,
- const class Plane& plane,
- Vector3& outLocation,
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const class Plane& plane,
+ Vector3& outLocation,
Vector3& outNormal = ignore);
- /**
- Calculates time between the intersection of a moving sphere and a fixed
- triangle.
-
- @param sphere Moving sphere.
- @param velocity Sphere's velocity.
- @param triangle Fixed Triangle.
- @param location Location of collision -- not center position of sphere
- at the collision time. [Post Condition]
- @param outNormal Box's surface normal to collision [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ /**
+ Calculates time between the intersection of a moving sphere and a fixed
+ triangle.
+
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param triangle Fixed Triangle. (collisions can happen on the back side of the triangle)
+ @param outLocation Location of collision, if collision occurs -- not center position of sphere
+ at the collision time. If there is interpenetration at the start, this point may be inside
+ the sphere.
+ @param b Barycentric coordinates. These are not valid unless collision occurs.
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingSphereFixedTriangle(
- const class Sphere& sphere,
- const Vector3& velocity,
- const Triangle& triangle,
- Vector3& outLocation,
- Vector3& outNormal = ignore);
-
- /**
- Calculates time between the intersection of a moving sphere and a fixed
- rectangle defined by the points v0, v1, v2, & v3.
-
- @param sphere Moving sphere.
- @param velocity Sphere's velocity.
- @param v0 Rectangle vertex 1.
- @param v1 Rectangle vertex 2.
- @param v2 Rectangle vertex 3
- @param v3 Rectangle vertex 4.
- @param location Location of collision -- not center position of sphere
- at the collision time. [Post Condition]
- @param outNormal Box's surface normal to collision [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const Triangle& triangle,
+ Vector3& outLocation,
+ float b[3] = (float*)&ignore);
+
+ /**
+ Calculates time between the intersection of a moving sphere and a fixed
+ rectangle defined by the points v0, v1, v2, & v3.
+
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param v0 Rectangle vertex 1.
+ @param v1 Rectangle vertex 2.
+ @param v2 Rectangle vertex 3
+ @param v3 Rectangle vertex 4.
+ @param outLocation Location of collision -- not center position of sphere
+ at the collision time. [Post Condition]
+ @param outNormal Box's surface normal to collision [Post Condition]
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingSphereFixedRectangle(
- const class Sphere& sphere,
- const Vector3& velocity,
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- Vector3& outLocation,
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ Vector3& outLocation,
Vector3& outNormal = ignore);
- /**
- Calculates time between the intersection of a moving sphere and a fixed
- box.
+ /**
+ Calculates time between the intersection of a moving sphere and a fixed
+ box.
- @note This function will not detect an intersection between a moving object
- that is already interpenetrating the fixed object.
+ @note This function will not detect an intersection between a moving object
+ that is already interpenetrating the fixed object.
- @param sphere Moving sphere.
- @param velocity Sphere's velocity.
- @param box Fixed box.
- @param location Location of collision -- not center position of sphere
- at the collision time. [Post Condition]
- @param outNormal Box's surface normal to collision [Post Condition]
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param box Fixed box.
+ @param location Location of collision -- not center position of sphere
+ at the collision time. [Post Condition]
+ @param outNormal Box's surface normal to collision [Post Condition]
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
static float collisionTimeForMovingSphereFixedBox(
- const class Sphere& sphere,
- const Vector3& velocity,
- const class Box& box,
- Vector3& outLocation,
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const class Box& box,
+ Vector3& outLocation,
Vector3& outNormal = ignore);
- /**
- Calculates time between the intersection of a moving sphere and a fixed
- sphere.
-
- @note This won't detect a collision if the sphere is already interpenetrating
- the fixed sphere.
-
- @param movingSphere Moving sphere.
- @param velocity Sphere's velocity.
- @param fixedSphere Fixed Sphere.
- @param location Location of collision -- not center position of sphere
- at the collision time. [Post Condition]
- @param outNormal Sphere's surface normal to collision [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
+ /** Calculates time between the intersection of a moving sphere
+ and a fixed sphere.
+
+ If they are already interpenetrating, returns 0 and @a
+ location is the closest point on the surface of the fixed sphere
+ to the center of the moving sphere.
+
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param fixedSphere Fixed Sphere.
+ @param outLocation Location of collision -- not center position of sphere
+ at the collision time. [Post Condition]
+ @param outNormal Moving sphere's surface normal to collision [Post Condition]
+
+ @return Time until collision. If there is no collision then the return
+ value will be inf().
*/
static float collisionTimeForMovingSphereFixedSphere(
- const class Sphere& sphere,
- const Vector3& velocity,
- const class Sphere& fixedSphere,
- Vector3& outLocation,
- Vector3& outNormal = ignore);
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Sphere& fixedSphere,
+ Vector3& outLocation,
+ Vector3& outNormal = ignore);
/**
- Calculates time between the intersection of a moving sphere and a fixed
- capsule.
-
- @note This won't detect a collision if the sphere is already
- interpenetrating the capsule.
-
- @param sphere Moving sphere.
- @param velocity Sphere's velocity.
- @param capsule Fixed capsule.
- @param location Location of collision -- not center position of sphere
- at the collision time. [Post Condition]
- @param outNormal Capsule's surface normal to the collision [Post Condition]
-
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
- static float collisionTimeForMovingSphereFixedCapsule(
- const class Sphere& sphere,
- const Vector3& velocity,
- const class Capsule& capsule,
- Vector3& outLocation,
+ Calculates time between the intersection of a moving sphere and a fixed
+ capsule.
+
+ @note This won't detect a collision if the sphere is already
+ interpenetrating the capsule.
+
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param capsule Fixed capsule.
+ @param location Location of collision -- not center position of sphere
+ at the collision time. [Post Condition]
+ @param outNormal Capsule's surface normal to the collision [Post Condition]
+
+ @return Time til collision. If there is no collision then the return
+ value will be inf().
+ */
+ static float collisionTimeForMovingSphereFixedCapsule(
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const class Capsule& capsule,
+ Vector3& outLocation,
Vector3& outNormal = ignore);
/**
- Finds the direction of bounce that a sphere would have when it
- intersects an object with the given time of collision, the
- collision location and the collision normal.
+ Finds the direction of bounce that a sphere would have when it
+ intersects an object with the given time of collision, the
+ collision location and the collision normal.
- @note This function works like a pong style ball bounce.
+ @note This function works like a pong style ball bounce.
- @param sphere Moving sphere.
- @param velocity Sphere's velocity.
- @param collisionTime Time of collision.
- @param collisionLocation Collision location.
- @param collisionNormal Surface collision normal.
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param collisionTime Time of collision.
+ @param collisionLocation Collision location.
+ @param collisionNormal Surface collision normal.
- @return Direction of bounce.
- */
+ @return Direction of bounce.
+ */
static Vector3 bounceDirection(
- const class Sphere& sphere,
- const Vector3& velocity,
- const float collisionTime,
- const Vector3& collisionLocation,
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const float collisionTime,
+ const Vector3& collisionLocation,
const Vector3& collisionNormal);
/**
- Finds the direction of slide given a moving sphere, its velocity, the
- time of collision and the collision location. This function works as
- if the sphere intersects the surface and continues to hug it.
+ Finds the direction of slide given a moving sphere, its velocity, the
+ time of collision and the collision location. This function works as
+ if the sphere intersects the surface and continues to hug it.
- @note The result will work well for calculating the movement of a player
- who collides with an object and continues moving along the object instead
- of just bouncing off it.
+ @note The result will work well for calculating the movement of a player
+ who collides with an object and continues moving along the object instead
+ of just bouncing off it.
- @param sphere Moving sphere.
- @param velocity Sphere's velocity.
- @param collisionTime Time of collision
- @param collisionLocation Collision location.
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param collisionTime Time of collision
+ @param collisionLocation Collision location.
- @return Direction of slide.
- */
+ @return Direction of slide.
+ */
static Vector3 slideDirection(
- const class Sphere& sphere,
- const Vector3& velocity,
- const float collisionTime,
- const Vector3& collisionLocation);
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const float collisionTime,
+ const Vector3& collisionLocation);
- /**
- Finds the closest point on a line segment to a given point.
+ /**
+ Finds the closest point on a line segment to a given point.
- @param v0 line vertex 1.
- @param v1 line vertex 2.
- @param point External point.
+ @param v0 line vertex 1.
+ @param v1 line vertex 2.
+ @param point External point.
- @return Closests point to <code>point</code> on the line segment.
- */
- static Vector3 closestPointOnLineSegment(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& point);
+ @return Closests point to <code>point</code> on the line segment.
+ */
+ static Vector3 closestPointOnLineSegment(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& point);
/**
- Finds the closest point on a line segment to a given point.
+ Finds the closest point on a line segment to a given point.
- @note This is an optimization to closestPointOnLineSegment. Edge length
- and direction can be used in this function if already pre-calculated. This
- prevents doing the same work twice.
+ @note This is an optimization to closestPointOnLineSegment. Edge length
+ and direction can be used in this function if already pre-calculated. This
+ prevents doing the same work twice.
- @param v0 line vertex 1.
- @param v1 line vertex 2.
+ @param v0 line vertex 0.
+ @param v1 line vertex 1.
@param edgeDirection The direction of the segment (unit length).
@param edgeLength The length of the segment.
@param point External point.
- @return Closests point to <code>point</code> on the line segment.
- */
+ @return Closests point to <code>point</code> on the line segment.
+ */
static Vector3 closestPointOnLineSegment(
- const Vector3& v0,
- const Vector3& v1,
+ const Vector3& v0,
+ const Vector3& v1,
const Vector3& edgeDirection,
- float edgeLength,
- const Vector3& point);
-
- /**
- Finds the closest point on the perimeter of the triangle to an external point;
- given a triangle defined by three points v0, v1, & v2, and the external point.
-
- @param v0 Triangle vertex 1.
- @param v1 Triangle vertex 2.
- @param v2 Triangle vertex 3.
- @param point External point.
-
- @return Closests point to <code>point</code> on the perimeter of the
- triangle.
- */
- static Vector3 closestPointToTrianglePerimeter(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& point);
+ float edgeLength,
+ const Vector3& point);
/**
- Finds the closest point on the perimeter of the triangle to an external point;
- given a triangle defined by the array of points v, its edge directions and
- their lengths, as well as the external point.
-
- @note This is an optimization to closestPointToTrianglePerimeter. Edge length
- and direction can be used in this function if already pre-calculated. This
- prevents doing the same work twice.
-
- @param v0 Triangle vertex 1.
- @param v1 Triangle vertex 2.
- @param v2 Triangle vertex 3.
- @param point External point.
-
- @return Closests point to <code>point</code> on the perimeter of the
- triangle.
- */
- static Vector3 closestPointToTrianglePerimeter(
+ Finds the closest point on the perimeter of the triangle to an external point;
+ given a triangle defined by three points v0, v1, & v2, and the external point.
+
+ @param v0 Triangle vertex 0.
+ @param v1 Triangle vertex 1.
+ @param v2 Triangle vertex 2.
+ @param point External point.
+
+ @return Closests point to <code>point</code> on the perimeter of the
+ triangle.
+ */
+ static Vector3 closestPointOnTrianglePerimeter(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& point);
+
+ /**
+ Finds the closest point on the perimeter of the triangle to an external point;
+ given a triangle defined by the array of points v, its edge directions and
+ their lengths, as well as the external point.
+
+ @note This is an optimization to closestPointToTrianglePerimeter. Edge length
+ and direction can be used in this function if already pre-calculated. This
+ prevents doing the same work twice.
+
+ @param v Triangle vertices.
+ @param point External point.
+ @param edgeIndex The point lies on the edge between v[edgeIndex] and v[(edgeIndex + 1) % 3]
+
+ @return Closest point to <code>point</code> on the perimeter of the
+ triangle.
+ */
+ static Vector3 closestPointOnTrianglePerimeter(
const Vector3 v[3],
const Vector3 edgeDirection[3],
- const double edgeLength[3],
- const Vector3& point);
+ const float edgeLength[3],
+ const Vector3& point,
+ int& edgeIndex);
/**
- Tests whether a point is contained within the triangle defined by
- v0, v1, & v2 and its plane's normal.
-
- @param v0 Triangle vertex 1.
- @param v1 Triangle vertex 2.
- @param v2 Triangle vertex 3.
- @param normal Normal to triangle's plane.
- @param point The point in question.
- @param primaryAxis Primary axis of triangle. This will be detected
- if not given. This parameter is provided as an optimization.
-
- @return true - if point is inside the triangle.
- @return false - otherwise
- */
+ Tests whether a point is contained within the triangle defined by
+ v0, v1, and v2 and its plane's normal.
+
+ @param v0 Triangle vertex 0.
+ @param v1 Triangle vertex 1.
+ @param v2 Triangle vertex 2.
+ @param normal Normal to triangle's plane.
+ @param point The point in question.
+ @param primaryAxis Primary axis of triangle. This will be detected
+ if not given. This parameter is provided as an optimization.
+ @param b Barycentric coordinates; b[i] is the weight on v[i]
+
+ @return true - if point is inside the triangle.
+ @return false - otherwise
+ */
static bool isPointInsideTriangle(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& normal,
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& normal,
const Vector3& point,
- Vector3::Axis primaryAxis = Vector3::DETECT_AXIS);
+ float b[3],
+ Vector3::Axis primaryAxis = Vector3::DETECT_AXIS);
+
+ inline static bool isPointInsideTriangle(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& normal,
+ const Vector3& point,
+ Vector3::Axis primaryAxis = Vector3::DETECT_AXIS) {
+
+ float b[3];
+ return isPointInsideTriangle(v0, v1, v2, normal, point, b, primaryAxis);
+ }
/**
- Tests for the intersection of a moving sphere and a fixed box in a
- given time limit.
+ Tests for the intersection of a moving sphere and a fixed box in a
+ given time limit.
- @note Returns true if any part of the sphere is inside the box
- during the time period (inf means "ever"). Useful for
- performing bounding-box collision detection.
+ @note Returns true if any part of the sphere is inside the box
+ during the time period (inf means "ever"). Useful for
+ performing bounding-box collision detection.
- @param sphere Moving sphere.
- @param velocity Velocity of moving sphere.
- @param box Fixed box.
- @param timeLimit Time limit for intersection test.
+ @param sphere Moving sphere.
+ @param velocity Velocity of moving sphere.
+ @param box Fixed box.
+ @param timeLimit Time limit for intersection test.
- @return true - if the two objects will touch.
- @return false - if there is no intersection.
- */
+ @return true - if the two objects will touch.
+ @return false - if there is no intersection.
+ */
static bool movingSpherePassesThroughFixedBox(
const Sphere& sphere,
const Vector3& velocity,
const Box& box,
double timeLimit = inf());
- /**
- Tests for the intersection of a moving sphere and a fixed sphere in a
- given time limit.
+ /**
+ Tests for the intersection of a moving sphere and a fixed sphere in a
+ given time limit.
- @note This function will not detect an intersection between a moving object
- that is already interpenetrating the fixed object.
+ @note This function will not detect an intersection between a moving object
+ that is already interpenetrating the fixed object.
- @param sphere Moving sphere.
- @param velocity Velocity of moving sphere.
- @param fixedSphere Fixed sphere.
- @param timeLimit Time limit for intersection test.
+ @param sphere Moving sphere.
+ @param velocity Velocity of moving sphere.
+ @param fixedSphere Fixed sphere.
+ @param timeLimit Time limit for intersection test.
- @return true - if the two spheres will touch.
- @return false - if there is no intersection.
- */
+ @return true - if the two spheres will touch.
+ @return false - if there is no intersection.
+ */
static bool movingSpherePassesThroughFixedSphere(
const Sphere& sphere,
const Vector3& velocity,
const Sphere& fixedSphere,
double timeLimit = inf());
- /**
- Tests for the intersection of two fixed spheres.
+ /**
+ Tests for the intersection of two fixed spheres.
- @param sphere1 Fixed sphere 1.
- @param sphere2 Fixed sphere 2.
+ @param sphere1 Fixed sphere 1.
+ @param sphere2 Fixed sphere 2.
- @return true - if the two spheres touch.
- @return false - if there is no intersection.
- */
+ @return true - if the two spheres touch.
+ @return false - if there is no intersection.
+ */
static bool fixedSolidSphereIntersectsFixedSolidSphere(
const Sphere& sphere1,
const Sphere& sphere2);
- /**
- Tests for the intersection of a fixed sphere and a fixed box.
+ /**
+ Tests for the intersection of a fixed sphere and a fixed box.
- @param sphere Fixed sphere.
- @param box Fixed box.
+ @param sphere Fixed sphere.
+ @param box Fixed box.
- @return true - if the two objects touch.
- @return false - if there is no intersection.
- */
+ @return true - if the two objects touch.
+ @return false - if there is no intersection.
+ */
static bool fixedSolidSphereIntersectsFixedSolidBox(
const Sphere& sphere,
const Box& box);
+ static bool fixedSolidSphereIntersectsFixedTriangle(
+ const Sphere& sphere,
+ const Triangle& triangle);
+
+ static bool fixedSolidBoxIntersectsFixedTriangle(
+ const AABox& box,
+ const Triangle& triangle);
+
/**
- Tests whether a point is inside a rectangle defined by the vertexes
- v0, v1, v2, & v3, and the rectangle's plane normal.
-
- @param v0 Rectangle vertex 1.
- @param v1 Rectangle vertex 2.
- @param v2 Rectangle vertex 3.
- @param v3 Rectangle vertex 4.
- @param normal Normal to rectangle's plane.
- @param point The point in question.
-
- @return true - if point is inside the rectangle.
- @return false - otherwise
- */
+ Tests whether a point is inside a rectangle defined by the vertexes
+ v0, v1, v2, & v3, and the rectangle's plane normal.
+
+ @param v0 Rectangle vertex 1.
+ @param v1 Rectangle vertex 2.
+ @param v2 Rectangle vertex 3.
+ @param v3 Rectangle vertex 4.
+ @param normal Normal to rectangle's plane.
+ @param point The point in question.
+
+ @return true - if point is inside the rectangle.
+ @return false - otherwise
+ */
static bool isPointInsideRectangle(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- const Vector3& normal,
- const Vector3& point);
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ const Vector3& normal,
+ const Vector3& point);
/**
- Finds the closest point on the perimeter of the rectangle to an
- external point; given a rectangle defined by four points v0, v1,
- v2, & v3, and the external point.
-
- @param v0 Rectangle vertex 1.
- @param v1 Rectangle vertex 2.
- @param v2 Rectangle vertex 3.
- @param v3 Rectangle vertex 4.
- @param point External point.
-
- @return Closests point to <code>point</code> on the perimeter of the
- rectangle.
- */
+ Finds the closest point on the perimeter of the rectangle to an
+ external point; given a rectangle defined by four points v0, v1,
+ v2, & v3, and the external point.
+
+ @param v0 Rectangle vertex 1.
+ @param v1 Rectangle vertex 2.
+ @param v2 Rectangle vertex 3.
+ @param v3 Rectangle vertex 4.
+ @param point External point.
+
+ @return Closests point to <code>point</code> on the perimeter of the
+ rectangle.
+ */
static Vector3 closestPointToRectanglePerimeter(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- const Vector3& point);
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ const Vector3& point);
/**
- Finds the closest point in the rectangle to an external point; Given
- a rectangle defined by four points v0, v1, v2, & v3, and the external
- point.
+ Finds the closest point in the rectangle to an external point; Given
+ a rectangle defined by four points v0, v1, v2, & v3, and the external
+ point.
- @param v0 Rectangle vertex 1.
- @param v1 Rectangle vertex 2.
- @param v2 Rectangle vertex 3
- @param v3 Rectangle vertex 4.
- @param point External point.
+ @param v0 Rectangle vertex 1.
+ @param v1 Rectangle vertex 2.
+ @param v2 Rectangle vertex 3
+ @param v3 Rectangle vertex 4.
+ @param point External point.
@return Closet point in the rectangle to the external point.
- */
- static Vector3 closestPointToRectangle(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- const Vector3& point);
+ */
+ static Vector3 closestPointToRectangle(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ const Vector3& point);
};
} // namespace
#endif // G3D_COLLISIONDETECTION_H
-
diff --git a/dep/include/g3dlite/G3D/Color1.h b/dep/include/g3dlite/G3D/Color1.h
new file mode 100644
index 00000000000..0f68c84b363
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Color1.h
@@ -0,0 +1,144 @@
+/**
+ @file Color1.h
+
+ Monochrome Color class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2007-01-31
+ @edited 2009-03-20
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_COLOR1_H
+#define G3D_COLOR1_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/HashTrait.h"
+#include <string>
+
+namespace G3D {
+
+/**
+ Monochrome color. This is just a float, but it has nice semantics
+ because a scaling by 255 automatically occurs when switching between
+ fixed point (Color1uint8) and floating point (Color1) formats.
+ */
+class Color1 {
+private:
+ // Hidden operators
+ bool operator<(const Color1&) const;
+ bool operator>(const Color1&) const;
+ bool operator<=(const Color1&) const;
+ bool operator>=(const Color1&) const;
+
+public:
+ float value;
+
+ /**
+ Initializes to 0
+ */
+ inline Color1() : value(0) {}
+
+ Color1(class BinaryInput& bi);
+
+ inline explicit Color1(float v) : value(v) {
+ }
+
+ inline bool isZero() const {
+ return value == 0.0f;
+ }
+
+ inline bool isOne() const {
+ return value == 1.0f;
+ }
+
+ static const Color1& one();
+
+ static const Color1& zero();
+
+ /** Returns the value three times */
+ class Color3 rgb() const;
+
+ Color1 (const class Color1uint8& other);
+
+ void serialize(class BinaryOutput& bo) const;
+ void deserialize(class BinaryInput& bi);
+
+ Color1 operator+ (const Color1& other) const {
+ return Color1(value + other.value);
+ }
+
+ Color1 operator+ (const float other) const {
+ return Color1(value + other);
+ }
+
+ Color1& operator+= (const Color1 other) {
+ value += other.value;
+ return *this;
+ }
+
+ Color1& operator-= (const Color1 other) {
+ value -= other.value;
+ return *this;
+ }
+
+ Color1 operator- (const Color1& other) const {
+ return Color1(value - other.value);
+ }
+
+ Color1 operator- (const float other) const {
+ return Color1(value - other);
+ }
+
+ Color1 operator- () const {
+ return Color1(-value);
+ }
+
+ Color1 operator* (const Color1& other) const {
+ return Color1(value * other.value);
+ }
+
+ Color1 operator* (const float other) const {
+ return Color1(value * other);
+ }
+
+ Color1 operator/ (const Color1& other) const {
+ return Color1(value / other.value);
+ }
+
+ Color1 operator/ (const float other) const {
+ return Color1(value / other);
+ }
+
+ inline Color1 max(const Color1& other) const {
+ return Color1(G3D::max(value, other.value));
+ }
+
+ inline Color1 min(const Color1& other) const {
+ return Color1(G3D::min(value, other.value));
+ }
+
+ inline Color1 lerp(const Color1& other, float a) const {
+ return Color1(value + (other.value - value) * a);
+
+ }
+
+ inline size_t hashCode() const {
+ return (size_t)(value * 0xFFFFFF);
+ }
+};
+
+}
+
+template <>
+struct HashTrait<G3D::Color1> {
+ static size_t hashCode(const G3D::Color1& key) {
+ return key.hashCode();
+ }
+};
+
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Color1uint8.h b/dep/include/g3dlite/G3D/Color1uint8.h
new file mode 100644
index 00000000000..092099d0d17
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Color1uint8.h
@@ -0,0 +1,91 @@
+/**
+ @file Color1uint8.h
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2007-01-30
+ @edited 2007-01-30
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_COLOR1UINT8_H
+#define G3D_COLOR1UINT8_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+/**
+ Represents a Color1 as a packed integer. Convenient
+ for creating unsigned int vertex arrays.
+
+ <B>WARNING</B>: Integer color formats are different than
+ integer vertex formats. The color channels are automatically
+ scaled by 255 (because OpenGL automatically scales integer
+ colors back by this factor). So Color3(1,1,1) == Color3uint8(255,255,255)
+ but Vector3(1,1,1) == Vector3int16(1,1,1).
+
+ <B>Note</B>:
+ Conversion of a float32 to uint8 is accomplished by min(iFloor(f * 256)) and
+ back to float32 by u / 255.0f. This gives equal size intervals.
+Consider a number line from 0 to 1 and a corresponding one from 0 to 255. If we use iRound(x * 255), then the mapping for three critical intervals are:
+
+<pre>
+let s = 0.5/255
+ float int size
+[0, s) -> 0 s
+[s, s * 3) -> 1 2*s
+(1 - s, 1] -> 255 s
+</pre>
+
+If we use max(floor(x * 256), 255), then we get:
+
+<pre>
+let s = 1/256
+ float int size
+[0, s) -> 0 s
+[s, 2 * s) -> 1 s
+(1 - s, 1] -> 255 s
+</PRE>
+and the intervals are all the same size, thus giving equal precision to all values.
+ */
+G3D_BEGIN_PACKED_CLASS(1)
+class Color1uint8 {
+private:
+ // Hidden operators
+ bool operator<(const Color1uint8&) const;
+ bool operator>(const Color1uint8&) const;
+ bool operator<=(const Color1uint8&) const;
+ bool operator>=(const Color1uint8&) const;
+
+public:
+
+ uint8 value;
+
+ Color1uint8() : value(0) {}
+
+ explicit Color1uint8(const uint8 _v) : value(_v) {}
+
+ Color1uint8(const class Color1& c);
+
+ Color1uint8(class BinaryInput& bi);
+
+ void serialize(class BinaryOutput& bo) const;
+
+ void deserialize(class BinaryInput& bi);
+
+ inline bool operator==(const Color1uint8& other) const {
+ return value == other.value;
+ }
+
+ inline bool operator!=(const Color1uint8& other) const {
+ return value != other.value;
+ }
+
+}
+G3D_END_PACKED_CLASS(1)
+}
+#endif
diff --git a/dep/include/g3dlite/G3D/Color3.h b/dep/include/g3dlite/G3D/Color3.h
new file mode 100644
index 00000000000..bffe434fc27
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Color3.h
@@ -0,0 +1,432 @@
+/**
+ @file Color3.h
+
+ Color class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Portions based on Dave Eberly's Magic Software Library
+ at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
+
+ @created 2001-06-02
+ @edited 2009-04-28
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Color3_h
+#define G3D_Color3_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/HashTrait.h"
+#include "G3D/Color1.h"
+#include <string>
+
+namespace G3D {
+class Any;
+
+/**
+ Do not subclass-- this implementation makes assumptions about the
+ memory layout.
+ */
+class Color3 {
+private:
+ // Hidden operators
+ bool operator<(const Color3&) const;
+ bool operator>(const Color3&) const;
+ bool operator<=(const Color3&) const;
+ bool operator>=(const Color3&) const;
+
+public:
+ /**
+ Does not initialize fields.
+ */
+ Color3();
+
+ /** \param any Must be in one of the following forms:
+ - Color3(#, #, #)
+ - Color3::fromARGB(#)
+ - Color3{r = #, g = #, b = #)
+ - Color3::one()
+ - Color3::zero()
+ */
+ Color3(const Any& any);
+
+ /** Converts the Color3 to an Any. */
+ operator Any() const;
+
+ explicit Color3(class BinaryInput& bi);
+
+ Color3(float r, float g, float b);
+ Color3(float v) : r(v), g(v), b(v) {}
+
+ explicit Color3(const class Vector3& v);
+
+ explicit Color3(const float value[3]);
+
+ /** Returns this color */
+ const Color3& rgb() const {
+ return *this;
+ }
+
+ /**
+ Initialize from another color.
+ */
+ Color3 (const Color3& other);
+
+ Color3 (const class Color3uint8& other);
+
+ inline bool isZero() const {
+ return (r == 0.0f) && (g == 0.0f) && (b == 0.0f);
+ }
+
+ inline bool isOne() const {
+ return (r == 1.0f) && (g == 1.0f) && (b == 1.0f);
+ }
+
+ bool isFinite() const;
+
+ /**
+ Initialize from an HTML-style color (e.g. 0xFF0000 == RED)
+ */
+ static Color3 fromARGB(uint32);
+
+ /** Returns one of the color wheel colors (e.g. RED, GREEN, CYAN).
+ Does not include white, black, or gray. */
+ static const Color3& wheelRandom();
+
+ /** Generate colors according to the ANSI color set, mod 16.
+ \sa pastelMap */
+ static Color3 ansiMap(uint32 i);
+
+ /**
+ Generate colors using a hash such that adjacent values
+ are unlikely to have similar colors.
+
+ Useful for rendering with
+ stable but arbitrary colors, e.g., when debugging a mesh
+ algorithm.
+
+ \sa ansiMap
+ */
+ static Color3 pastelMap(uint32 i);
+
+ /**
+ * Channel value.
+ */
+ float r, g, b;
+
+ void serialize(class BinaryOutput& bo) const;
+ void deserialize(class BinaryInput& bi);
+
+ // access vector V as V[0] = V.r, V[1] = V.g, V[2] = V.b
+ //
+ // WARNING. These member functions rely on
+ // (1) Color3 not having virtual functions
+ // (2) the data packed in a 3*sizeof(float) memory block
+ const float& operator[] (int i) const;
+ float& operator[] (int i);
+
+ // assignment and comparison
+ Color3& operator= (const Color3& rkVector);
+ bool operator== (const Color3& rkVector) const;
+ bool operator!= (const Color3& rkVector) const;
+ size_t hashCode() const;
+
+ // arithmetic operations
+ Color3 operator+ (const Color3& rkVector) const;
+ Color3 operator- (const Color3& rkVector) const;
+ inline Color3 operator* (float s) const {
+ return Color3(r * s, g * s, b * s);
+ }
+ Color3 operator* (const Color3& rkVector) const;
+ inline Color3 operator/ (float fScalar) const {
+ return (*this) * (1.0f / fScalar);
+ }
+ Color3 operator- () const;
+
+ // arithmetic updates
+ Color3& operator+= (const Color3& rkVector);
+ Color3& operator-= (const Color3& rkVector);
+ Color3& operator*= (const Color3& rkVector);
+ Color3& operator*= (float fScalar);
+ Color3& operator/= (float fScalar);
+
+ bool fuzzyEq(const Color3& other) const;
+ bool fuzzyNe(const Color3& other) const;
+
+ // vector operations
+ float length () const;
+ Color3 direction() const;
+ float squaredLength () const;
+ float dot (const Color3& rkVector) const;
+ float unitize (float fTolerance = 1e-06);
+ Color3 cross (const Color3& rkVector) const;
+ Color3 unitCross (const Color3& rkVector) const;
+
+ inline Color3 pow(const Color3& other) const {
+ return Color3(::pow(r, other.r), ::pow(g, other.g), ::pow(b, other.b));
+ }
+
+ inline Color3 pow(float other) const {
+ return Color3(::pow(r, other), ::pow(g, other), ::pow(b, other));
+ }
+
+ inline Color3 max(const Color3& other) const {
+ return Color3(G3D::max(r, other.r), G3D::max(g, other.g), G3D::max(b, other.b));
+ }
+
+ inline Color3 min(const Color3& other) const {
+ return Color3(G3D::min(r, other.r), G3D::min(g, other.g), G3D::min(b, other.b));
+ }
+
+ /** Smallest element */
+ inline float min() const {
+ return G3D::min(G3D::min(r, g), b);
+ }
+
+ /** Largest element */
+ inline float max() const {
+ return G3D::max(G3D::max(r, g), b);
+ }
+
+ inline Color3 lerp(const Color3& other, float a) const {
+ return (*this) + (other - *this) * a;
+
+ }
+
+ inline float sum() const {
+ return r + g + b;
+ }
+
+ inline float average() const {
+ return sum() / 3.0f;
+ }
+
+
+ /**
+ * Converts from HSV to RGB , note: toHSV(fromHSV(_hsv)) may not be _hsv, if it is at a grey point or black point.
+ * The components of _hsv should lie in the unit interval.
+ * @cite Alvy Ray Smith SIGGRAPH 1978 "Color Gamut Transform Pairs"
+ **/
+ static Color3 fromHSV(const Vector3& _hsv);
+ static Vector3 toHSV(const Color3& _rgb);
+
+ /** Duplicates the matlab jet colormap maps [0,1] --> (r,g,b) where blue is close to 0 and red is close to 1. */
+ static Color3 jetColorMap(const float& val);
+
+ /** Returns colors with maximum saturation and value @param hue [0, 1]*/
+ static Color3 rainbowColorMap(float hue);
+
+ std::string toString() const;
+
+ /** Random unit vector */
+ static Color3 random();
+
+ // Special values.
+ // Intentionally not inlined: see Matrix3::identity() for details.
+ static const Color3& red();
+ static const Color3& green();
+ static const Color3& blue();
+ static const Color3& purple();
+ static const Color3& cyan();
+ static const Color3& yellow();
+ static const Color3& brown();
+ static const Color3& orange();
+ static const Color3& black();
+ static const Color3& gray();
+ static const Color3& white();
+
+ static const Color3& zero();
+ static const Color3& one();
+
+ inline Color3 bgr() const {
+ return Color3(b, g, r);
+ }
+};
+
+inline G3D::Color3 operator* (float s, const G3D::Color3& c) {
+ return c * s;
+}
+
+inline G3D::Color3 operator* (G3D::Color1& s, const G3D::Color3& c) {
+ return c * s.value;
+}
+
+inline G3D::Color3 operator* (const G3D::Color3& c, G3D::Color1& s) {
+ return c * s.value;
+}
+
+
+//----------------------------------------------------------------------------
+inline Color3::Color3 () {
+}
+
+//----------------------------------------------------------------------------
+
+inline Color3::Color3(float fX, float fY, float fZ) {
+ r = fX;
+ g = fY;
+ b = fZ;
+}
+
+//----------------------------------------------------------------------------
+inline Color3::Color3(const float afCoordinate[3]) {
+ r = afCoordinate[0];
+ g = afCoordinate[1];
+ b = afCoordinate[2];
+}
+
+//----------------------------------------------------------------------------
+inline Color3::Color3 (const Color3& rkVector) {
+ r = rkVector.r;
+ g = rkVector.g;
+ b = rkVector.b;
+}
+
+//----------------------------------------------------------------------------
+inline float& Color3::operator[] (int i) {
+ return ((float*)this)[i];
+}
+
+//----------------------------------------------------------------------------
+
+inline const float& Color3::operator[] (int i) const {
+ return ((float*)this)[i];
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Color3::fuzzyEq(const Color3& other) const {
+ return G3D::fuzzyEq((*this - other).squaredLength(), 0);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Color3::fuzzyNe(const Color3& other) const {
+ return G3D::fuzzyNe((*this - other).squaredLength(), 0);
+}
+
+
+//----------------------------------------------------------------------------
+inline Color3& Color3::operator= (const Color3& rkVector) {
+ r = rkVector.r;
+ g = rkVector.g;
+ b = rkVector.b;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline bool Color3::operator== (const Color3& rkVector) const {
+ return ( r == rkVector.r && g == rkVector.g && b == rkVector.b );
+}
+
+//----------------------------------------------------------------------------
+inline bool Color3::operator!= (const Color3& rkVector) const {
+ return ( r != rkVector.r || g != rkVector.g || b != rkVector.b );
+}
+
+//----------------------------------------------------------------------------
+inline Color3 Color3::operator+ (const Color3& rkVector) const {
+ return Color3(r + rkVector.r, g + rkVector.g, b + rkVector.b);
+}
+
+//----------------------------------------------------------------------------
+inline Color3 Color3::operator- (const Color3& rkVector) const {
+ return Color3(r -rkVector.r, g - rkVector.g, b - rkVector.b);
+}
+
+//----------------------------------------------------------------------------
+inline Color3 Color3::operator* (const Color3& rkVector) const {
+ return Color3(r * rkVector.r, g * rkVector.g, b * rkVector.b);
+}
+
+//----------------------------------------------------------------------------
+inline Color3 Color3::operator- () const {
+ return Color3( -r, -g, -b);
+}
+
+//----------------------------------------------------------------------------
+inline Color3& Color3::operator+= (const Color3& rkVector) {
+ r += rkVector.r;
+ g += rkVector.g;
+ b += rkVector.b;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Color3& Color3::operator-= (const Color3& rkVector) {
+ r -= rkVector.r;
+ g -= rkVector.g;
+ b -= rkVector.b;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Color3& Color3::operator*= (float fScalar) {
+ r *= fScalar;
+ g *= fScalar;
+ b *= fScalar;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Color3& Color3::operator*= (const Color3& rkVector) {
+ r *= rkVector.r;
+ g *= rkVector.g;
+ b *= rkVector.b;
+ return *this;
+}
+//----------------------------------------------------------------------------
+inline float Color3::squaredLength () const {
+ return r*r + g*g + b*b;
+}
+
+//----------------------------------------------------------------------------
+inline float Color3::length () const {
+ return sqrtf(r*r + g*g + b*b);
+}
+
+//----------------------------------------------------------------------------
+inline Color3 Color3::direction () const {
+ float lenSquared = r * r + g * g + b * b;
+
+ if (lenSquared != 1.0f) {
+ return *this / sqrtf(lenSquared);
+ } else {
+ return *this;
+ }
+}
+
+//----------------------------------------------------------------------------
+inline float Color3::dot (const Color3& rkVector) const {
+ return r*rkVector.r + g*rkVector.g + b*rkVector.b;
+}
+
+//----------------------------------------------------------------------------
+inline Color3 Color3::cross (const Color3& rkVector) const {
+ return Color3(g*rkVector.b - b*rkVector.g, b*rkVector.r - r*rkVector.b,
+ r*rkVector.g - g*rkVector.r);
+}
+
+//----------------------------------------------------------------------------
+inline Color3 Color3::unitCross (const Color3& rkVector) const {
+ Color3 kCross(g*rkVector.b - b*rkVector.g, b*rkVector.r - r*rkVector.b,
+ r*rkVector.g - g*rkVector.r);
+ kCross.unitize();
+ return kCross;
+}
+
+
+} // namespace
+
+
+template <> struct HashTrait<G3D::Color3> {
+ static size_t hashCode(const G3D::Color3& key) {
+ return key.hashCode();
+ }
+};
+
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Color3uint8.h b/dep/include/g3dlite/G3D/Color3uint8.h
new file mode 100644
index 00000000000..bd4b00d7fd6
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Color3uint8.h
@@ -0,0 +1,110 @@
+/**
+ @file Color3uint8.h
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2003-04-07
+ @edited 2006-06-24
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_COLOR3UINT8_H
+#define G3D_COLOR3UINT8_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+/**
+ Represents a Color3 as a packed integer. Convenient
+ for creating unsigned int vertex arrays. Used by
+ G3D::GImage as the underlying format.
+
+ <B>WARNING</B>: Integer color formats are different than
+ integer vertex formats. The color channels are automatically
+ scaled by 255 (because OpenGL automatically scales integer
+ colors back by this factor). So Color3(1,1,1) == Color3uint8(255,255,255)
+ but Vector3(1,1,1) == Vector3int16(1,1,1).
+ */
+
+G3D_BEGIN_PACKED_CLASS(1)
+
+class Color3uint8 {
+private:
+ // Hidden operators
+ bool operator<(const Color3uint8&) const;
+ bool operator>(const Color3uint8&) const;
+ bool operator<=(const Color3uint8&) const;
+ bool operator>=(const Color3uint8&) const;
+
+public:
+ uint8 r;
+ uint8 g;
+ uint8 b;
+
+ Color3uint8() : r(0), g(0), b(0) {}
+
+ Color3uint8(const uint8 _r, const uint8 _g, const uint8 _b) : r(_r), g(_g), b(_b) {}
+
+ Color3uint8(const class Color3& c);
+
+ Color3uint8(class BinaryInput& bi);
+
+ inline static Color3uint8 fromARGB(uint32 i) {
+ Color3uint8 c;
+ c.r = (i >> 16) & 0xFF;
+ c.g = (i >> 8) & 0xFF;
+ c.b = i & 0xFF;
+ return c;
+ }
+
+ inline Color3uint8 bgr() const {
+ return Color3uint8(b, g, r);
+ }
+
+ /**
+ Returns the color packed into a uint32
+ (the upper byte is 0xFF)
+ */
+ inline uint32 asUInt32() const {
+ return (0xFF << 24) + ((uint32)r << 16) + ((uint32)g << 8) + b;
+ }
+
+ void serialize(class BinaryOutput& bo) const;
+
+ void deserialize(class BinaryInput& bi);
+
+ // access vector V as V[0] = V.r, V[1] = V.g, V[2] = V.b
+ //
+ // WARNING. These member functions rely on
+ // (1) Color3 not having virtual functions
+ // (2) the data packed in a 3*sizeof(uint8) memory block
+ uint8& operator[] (int i) const {
+ debugAssert((unsigned int)i < 3);
+ return ((uint8*)this)[i];
+ }
+
+ operator uint8* () {
+ return (G3D::uint8*)this;
+ }
+
+ operator const uint8* () const {
+ return (uint8*)this;
+ }
+
+ bool operator==(const Color3uint8& other) const {
+ return (other.r == r) && (other.g == g) && (other.b == b);
+ }
+
+ bool operator!=(const Color3uint8& other) const {
+ return (other.r != r) && (other.g != g) && (other.b != b);
+ }
+}
+G3D_END_PACKED_CLASS(1)
+
+} // namespace G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Color4.h b/dep/include/g3dlite/G3D/Color4.h
new file mode 100644
index 00000000000..d8858abbce2
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Color4.h
@@ -0,0 +1,338 @@
+/**
+ @file Color4.h
+
+ Color class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Portions based on Dave Eberly's Magic Software Library
+ at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
+
+ @created 2002-06-25
+ @edited 2009-11-15
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Color4_h
+#define G3D_Color4_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Color3.h"
+#include <string>
+
+namespace G3D {
+
+class Any;
+
+/**
+ Do not subclass-- this implementation makes assumptions about the
+ memory layout.
+ */
+class Color4 {
+private:
+ // Hidden operators
+ bool operator<(const Color4&) const;
+ bool operator>(const Color4&) const;
+ bool operator<=(const Color4&) const;
+ bool operator>=(const Color4&) const;
+
+public:
+
+ /** \param any Must be in one of the following forms:
+ - Color4(#, #, #, #)
+ - Color4::fromARGB(#)
+ - Color4{r = #, g = #, b = #, a = #)
+ */
+ Color4(const Any& any);
+
+ /** Converts the Color4 to an Any. */
+ operator Any() const;
+
+ /**
+ * Does not initialize fields.
+ */
+ Color4 ();
+
+ Color4(const Color3& c3, float a = 1.0);
+
+ Color4(const class Color4uint8& c);
+
+ Color4(class BinaryInput& bi);
+
+ Color4(const class Vector4& v);
+
+ Color4(float r, float g, float b, float a = 1.0);
+
+ static const Color4& one();
+
+ Color4(float value[4]);
+
+ /**
+ * Initialize from another color.
+ */
+ Color4(const Color4& other);
+
+
+ inline bool isZero() const {
+ return (r == 0.0f) && (g == 0.0f) && (b == 0.0f) && (a == 0.0f);
+ }
+
+ inline bool isOne() const {
+ return (r == 1.0f) && (g == 1.0f) && (b == 1.0f) && (a == 1.0f);
+ }
+
+ void serialize(class BinaryOutput& bo) const;
+ void deserialize(class BinaryInput& bi);
+
+ /**
+ Initialize from an HTML-style color (e.g. 0xFFFF0000 == RED)
+ */
+ static Color4 fromARGB(uint32);
+
+ /**
+ * Channel values.
+ */
+ float r, g, b, a;
+
+ inline Color3 rgb() const {
+ return Color3(r, g, b);
+ }
+
+ // access vector V as V[0] = V.r, V[1] = V.g, V[2] = V.b, v[3] = V.a
+ //
+ // WARNING. These member functions rely on
+ // (1) Color4 not having virtual functions
+ // (2) the data packed in a 3*sizeof(float) memory block
+ float& operator[] (int i) const;
+
+ // assignment and comparison
+ Color4& operator= (const Color4& rkVector);
+ bool operator== (const Color4& rkVector) const;
+ bool operator!= (const Color4& rkVector) const;
+ size_t hashCode() const;
+
+ // arithmetic operations
+ Color4 operator+ (const Color4& rkVector) const;
+ Color4 operator- (const Color4& rkVector) const;
+ Color4 operator* (float fScalar) const;
+ inline Color4 operator* (const Color4& k) const {
+ return Color4(r*k.r, g*k.g, b*k.b, a * k.a);
+ }
+ Color4 operator/ (float fScalar) const;
+ Color4 operator- () const;
+ friend Color4 operator* (double fScalar, const Color4& rkVector);
+
+ // arithmetic updates
+ Color4& operator+= (const Color4& rkVector);
+ Color4& operator-= (const Color4& rkVector);
+ Color4& operator*= (float fScalar);
+ Color4& operator/= (float fScalar);
+
+ bool fuzzyEq(const Color4& other) const;
+ bool fuzzyNe(const Color4& other) const;
+
+ std::string toString() const;
+
+ inline Color4 max(const Color4& other) const {
+ return Color4(G3D::max(r, other.r), G3D::max(g, other.g), G3D::max(b, other.b), G3D::max(a, other.a));
+ }
+
+ inline Color4 min(const Color4& other) const {
+ return Color4(G3D::min(r, other.r), G3D::min(g, other.g), G3D::min(b, other.b), G3D::min(a, other.a));
+ }
+
+ /** r + g + b + a */
+ inline float sum() const {
+ return r + g + b + a;
+ }
+
+ inline Color4 lerp(const Color4& other, float a) const {
+ return (*this) + (other - *this) * a;
+
+ }
+
+ // Special values.
+ // Intentionally not inlined: see Matrix3::identity() for details.
+ static const Color4& zero();
+ static const Color4& clear();
+
+ static const Color4& inf();
+ static const Color4& nan();
+
+ inline bool isFinite() const {
+ return G3D::isFinite(r) && G3D::isFinite(g) && G3D::isFinite(b) && G3D::isFinite(a);
+ }
+
+ inline Color3 bgr() const {
+ return Color3(b, g, r);
+ }
+};
+
+/**
+ Extends the c3 with alpha = 1.0
+ */
+Color4 operator*(const Color3& c3, const Color4& c4);
+
+
+inline Color4 operator*(const Color3& c3, const Color4& c4) {
+ return Color4(c3.r * c4.r, c3.g * c4.g, c3.b * c4.b, c4.a);
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4::Color4 () {
+ // For efficiency in construction of large arrays of vectors, the
+ // default constructor does not initialize the vector.
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4::Color4(const Color3& c3, float a) {
+ r = c3.r;
+ g = c3.g;
+ b = c3.b;
+ this->a = a;
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4::Color4(
+ float r,
+ float g,
+ float b,
+ float a) :
+ r(r), g(g), b(b), a(a) {
+}
+
+//----------------------------------------------------------------------------
+inline Color4::Color4 (float afCoordinate[4]) {
+ r = afCoordinate[0];
+ g = afCoordinate[1];
+ b = afCoordinate[2];
+ a = afCoordinate[3];
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4::Color4(
+ const Color4& other) {
+
+ r = other.r;
+ g = other.g;
+ b = other.b;
+ a = other.a;
+}
+
+//----------------------------------------------------------------------------
+
+inline float& Color4::operator[] (int i) const {
+ return ((float*)this)[i];
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Color4::fuzzyEq(const Color4& other) const {
+ Color4 dif = (*this - other);
+ return G3D::fuzzyEq(dif.r * dif.r + dif.g * dif.g + dif.b * dif.b + dif.a * dif.a, 0);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Color4::fuzzyNe(const Color4& other) const {
+ Color4 dif = (*this - other);
+ return G3D::fuzzyNe(dif.r * dif.r + dif.g * dif.g + dif.b * dif.b + dif.a * dif.a, 0);
+}
+
+
+//----------------------------------------------------------------------------
+inline Color4& Color4::operator= (const Color4& other) {
+ r = other.r;
+ g = other.g;
+ b = other.b;
+ a = other.a;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Color4::operator== (const Color4& other) const {
+ return ( r == other.r && g == other.g && b == other.b && a == other.a);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Color4::operator!= (const Color4& other) const {
+ return ( r != other.r || g != other.g || b != other.b || a != other.a);
+}
+
+//----------------------------------------------------------------------------
+inline Color4 Color4::operator+ (const Color4& other) const {
+ return Color4(r + other.r, g + other.g, b + other.b, a + other.a);
+}
+
+//----------------------------------------------------------------------------
+inline Color4 Color4::operator- (const Color4& other) const {
+ return Color4(r - other.r, g - other.g, b - other.b, a - other.a);
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4 Color4::operator* (float fScalar) const {
+ return Color4(fScalar * r, fScalar * g, fScalar * b, fScalar * a);
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4 Color4::operator- () const {
+ return Color4(-r, -g, -b, -a);
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4 operator* (float fScalar, const Color4& other) {
+ return Color4(fScalar * other.r, fScalar * other.g,
+ fScalar * other.b, fScalar * other.a);
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4& Color4::operator+= (const Color4& other) {
+ r += other.r;
+ g += other.g;
+ b += other.b;
+ a += other.a;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4& Color4::operator-= (const Color4& other) {
+ r -= other.r;
+ g -= other.g;
+ b -= other.b;
+ a -= other.a;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+
+inline Color4& Color4::operator*= (float fScalar) {
+ r *= fScalar;
+ g *= fScalar;
+ b *= fScalar;
+ a *= fScalar;
+ return *this;
+}
+
+} // namespace
+
+template <>
+struct HashTrait<G3D::Color4> {
+ static size_t hashCode(const G3D::Color4& key) {
+ return key.hashCode();
+ }
+};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Color4uint8.h b/dep/include/g3dlite/G3D/Color4uint8.h
new file mode 100644
index 00000000000..ab8c0729276
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Color4uint8.h
@@ -0,0 +1,115 @@
+/**
+ @file Color4uint8.h
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2003-04-07
+ @edited 2006-03-24
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef COLOR4UINT8_H
+#define COLOR4UINT8_H
+
+#include "G3D/g3dmath.h"
+#include "G3D/platform.h"
+#include "G3D/Color3uint8.h"
+
+namespace G3D {
+
+/**
+ Represents a Color4 as a packed integer. Convenient
+ for creating unsigned int vertex arrays. Used by
+ G3D::GImage as the underlying format.
+
+ <B>WARNING</B>: Integer color formats are different than
+ integer vertex formats. The color channels are automatically
+ scaled by 255 (because OpenGL automatically scales integer
+ colors back by this factor). So Color4(1,1,1) == Color4uint8(255,255,255)
+ but Vector3(1,1,1) == Vector3int16(1,1,1).
+
+ */
+G3D_BEGIN_PACKED_CLASS(1)
+class Color4uint8 {
+private:
+ // Hidden operators
+ bool operator<(const Color4uint8&) const;
+ bool operator>(const Color4uint8&) const;
+ bool operator<=(const Color4uint8&) const;
+ bool operator>=(const Color4uint8&) const;
+
+public:
+ uint8 r;
+ uint8 g;
+ uint8 b;
+ uint8 a;
+
+ Color4uint8() : r(0), g(0), b(0), a(0) {}
+
+ Color4uint8(const class Color4& c);
+
+ Color4uint8(const uint8 _r, const uint8 _g, const uint8 _b, const uint8 _a) : r(_r), g(_g), b(_b), a(_a) {}
+
+ Color4uint8(const Color3uint8& c, const uint8 _a) : r(c.r), g(c.g), b(c.b), a(_a) {}
+
+ Color4uint8(class BinaryInput& bi);
+
+ inline static Color4uint8 fromARGB(uint32 i) {
+ Color4uint8 c;
+ c.a = (i >> 24) & 0xFF;
+ c.r = (i >> 16) & 0xFF;
+ c.g = (i >> 8) & 0xFF;
+ c.b = i & 0xFF;
+ return c;
+ }
+
+ inline uint32 asUInt32() const {
+ return ((uint32)a << 24) + ((uint32)r << 16) + ((uint32)g << 8) + b;
+ }
+
+ // access vector V as V[0] = V.r, V[1] = V.g, V[2] = V.b
+ //
+ // WARNING. These member functions rely on
+ // (1) Color4uint8 not having virtual functions
+ // (2) the data packed in a 3*sizeof(uint8) memory block
+ uint8& operator[] (int i) const {
+ return ((uint8*)this)[i];
+ }
+
+ operator uint8* () {
+ return (uint8*)this;
+ }
+
+ operator const uint8* () const {
+ return (uint8*)this;
+ }
+
+
+ inline Color3uint8 bgr() const {
+ return Color3uint8(b, g, r);
+ }
+
+ void serialize(class BinaryOutput& bo) const;
+
+ void deserialize(class BinaryInput& bi);
+
+ inline Color3uint8 rgb() const {
+ return Color3uint8(r, g, b);
+ }
+
+ bool operator==(const Color4uint8& other) const {
+ return *reinterpret_cast<const uint32*>(this) == *reinterpret_cast<const uint32*>(&other);
+ }
+
+ bool operator!=(const Color4uint8& other) const {
+ return *reinterpret_cast<const uint32*>(this) != *reinterpret_cast<const uint32*>(&other);
+ }
+
+}
+G3D_END_PACKED_CLASS(1)
+
+} // namespace G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Cone.h b/dep/include/g3dlite/G3D/Cone.h
new file mode 100644
index 00000000000..d801a9b348f
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Cone.h
@@ -0,0 +1,68 @@
+/**
+ @file Cone.h
+
+ Cone class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
+
+ @created 2001-06-02
+ @edited 2006-02-23
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_CONE_H
+#define G3D_CONE_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Vector3.h"
+
+namespace G3D {
+
+/**
+ An infinite cone.
+ */
+class Cone {
+
+private:
+ Vector3 tip;
+ Vector3 direction;
+
+ /** Angle from the center line to the edge. */
+ float angle;
+
+public:
+
+ /**
+ @param angle Angle from the center line to the edge, in radians
+ */
+ Cone(const Vector3& tip, const Vector3& direction, float angle);
+
+ /**
+ Forms the smallest cone that contains the box. Undefined if
+ the tip is inside or on the box.
+ */
+ Cone(const Vector3& tip, const class Box& box);
+
+ virtual ~Cone() {}
+
+ /**
+ Returns true if the cone touches, intersects, or contains b.
+
+ If c.intersects(s) and c.intersects(Sphere(s.center, s.radius * 2)
+ then the sphere s is entirely within cone c.
+ */
+ bool intersects(const class Sphere& s) const;
+
+ /**
+ True if v is a point inside the cone.
+ */
+ bool contains(const class Vector3& v) const;
+};
+
+} // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/ConvexPolyhedron.h b/dep/include/g3dlite/G3D/ConvexPolyhedron.h
new file mode 100644
index 00000000000..a6fdd62cf90
--- /dev/null
+++ b/dep/include/g3dlite/G3D/ConvexPolyhedron.h
@@ -0,0 +1,180 @@
+/**
+ @file ConvexPolyhedron.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-11-11
+ @edited 2006-04-10
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_CONVEXPOLYHEDRON_H
+#define G3D_CONVEXPOLYHEDRON_H
+
+#include "G3D/platform.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector2.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Plane.h"
+#include "G3D/Line.h"
+#include "G3D/Array.h"
+
+namespace G3D {
+
+class DirectedEdge {
+public:
+ Vector3 start;
+ Vector3 stop;
+};
+
+class ConvexPolygon {
+private:
+
+ friend class ConvexPolyhedron;
+
+ Array<Vector3> _vertex;
+
+public:
+
+ ConvexPolygon() {}
+ ConvexPolygon(const Vector3& v0, const Vector3& v1, const Vector3& v2);
+ ConvexPolygon(const Array<Vector3>& __vertex);
+ virtual ~ConvexPolygon() {}
+
+ /**
+ Counter clockwise winding order.
+ */
+ inline const Vector3& vertex(int i) const {
+ return _vertex[i];
+ }
+
+ inline void setVertex(int i, const Vector3& v) {
+ _vertex[i] = v;
+ }
+
+ /**
+ Zero vertices indicates an empty polygon (zero area).
+ */
+ inline int numVertices() const {
+ return _vertex.size();
+ }
+
+ inline void setNumVertices(int n) {
+ _vertex.resize(n);
+ }
+
+ /**
+ O(n) in the number of edges
+ */
+ bool isEmpty() const;
+
+ /**
+ Cuts the polygon at the plane. If the polygon is entirely above or below
+ the plane, one of the returned polygons will be empty.
+
+ @param above The part of the polygon above (on the side the
+ normal points to or in the plane) the plane
+ @param below The part of the polygon below the plane.
+ @param newEdge If a new edge was introduced, this is that edge (on the above portion; the below portion is the opposite winding.
+ */
+ void cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below, DirectedEdge& newEdge);
+ void cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below);
+
+ /**
+ When a cut plane grazes a vertex in the polygon, two near-identical vertices may be created.
+ The closeness of these two points can cause a number of problems, such as ConvexPolygon::normal()
+ returning an infinite vector. It should be noted, however, that not all applications are
+ sensitive to near-identical vertices.
+
+ removeDuplicateVertices() detects and eliminates redundant vertices.
+ */
+ void removeDuplicateVertices();
+
+ /**
+ O(n) in the number of edges
+ */
+ float getArea() const;
+
+ inline Vector3 normal() const {
+ debugAssert(_vertex.length() >= 3);
+ return (_vertex[1] - _vertex[0]).cross(_vertex[2] - _vertex[0]).direction();
+ }
+
+ /**
+ Returns the same polygon with inverse winding.
+ */
+ ConvexPolygon inverse() const;
+};
+
+
+
+class ConvexPolyhedron {
+public:
+ /**
+ Zero faces indicates an empty polyhedron
+ */
+ Array<ConvexPolygon> face;
+
+ ConvexPolyhedron() {}
+ ConvexPolyhedron(const Array<ConvexPolygon>& _face);
+
+ /**
+ O(n) in the number of edges
+ */
+ bool isEmpty() const;
+
+ /**
+ O(n) in the number of edges
+ */
+ float getVolume() const;
+
+ /**
+ Cuts the polyhedron at the plane. If the polyhedron is entirely above or below
+ the plane, one of the returned polyhedra will be empty.
+
+ @param above The part of the polyhedron above (on the side the
+ normal points to or in the plane) the plane
+ @param below The part of the polyhedron below the plane.
+ */
+ void cut(const Plane& plane, ConvexPolyhedron &above, ConvexPolyhedron &below);
+};
+
+/**
+
+ */
+class ConvexPolygon2D {
+private:
+
+ Array<Vector2> m_vertex;
+
+public:
+
+ ConvexPolygon2D() {}
+
+ /**
+ Points are counter-clockwise in a Y = down, X = right coordinate
+ system.
+
+ @param reverse If true, the points are reversed (i.e. winding direction is changed)
+ before the polygon is created.
+ */
+ ConvexPolygon2D(const Array<Vector2>& pts, bool reverse = false);
+
+ inline int numVertices() const {
+ return m_vertex.size();
+ }
+
+ inline const Vector2& vertex(int index) const {
+ debugAssert((index >= 0) && (index <= m_vertex.size()));
+ return m_vertex[index];
+ }
+
+ /** @param reverseWinding If true, the winding direction of the polygon is reversed for this test.*/
+ bool contains(const Vector2& p, bool reverseWinding = false) const;
+};
+
+
+} // namespace
+#endif
diff --git a/dep/include/g3dlite/G3D/CoordinateFrame.h b/dep/include/g3dlite/G3D/CoordinateFrame.h
index 62cbbd47639..7ed4d0acc65 100644
--- a/dep/include/g3dlite/G3D/CoordinateFrame.h
+++ b/dep/include/g3dlite/G3D/CoordinateFrame.h
@@ -1,17 +1,17 @@
/**
@file CoordinateFrame.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2001-03-04
- @edited 2006-04-07
+ @edited 2009-04-29
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_COORDINATEFRAME_H
-#define G3D_COORDINATEFRAME_H
+#ifndef G3D_CFrame_h
+#define G3D_CFrame_h
#include "G3D/platform.h"
#include "G3D/Vector3.h"
@@ -24,47 +24,55 @@
#include <cstdarg>
#include <assert.h>
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
+
namespace G3D {
+class Any;
/**
A rigid body RT (rotation-translation) transformation.
-
+
CoordinateFrame abstracts a 4x4 matrix that maps object space to world space:
-
+
v_world = C * v_object
CoordinateFrame::rotation is the upper 3x3 submatrix, CoordinateFrame::translation
-is the right 3x1 column. The 4th row is always [0 0 0 1], so it isn't stored.
+is the right 3x1 column. The 4th row is always [0 0 0 1], so it isn't stored.
So you don't have to remember which way the multiplication and transformation work,
-it provides explicit toWorldSpace and toObjectSpace methods. Also, points, vectors
+it provides explicit toWorldSpace and toObjectSpace methods. Also, points, vectors
(directions), and surface normals transform differently, so they have separate methods.
-
+
Some helper functions transform whole primitives like boxes in and out of object space.
Convert to Matrix4 using CoordinateFrame::toMatrix4. You <I>can</I> construct a CoordinateFrame
-from a Matrix4 using Matrix4::approxCoordinateFrame, however, because a Matrix4 is more
+from a Matrix4 using Matrix4::approxCoordinateFrame, however, because a Matrix4 is more
general than a CoordinateFrame, some information may be lost.
-See also: G3D::Matrix4, G3D::Quat
+@sa G3D::UprightFrame, G3D::PhysicsFrame, G3D::Matrix4, G3D::Quat
*/
class CoordinateFrame {
public:
- /**
- Takes object space points to world space.
- */
- Matrix3 rotation;
+ /** Takes object space points to world space. */
+ Matrix3 rotation;
- /**
- Takes object space points to world space.
- */
- Vector3 translation;
+ /** Takes object space points to world space. */
+ Vector3 translation;
- /**
- The direction an object "looks" relative to its own axes.
- @deprecated This is always -1 and will be fixed at that value in future releases.
- */
- static const float zLookDirection;
+ /** \param any Must be in one of the following forms:
+ - CFrame((matrix3 expr), (vector3 expr))
+ - CFrame::fromXYZYPRDegrees(#, #, #, #, #, #)
+ - CFrame { rotation = (matrix3 expr), translation = (vector3 expr) }
+ */
+ CoordinateFrame(const Any& any);
+
+ /** Converts the CFrame to an Any. */
+ operator Any() const;
inline bool operator==(const CoordinateFrame& other) const {
return (translation == other.translation) && (rotation == other.rotation);
@@ -83,14 +91,12 @@ public:
/**
Initializes to the identity coordinate frame.
*/
- inline CoordinateFrame() :
- rotation(Matrix3::identity()), translation(Vector3::zero()) {
- }
+ CoordinateFrame();
CoordinateFrame(const Vector3& _translation) :
rotation(Matrix3::identity()), translation(_translation) {
}
-
+
CoordinateFrame(const Matrix3 &rotation, const Vector3 &translation) :
rotation(rotation), translation(translation) {
}
@@ -99,6 +105,23 @@ public:
rotation(rotation), translation(Vector3::zero()) {
}
+ CoordinateFrame(const class UprightFrame& f);
+
+ static CoordinateFrame fromXYZYPRRadians(float x, float y, float z, float yaw = 0.0f, float pitch = 0.0f, float roll = 0.0f);
+
+ /** Construct a coordinate frame from translation = (x,y,z) and
+ rotations (in that order) about Y, object space X, object space
+ Z. Note that because object-space axes are used, these are not
+ equivalent to Euler angles; they are known as Tait-Bryan
+ rotations and are more convenient for intuitive positioning.*/
+ static CoordinateFrame fromXYZYPRDegrees(float x, float y, float z, float yaw = 0.0f, float pitch = 0.0f, float roll = 0.0f);
+
+ CoordinateFrame(class BinaryInput& b);
+
+ void deserialize(class BinaryInput& b);
+
+ void serialize(class BinaryOutput& b) const;
+
CoordinateFrame(const CoordinateFrame &other) :
rotation(other.rotation), translation(other.translation) {}
@@ -117,21 +140,26 @@ public:
/** See also Matrix4::approxCoordinateFrame */
class Matrix4 toMatrix4() const;
+ void getXYZYPRRadians(float& x, float& y, float& z, float& yaw, float& pitch, float& roll) const;
+ void getXYZYPRDegrees(float& x, float& y, float& z, float& yaw, float& pitch, float& roll) const;
+
+
/**
Produces an XML serialization of this coordinate frame.
+ @deprecated
*/
std::string toXML() const;
/**
Returns the heading of the lookVector as an angle in radians relative to
- the world -z axis. That is, a counter-clockwise heading where north (-z)
+ the world -z axis. That is, a counter-clockwise heading where north (-z)
is 0 and west (-x) is PI/2.
Note that the heading ignores the Y axis, so an inverted
object has an inverted heading.
*/
inline float getHeading() const {
- Vector3 look = rotation.getColumn(2);
+ Vector3 look = rotation.column(2);
float angle = -(float) atan2(-look.x, look.z);
return angle;
}
@@ -157,23 +185,24 @@ public:
*/
inline Vector3 pointToWorldSpace(const Vector3& v) const {
return Vector3(
- rotation[0][0] * v[0] + rotation[0][1] * v[1] + rotation[0][2] * v[2] + translation[0],
- rotation[1][0] * v[0] + rotation[1][1] * v[1] + rotation[1][2] * v[2] + translation[1],
- rotation[2][0] * v[0] + rotation[2][1] * v[1] + rotation[2][2] * v[2] + translation[2]);
+ rotation[0][0] * v[0] + rotation[0][1] * v[1] + rotation[0][2] * v[2] + translation[0],
+ rotation[1][0] * v[0] + rotation[1][1] * v[1] + rotation[1][2] * v[2] + translation[1],
+ rotation[2][0] * v[0] + rotation[2][1] * v[1] + rotation[2][2] * v[2] + translation[2]);
}
/**
- Transforms the point into object space.
+ Transforms the point into object space. Assumes that the rotation matrix is orthonormal.
*/
inline Vector3 pointToObjectSpace(const Vector3& v) const {
float p[3];
p[0] = v[0] - translation[0];
p[1] = v[1] - translation[1];
p[2] = v[2] - translation[2];
+ debugAssert(G3D::fuzzyEq(rotation.determinant(), 1.0f));
return Vector3(
- rotation[0][0] * p[0] + rotation[1][0] * p[1] + rotation[2][0] * p[2],
- rotation[0][1] * p[0] + rotation[1][1] * p[1] + rotation[2][1] * p[2],
- rotation[0][2] * p[0] + rotation[1][2] * p[1] + rotation[2][2] * p[2]);
+ rotation[0][0] * p[0] + rotation[1][0] * p[1] + rotation[2][0] * p[2],
+ rotation[0][1] * p[0] + rotation[1][1] * p[1] + rotation[2][1] * p[2],
+ rotation[0][2] * p[0] + rotation[1][2] * p[1] + rotation[2][2] * p[2]);
}
/**
@@ -235,7 +264,7 @@ public:
class Box toObjectSpace(const Box& b) const;
class Plane toObjectSpace(const Plane& p) const;
-
+
class Sphere toObjectSpace(const Sphere& b) const;
Triangle toObjectSpace(const Triangle& t) const;
@@ -260,47 +289,29 @@ public:
const Vector3& target,
Vector3 up);
- /** @deprecated See lookVector */
- inline Vector3 getLookVector() const {
- return rotation.getColumn(2) * zLookDirection;
- }
-
/** The direction this camera is looking (its negative z axis)*/
- inline Vector3 lookVector() const {
- return rotation.getColumn(2) * zLookDirection;
- }
+ inline Vector3 lookVector() const {
+ return -rotation.column(2);
+ }
/** Returns the ray starting at the camera origin travelling in direction CoordinateFrame::lookVector. */
class Ray lookRay() const;
/** Up direction for this camera (its y axis). */
inline Vector3 upVector() const {
- return rotation.getColumn(1);
- }
-
- /**
- If a viewer looks along the look vector, this is the viewer's "left"
- @deprecated leftVector
- */
- inline Vector3 getLeftVector() const {
- return -rotation.getColumn(0);
+ return rotation.column(1);
}
- /** @deprecated See rightVector */
- inline Vector3 getRightVector() const {
- return rotation.getColumn(0);
- }
+ inline Vector3 rightVector() const {
+ return rotation.column(0);
+ }
/**
If a viewer looks along the look vector, this is the viewer's "left".
Useful for strafing motions and building alternative coordinate frames.
*/
inline Vector3 leftVector() const {
- return -rotation.getColumn(0);
- }
-
- inline Vector3 rightVector() const {
- return rotation.getColumn(0);
+ return -rotation.column(0);
}
/**
@@ -313,7 +324,8 @@ public:
};
+typedef CoordinateFrame CFrame;
+
} // namespace
#endif
-
diff --git a/dep/include/g3dlite/G3D/Crypto.h b/dep/include/g3dlite/G3D/Crypto.h
index 0bd5b75efca..56c816a4977 100644
--- a/dep/include/g3dlite/G3D/Crypto.h
+++ b/dep/include/g3dlite/G3D/Crypto.h
@@ -1,7 +1,8 @@
-/**
+/**
@file Crypto.h
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2006-03-29
@edited 2006-04-06
@@ -16,6 +17,48 @@
namespace G3D {
+/** See G3D::Crypto::md5 */
+class MD5Hash {
+private:
+
+ uint8 value[16];
+
+public:
+
+ MD5Hash() {
+ for (int i = 0; i < 16; ++i) {
+ value[i] = 0;
+ }
+ }
+
+ explicit MD5Hash(class BinaryInput& b);
+
+ uint8& operator[](int i) {
+ return value[i];
+ }
+
+ const uint8& operator[](int i) const {
+ return value[i];
+ }
+
+ bool operator==(const MD5Hash& other) const {
+ bool match = true;
+ for (int i = 0; i < 16; ++i) {
+ match = match && (other.value[i] == value[i]);
+ }
+ return match;
+ }
+
+ inline bool operator!=(const MD5Hash& other) const {
+ return !(*this == other);
+ }
+
+ void deserialize(class BinaryInput& b);
+
+ void serialize(class BinaryOutput& b) const;
+};
+
+
/** Cryptography and hashing helper functions */
class Crypto {
public:
@@ -31,6 +74,14 @@ public:
static uint32 crc32(const void* bytes, size_t numBytes);
/**
+ Computes the MD5 hash (message digest) of a byte stream, as defined by
+ http://www.ietf.org/rfc/rfc1321.txt.
+
+ @cite Based on implementation by L. Peter Deutsch, ghost@aladdin.com
+ */
+ MD5Hash md5(const void* bytes, size_t numBytes);
+
+ /**
Returns the nth prime less than 2000 in constant time. The first prime has index
0 and is the number 2.
*/
@@ -43,4 +94,3 @@ public:
}
#endif
-
diff --git a/dep/include/g3dlite/G3D/Cylinder.h b/dep/include/g3dlite/G3D/Cylinder.h
new file mode 100644
index 00000000000..85eba77b794
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Cylinder.h
@@ -0,0 +1,92 @@
+/**
+ @file Cylinder.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-02-07
+ @edited 2005-09-26
+
+ Copyright 2000-2005, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Cylinder_H
+#define G3D_Cylinder_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Vector3.h"
+
+namespace G3D {
+
+class Line;
+class AABox;
+/**
+ Right cylinder
+ */
+class Cylinder {
+private:
+ Vector3 p1;
+ Vector3 p2;
+
+ float mRadius;
+
+public:
+
+ /** Uninitialized */
+ Cylinder();
+ Cylinder(class BinaryInput& b);
+ Cylinder(const Vector3& _p1, const Vector3& _p2, float _r);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ /** The line down the center of the Cylinder */
+ Line axis() const;
+
+ /**
+ A reference frame in which the center of mass is at the origin and
+ the Y-axis is the cylinder's axis. If the cylinder is transformed, this reference frame
+ may freely rotate around its axis.*/
+ void getReferenceFrame(class CoordinateFrame& cframe) const;
+
+ /** Returns point 0 or 1 */
+ inline const Vector3& point(int i) const {
+ debugAssert(i >= 0 && i <= 1);
+ return (i == 0) ? p1 : p2;
+ }
+
+ /**
+ Returns true if the point is inside the Cylinder or on its surface.
+ */
+ bool contains(const Vector3& p) const;
+
+ float area() const;
+
+ float volume() const;
+
+ float radius() const;
+
+ /** Center of mass */
+ inline Vector3 center() const {
+ return (p1 + p2) / 2.0f;
+ }
+
+ inline float height() const {
+ return (p1 - p2).magnitude();
+ }
+
+ /**
+ Get close axis aligned bounding box.
+ With vertical world orientation, the top and bottom might not be very tight. */
+ void getBounds(AABox& out) const;
+
+ /** Random world space point with outward facing normal. */
+ void getRandomSurfacePoint(Vector3& P, Vector3& N) const;
+
+ /** Point selected uniformly at random over the volume. */
+ Vector3 randomInteriorPoint() const;
+};
+
+} // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/EqualsTrait.h b/dep/include/g3dlite/G3D/EqualsTrait.h
new file mode 100644
index 00000000000..349cb5088fb
--- /dev/null
+++ b/dep/include/g3dlite/G3D/EqualsTrait.h
@@ -0,0 +1,26 @@
+/**
+ @file EqualsTrait.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2008-10-01
+ @edited 2008-10-01
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_EQUALSTRAIT_H
+#define G3D_EQUALSTRAIT_H
+
+#include "G3D/platform.h"
+
+/** Default implementation of EqualsTrait.
+ @see G3D::Table for specialization requirements.
+*/
+template<typename Key> struct EqualsTrait {
+ static bool equals(const Key& a, const Key& b) {
+ return a == b;
+ }
+};
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/G3D.h b/dep/include/g3dlite/G3D/G3D.h
new file mode 100644
index 00000000000..5b56b9c71dc
--- /dev/null
+++ b/dep/include/g3dlite/G3D/G3D.h
@@ -0,0 +1,162 @@
+/**
+ @file G3D.h
+
+ This header includes all of the G3D libraries in
+ appropriate namespaces.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-08-25
+ @edited 2010-01-30
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+*/
+
+#ifndef G3D_G3D_h
+#define G3D_G3D_h
+
+#define NOMINMAX 1
+#ifdef min
+ #undef min
+#endif
+#ifdef max
+ #undef max
+#endif
+
+#include "G3D/platform.h"
+#include "G3D/units.h"
+#include "G3D/ParseError.h"
+#include "G3D/Random.h"
+#include "G3D/Array.h"
+#include "G3D/SmallArray.h"
+#include "G3D/Queue.h"
+#include "G3D/Crypto.h"
+#include "G3D/format.h"
+#include "G3D/Vector2.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector4.h"
+#include "G3D/Color1.h"
+#include "G3D/Color3.h"
+#include "G3D/Color4.h"
+#include "G3D/Matrix2.h"
+#include "G3D/Matrix3.h"
+#include "G3D/Matrix4.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/PhysicsFrame.h"
+#include "G3D/Plane.h"
+#include "G3D/Line.h"
+#include "G3D/Ray.h"
+#include "G3D/Sphere.h"
+#include "G3D/Box.h"
+#include "G3D/Box2D.h"
+#include "G3D/AABox.h"
+#include "G3D/WrapMode.h"
+#include "G3D/Cone.h"
+#include "G3D/Quat.h"
+#include "G3D/stringutils.h"
+#include "G3D/prompt.h"
+#include "G3D/Table.h"
+#include "G3D/Set.h"
+#include "G3D/GUniqueID.h"
+#include "G3D/BinaryFormat.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/debug.h"
+#include "G3D/g3dfnmatch.h"
+#include "G3D/G3DGameUnits.h"
+#include "G3D/g3dmath.h"
+#include "G3D/uint128.h"
+#include "G3D/fileutils.h"
+#include "G3D/ReferenceCount.h"
+#include "G3D/Welder.h"
+#include "G3D/GMutex.h"
+#include "G3D/PrecomputedRandom.h"
+#include "G3D/MemoryManager.h"
+#include "G3D/AreaMemoryManager.h"
+#include "G3D/BumpMapPreprocess.h"
+
+template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
+ static size_t hashCode(G3D::ReferenceCountedPointer<T> key) { return reinterpret_cast<size_t>( key.pointer() ); }
+};
+
+#include "G3D/GImage.h"
+#include "G3D/CollisionDetection.h"
+#include "G3D/Intersect.h"
+#include "G3D/Log.h"
+#include "G3D/serialize.h"
+#include "G3D/TextInput.h"
+#include "G3D/NetAddress.h"
+#include "G3D/NetworkDevice.h"
+#include "G3D/System.h"
+#include "G3D/splinefunc.h"
+#include "G3D/Spline.h"
+#include "G3D/UprightFrame.h"
+#include "G3D/LineSegment.h"
+#include "G3D/Capsule.h"
+#include "G3D/Cylinder.h"
+#include "G3D/Triangle.h"
+#include "G3D/Color3uint8.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/Vector2int16.h"
+#include "G3D/Vector3int16.h"
+#include "G3D/Vector3int32.h"
+#include "G3D/Vector4int8.h"
+#include "G3D/ConvexPolyhedron.h"
+#include "G3D/MeshAlg.h"
+#include "G3D/vectorMath.h"
+#include "G3D/Rect2D.h"
+#include "G3D/GCamera.h"
+#include "G3D/GLight.h"
+#include "G3D/KDTree.h"
+#include "G3D/PointKDTree.h"
+#include "G3D/TextOutput.h"
+#include "G3D/MeshBuilder.h"
+#include "G3D/Stopwatch.h"
+#include "G3D/AtomicInt32.h"
+#include "G3D/GThread.h"
+#include "G3D/ThreadSet.h"
+#include "G3D/RegistryUtil.h"
+#include "G3D/Any.h"
+#include "G3D/PointHashGrid.h"
+#include "G3D/Map2D.h"
+#include "G3D/Image1.h"
+#include "G3D/Image1uint8.h"
+#include "G3D/Image3.h"
+#include "G3D/Image3uint8.h"
+#include "G3D/Image4.h"
+#include "G3D/Image4uint8.h"
+#include "G3D/filter.h"
+#include "G3D/WeakCache.h"
+#include "G3D/Pointer.h"
+#include "G3D/Matrix.h"
+#include "G3D/ImageFormat.h"
+
+#ifdef _MSC_VER
+# pragma comment(lib, "zlib")
+# pragma comment(lib, "ws2_32")
+# pragma comment(lib, "winmm")
+# pragma comment(lib, "imagehlp")
+# pragma comment(lib, "gdi32")
+# pragma comment(lib, "user32")
+# pragma comment(lib, "kernel32")
+# pragma comment(lib, "version")
+# pragma comment(lib, "advapi32")
+# pragma comment(lib, "png")
+# pragma comment(lib, "jpeg")
+# pragma comment(lib, "zip")
+# ifdef _DEBUG
+ // Don't link against G3D when building G3D itself.
+# ifndef G3D_BUILDING_LIBRARY_DLL
+# pragma comment(lib, "G3Dd.lib")
+# endif
+# else
+ // Don't link against G3D when building G3D itself.
+# ifndef G3D_BUILDING_LIBRARY_DLL
+# pragma comment(lib, "G3D.lib")
+# endif
+# endif
+#endif
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/G3DAll.h b/dep/include/g3dlite/G3D/G3DAll.h
new file mode 100644
index 00000000000..1176fe742e7
--- /dev/null
+++ b/dep/include/g3dlite/G3D/G3DAll.h
@@ -0,0 +1,26 @@
+/**
+ @file G3DAll.h
+
+ Includes all G3D and GLG3D files and uses the G3D namespace.
+
+ This requires OpenGL and SDL headers. If you don't want all of this,
+ \#include <G3D.h> separately.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2002-01-01
+ @edited 2006-08-13
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_G3DALL_H
+#define G3D_G3DALL_H
+
+#include "G3D/G3D.h"
+#include "GLG3D/GLG3D.h"
+
+using namespace G3D;
+
+#endif
diff --git a/dep/include/g3dlite/G3D/G3DGameUnits.h b/dep/include/g3dlite/G3D/G3DGameUnits.h
new file mode 100644
index 00000000000..e2bc2c811e8
--- /dev/null
+++ b/dep/include/g3dlite/G3D/G3DGameUnits.h
@@ -0,0 +1,42 @@
+/**
+ @file G3DGameUnits.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-10-05
+ @edited 2006-11-10
+ */
+
+#ifndef G3D_GAMEUNITS_H
+#define G3D_GAMEUNITS_H
+
+#include "G3D/platform.h"
+
+namespace G3D {
+/**
+ Time, in seconds.
+ */
+typedef double GameTime;
+typedef double SimTime;
+
+/**
+ Actual wall clock time in seconds.
+ */
+typedef double RealTime;
+
+enum AMPM {AM, PM};
+
+/** \deprecated */
+enum {SECOND=1, MINUTE=60, HOUR = 60*60, DAY=24*60*60, SUNRISE=24*60*60/4, SUNSET=24*60*60*3/4, MIDNIGHT=0, METER=1, KILOMETER=1000};
+
+/**
+ Converts a 12 hour clock time into the number of seconds since
+ midnight. Note that 12:00 PM is noon and 12:00 AM is midnight.
+
+ Example: <CODE>toSeconds(10, 00, AM)</CODE>
+ */
+SimTime toSeconds(int hour, int minute, double seconds, AMPM ap);
+SimTime toSeconds(int hour, int minute, AMPM ap);
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/GCamera.h b/dep/include/g3dlite/G3D/GCamera.h
index 7bf8e26e562..018fbc85d59 100644
--- a/dep/include/g3dlite/G3D/GCamera.h
+++ b/dep/include/g3dlite/G3D/GCamera.h
@@ -1,59 +1,88 @@
/**
@file GCamera.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
- @created 2001-06-02
- @edited 2006-02-11
+ @created 2005-07-20
+ @edited 2009-04-20
*/
-#ifndef G3D_GCAMERA_H
-#define G3D_GCAMERA_H
+#ifndef G3D_GCamera_H
+#define G3D_GCamera_H
#include "G3D/platform.h"
#include "G3D/CoordinateFrame.h"
#include "G3D/Vector3.h"
#include "G3D/Plane.h"
+#include "G3D/debugAssert.h"
namespace G3D {
+class Matrix4;
+class Rect2D;
+class Any;
+
/**
- There is a viewport of width x height size in world space that corresponds to
- a screenWidth x screenHeight pixel grid on a
- renderDevice->getWidth() x renderDevice->getHeight()
- window.
+ Abstraction of a pinhole camera.
+
+ The area a camera sees is called a frustum. It is bounded by the
+ near plane, the far plane, and the sides of the view frame projected
+ into the scene. It has the shape of a pyramid with the top cut off.
+
+ Cameras can project points from 3D to 2D. The "unit" projection
+ matches OpenGL. It maps the entire view frustum to a cube of unit
+ radius (i.e., edges of length 2) centered at the origin. The
+ non-unit projection then maps that cube to the specified pixel
+ viewport in X and Y and the range [0, 1] in Z. The projection is
+ reversable as long as the projected Z value is known.
All viewport arguments are the pixel bounds of the viewport-- e.g.,
- RenderDevice::getViewport().
+ RenderDevice::viewport().
*/
class GCamera {
-private:
+public:
/**
- Vertical field of view (in radians)
+ Stores the direction of the field of view
*/
- float fieldOfView;
+ enum FOVDirection {HORIZONTAL, VERTICAL};
- /**
- The image plane depth corresponding to a vertical field of
- view, where the film size is 1x1.
- */
- float imagePlaneDepth;
+private:
+
+ /** Full field of view (in radians) */
+ float m_fieldOfView;
- /**
- Clipping plane, *not* imaging plane. Positive numbers.
- */
- float nearPlane;
+ /** Clipping plane, *not* imaging plane. Negative numbers. */
+ float m_nearPlaneZ;
- /**
- Positive
- */
- float farPlane;
+ /** Negative */
+ float m_farPlaneZ;
+
+ /** Stores the camera's location and orientation */
+ CoordinateFrame m_cframe;
- CoordinateFrame cframe;
+ /** Horizontal or Vertical */
+ FOVDirection m_direction;
public:
+ /** Must be of the format produced by the Any cast, e.g.,
+
+ <pre>
+ GCamera {
+ coordinateFrame = CFrame::fromXYZYPRDegrees(-13.3f, 8.0f, -1.9f, 246.6f, -3),
+ nearPlaneZ = -0.5,
+ farPlaneZ = -50,
+ fovDirection = "HORIZONTAL",
+ fovAngleDegrees = 90
+ }</pre>
+
+ Missing fields are filled from the default GCamera constructor.
+ */
+ GCamera(const Any& any);
+
+ operator Any() const;
+
class Frustum {
public:
class Face {
@@ -64,7 +93,7 @@ public:
/** The plane containing the face. */
Plane plane;
};
-
+
/** The vertices, in homogeneous space. If w == 0,
a vertex is at infinity. */
Array<Vector4> vertexPos;
@@ -79,50 +108,95 @@ public:
GCamera();
+ GCamera(const Matrix4& proj, const CFrame& frame);
+
virtual ~GCamera();
- CoordinateFrame getCoordinateFrame() const;
+ /** Returns the current coordinate frame */
+ const CoordinateFrame& coordinateFrame() const {
+ return m_cframe;
+ }
+
+ /** Sets c to the camera's coordinate frame */
void getCoordinateFrame(CoordinateFrame& c) const;
- void setCoordinateFrame(const CoordinateFrame& c);
- /**
- Sets the horizontal field of view, in radians. The
- initial angle is toRadians(55).
- <UL>
- <LI> toRadians(50) - Telephoto
- <LI> toRadians(110) - Normal
- <LI> toRadians(140) - Wide angle
- </UL>
+ /** Sets a new coordinate frame for the camera */
+ void setCoordinateFrame(const CoordinateFrame& c);
+
+ /** Sets \a P equal to the camera's projection matrix. This is the
+ matrix that maps points to the homogeneous clip cube that
+ varies from -1 to 1 on all axes. The projection matrix does
+ not include the camera transform.
+
+ This is the matrix that a RenderDevice (or OpenGL) uses as the projection matrix.
+ @sa RenderDevice::setProjectionAndCameraMatrix, RenderDevice::setProjectionMatrix, Matrix4::perspectiveProjection
*/
- void setFieldOfView(float angle);
+ void getProjectUnitMatrix(const Rect2D& viewport, Matrix4& P) const;
+
+ /** Sets \a P equal to the matrix that transforms points to pixel
+ coordinates on the given viewport. A point correspoinding to
+ the top-left corner of the viewport in camera space will
+ transform to viewport.x0y0() and the bottom-right to viewport.x1y1(). */
+ void getProjectPixelMatrix(const Rect2D& viewport, Matrix4& P) const;
+
+ /** Converts projected points from OpenGL standards
+ (-1, 1) to normal 3D coordinate standards (0, 1)
+
+ \deprecated
+ */ // TODO: Remove
+ Vector3 convertFromUnitToNormal(const Vector3& in, const Rect2D& viewport) const;
/**
- Sets the field of view based on a desired image plane depth
- (<I>s'</I>) and film dimensions in world space. Depth must be positive. Width,
- depth, and height are measured in the same units (meters are
- recommended). The field of view will span the diagonal to the
- image.<P> <I>Note</I>: to simulate a 35mm GCamera, set width =
- 0.36 mm and height = 0.24 mm. The width and height used are
- generally not the pixel dimensions of the image.
+ Sets the field of view, in radians. The
+ initial angle is toRadians(55). Must specify
+ the direction of the angle.
+
+ This is the full angle, i.e., from the left side of the
+ viewport to the right side.
*/
- void setImagePlaneDepth(
- float depth,
- const class Rect2D& viewport);
+ void setFieldOfView(float angle, FOVDirection direction);
- inline double getFieldOfView() const {
- return fieldOfView;
+ /** Returns the current full field of view angle (from the left side of the
+ viewport to the right side) and direction */
+ inline void getFieldOfView(float& angle, FOVDirection& direction) const {
+ angle = m_fieldOfView;
+ direction = m_direction;
}
/**
Projects a world space point onto a width x height screen. The
returned coordinate uses pixmap addressing: x = right and y =
- down. The resulting z value is <I>rhw</I>.
+ down. The resulting z value is 0 at the near plane, 1 at the far plane,
+ and is a linear compression of unit cube projection.
If the point is behind the camera, Vector3::inf() is returned.
*/
- G3D::Vector3 project(
- const G3D::Vector3& point,
- const class Rect2D& viewport) const;
+ Vector3 project(const G3D::Vector3& point,
+ const class Rect2D& viewport) const;
+
+ /**
+ Projects a world space point onto a unit cube. The resulting
+ x,y,z values range between -1 and 1, where z is -1
+ at the near plane and 1 at the far plane and varies hyperbolically in between.
+
+ If the point is behind the camera, Vector3::inf() is returned.
+ */
+ Vector3 projectUnit(const G3D::Vector3& point,
+ const class Rect2D& viewport) const;
+
+ /**
+ Gives the world-space coordinates of screen space point v, where
+ v.x is in pixels from the left, v.y is in pixels from
+ the top, and v.z is on the range 0 (near plane) to 1 (far plane).
+ */
+ Vector3 unproject(const Vector3& v, const Rect2D& viewport) const;
+
+ /**
+ Gives the world-space coordinates of unit cube point v, where
+ v varies from -1 to 1 on all axes. The unproject first
+ transforms the point into a pixel location for the viewport, then calls unproject
+ */
+ Vector3 unprojectUnit(const Vector3& v, const Rect2D& viewport) const;
/**
Returns the pixel area covered by a shape of the given
@@ -133,23 +207,29 @@ public:
/**
Returns the world space 3D viewport corners. These
are at the near clipping plane. The corners are constructed
- from the nearPlaneZ, getViewportWidth, and getViewportHeight.
+ from the nearPlaneZ, viewportWidth, and viewportHeight.
"left" and "right" are from the GCamera's perspective.
*/
- void get3DViewportCorners(
- const class Rect2D& viewport,
- Vector3& outUR,
- Vector3& outUL,
- Vector3& outLL,
- Vector3& outLR) const;
+ void getNearViewportCorners(const class Rect2D& viewport,
+ Vector3& outUR, Vector3& outUL,
+ Vector3& outLL, Vector3& outLR) const;
/**
- Returns the image plane depth, <I>s'</I>, given the current field
- of view for film of dimensions width x height. See
- setImagePlaneDepth for a discussion of worldspace values width and height.
- */
- float getImagePlaneDepth(
- const class Rect2D& viewport) const;
+ Returns the world space 3D viewport corners. These
+ are at the Far clipping plane. The corners are constructed
+ from the nearPlaneZ, farPlaneZ, viewportWidth, and viewportHeight.
+ "left" and "right" are from the GCamera's perspective.
+ */
+ void getFarViewportCorners(const class Rect2D& viewport,
+ Vector3& outUR, Vector3& outUL,
+ Vector3& outLL, Vector3& outLR) const;
+
+ /**
+ Returns the image plane depth, assumes imagePlane
+ is the same as the near clipping plane.
+ returns a positive number.
+ */
+ float imagePlaneDepth() const;
/**
Returns the world space ray passing through the center of pixel
@@ -157,10 +237,13 @@ public:
the 3D object space axes: (0,0) is the upper left corner of the screen.
They are in viewport coordinates, not screen coordinates.
+ The ray origin is at the origin. To start it at the image plane,
+ move it forward by imagePlaneDepth/ray.direction.z
+
Integer (x, y) values correspond to
the upper left corners of pixels. If you want to cast rays
- through pixel centers, add 0.5 to x and y.
- */
+ through pixel centers, add 0.5 to x and y.
+ */
Ray worldRay(
float x,
float y,
@@ -169,80 +252,86 @@ public:
/**
Returns a negative z-value.
*/
- inline float getNearPlaneZ() const {
- return -nearPlane;
+ inline float nearPlaneZ() const {
+ return m_nearPlaneZ;
}
/**
Returns a negative z-value.
*/
- inline float getFarPlaneZ() const {
- return -farPlane;
+ inline float farPlaneZ() const {
+ return m_farPlaneZ;
}
+ /**
+ Sets a new value for the far clipping plane
+ Expects a negative value
+ */
inline void setFarPlaneZ(float z) {
debugAssert(z < 0);
- farPlane = -z;
+ m_farPlaneZ = z;
}
-
+
+ /**
+ Sets a new value for the near clipping plane
+ Expects a negative value
+ */
inline void setNearPlaneZ(float z) {
debugAssert(z < 0);
- nearPlane = -z;
+ m_nearPlaneZ = z;
}
/**
- Returns the GCamera space width of the viewport.
- */
- float getViewportWidth(
- const class Rect2D& viewport) const;
-
- /**
- Returns the GCamera space height of the viewport.
+ Returns the camera space width of the viewport at the near plane.
*/
- float getViewportHeight(
- const class Rect2D& viewport) const;
+ float viewportWidth(const class Rect2D& viewport) const;
/**
- Read back a GCamera space z-value at pixel (x, y) from the depth buffer.
- double getZValue(
- double x,
- double y,
- const class Rect2D& viewport,
- double polygonOffset = 0) const;
+ Returns the camera space height of the viewport at the near plane.
*/
+ float viewportHeight(const class Rect2D& viewport) const;
void setPosition(const Vector3& t);
+ /** Rotate the camera in place to look at the target. Does not
+ persistently look at that location when the camera moves;
+ i.e., if you move the camera and still want it to look at the
+ old target, you must call lookAt again after moving the
+ camera.)*/
void lookAt(const Vector3& position, const Vector3& up = Vector3::unitY());
- /**
- Returns the clipping planes of the frustum, in world space.
- The planes have normals facing <B>into</B> the view frustum.
-
- The plane order is guaranteed to be:
- Near, Right, Left, Top, Bottom, [Far]
-
- If the far plane is at infinity, the resulting array will have
- 5 planes, otherwise there will be 6.
-
- The viewport is used only to determine the aspect ratio of the screen; the
- absolute dimensions and xy values don't matter.
+ /**
+ Returns the clipping planes of the frustum, in world space.
+ The planes have normals facing <B>into</B> the view frustum.
+
+ The plane order is guaranteed to be:
+ Near, Right, Left, Top, Bottom, [Far]
+
+ If the far plane is at infinity, the resulting array will have
+ 5 planes, otherwise there will be 6.
+
+ The viewport is used only to determine the aspect ratio of the screen; the
+ absolute dimensions and xy values don't matter.
*/
- void getClipPlanes(
- const Rect2D& viewport,
- Array<Plane>& outClip) const;
+ void getClipPlanes
+ (
+ const Rect2D& viewport,
+ Array<Plane>& outClip) const;
- /**
- Returns the world space view frustum, which is a truncated pyramid describing
- the volume of space seen by this camera.
+ /**
+ Returns the world space view frustum, which is a truncated pyramid describing
+ the volume of space seen by this camera.
*/
- void getFrustum(const Rect2D& viewport, GCamera::Frustum& f) const;
-
- GCamera::Frustum frustum(const Rect2D& viewport) const;
-
+ void frustum(const Rect2D& viewport, GCamera::Frustum& f) const;
+
+ GCamera::Frustum frustum(const Rect2D& viewport) const;
+
+ /** Read and Write camera parameters */
+ void serialize(class BinaryOutput& bo) const;
+ void deserialize(class BinaryInput& bi);
+
};
} // namespace G3D
#endif
-
diff --git a/dep/include/g3dlite/G3D/GImage.h b/dep/include/g3dlite/G3D/GImage.h
new file mode 100644
index 00000000000..8ae11134fc9
--- /dev/null
+++ b/dep/include/g3dlite/G3D/GImage.h
@@ -0,0 +1,607 @@
+/**
+ \file GImage.h
+
+ See G3D::GImage for details.
+
+ @cite JPEG compress/decompressor is the <A HREF="http://www.ijg.org/files/">IJG library</A>, used in accordance with their license.
+ @cite JPG code by John Chisholm, using the IJG Library
+ @cite TGA code by Morgan McGuire
+ @cite BMP code by John Chisholm, based on code by Edward "CGameProgrammer" Resnick <A HREF="mailto:cgp@gdnmail.net">mailto:cgp@gdnmail.net</A> at <A HREF="ftp://ftp.flipcode.com/cotd/LoadPicture.txt">ftp://ftp.flipcode.com/cotd/LoadPicture.txt</A>
+ @cite PCX format described in the ZSOFT PCX manual http://www.nist.fss.ru/hr/doc/spec/pcx.htm#2
+ @cite PNG compress/decompressor is the <A HREF="http://www.libpng.org/pub/png/libpng.html">libpng library</A>, used in accordance with their license.
+ @cite PPM code by Morgan McGuire based on http://netpbm.sourceforge.net/doc/ppm.html
+
+ \maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ \created 2002-05-27
+ \edited 2010-01-04
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_GImage_h
+#define G3D_GImage_h
+
+#include "G3D/platform.h"
+#include <string>
+#include "G3D/Array.h"
+#include "G3D/g3dmath.h"
+#include "G3D/stringutils.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/Color3uint8.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/MemoryManager.h"
+#include "G3D/BumpMapPreprocess.h"
+
+namespace G3D {
+class BinaryInput;
+class BinaryOutput;
+
+
+/**
+ Interface to image compression & file formats.
+
+ Supported formats (decode and encode): Color JPEG, PNG,
+ (Uncompressed)TGA 24, (Uncompressed)TGA 32, BMP 1, BMP 4, BMP 8, BMP
+ 24, PPM (P6), and PPM ASCII (P1, P2, P3), which includes PPM, PGM,
+ and PBM. 8-bit paletted PCX, 24-bit PCX, and ICO are supported for
+ decoding only.
+
+ Sample usage:
+
+ \verbatim
+ // Loading from disk:
+ G3D::GImage im1("test.jpg");
+
+ // Loading from memory:
+ G3D::GImage im2(data, length);
+
+ // im.pixel is a pointer to RGB color data. If you want
+ // an alpha channel, call RGBtoRGBA or RGBtoARGB for
+ // conversion.
+
+ // Saving to memory:
+ G3D::GImage im3(width, height);
+ // (Set the pixels of im3...)
+ uint8* data2;
+ int len2;
+ im3.encode(G3D::GImage::JPEG, data2, len2);
+
+ // Saving to disk
+ im3.save("out.jpg");
+ \endverbatim
+
+ The free Image Magick Magick Wand API
+ (http://www.imagemagick.org/www/api/magick_wand.html) provides a more powerful
+ API for image manipulation and wider set of image load/save formats. It is
+ recommended over GImage (we don't include it directly in G3D because their license
+ is more restrictive than the BSD one).
+
+ */
+class GImage {
+private:
+
+ /** Used exclusively for allocating m_byte; this may be an
+ implementation that allocates directly on a GPU.*/
+ MemoryManager::Ref m_memMan;
+ uint8* m_byte;
+
+ int m_channels;
+ int m_width;
+ int m_height;
+
+public:
+
+ class Error {
+ public:
+ Error(
+ const std::string& reason,
+ const std::string& filename = "") :
+ reason(reason), filename(filename) {}
+
+ std::string reason;
+ std::string filename;
+ };
+
+ /** PGM, PPM, and PBM all come in two versions and are classified as PPM_* files */
+ enum Format {JPEG, BMP, TGA, PCX, ICO, PNG,
+ PPM_BINARY, PGM_BINARY = PPM_BINARY,
+ PPM_ASCII, PGM_ASCII = PPM_ASCII,
+ AUTODETECT, UNKNOWN};
+
+
+ /**
+ The number of channels; either 3 (RGB) or 4 (RGBA)
+ */
+ inline int channels() const {
+ return m_channels;
+ }
+
+ inline int width() const {
+ return m_width;
+ }
+
+ inline int height() const {
+ return m_height;
+ }
+
+ inline const uint8* byte() const {
+ return m_byte;
+ }
+
+ /** Returns a pointer to the underlying data, which is stored
+ in row-major order without row padding.
+ e.g., <code>uint8* ptr = image.rawData<uint8>();
+ */
+ template<typename Type>
+ inline const Type* rawData() const {
+ return (Type*)m_byte;
+ }
+
+ /** \copybrief GImage::rawData() const */
+ template<typename Type>
+ inline Type* rawData() {
+ return (Type*)m_byte;
+ }
+
+ inline const Color1uint8* pixel1() const {
+ debugAssertM(m_channels == 1, format("Tried to call GImage::pixel1 on an image with %d channels", m_channels));
+ return (Color1uint8*)m_byte;
+ }
+
+ inline Color1uint8* pixel1() {
+ debugAssertM(m_channels == 1, format("Tried to call GImage::pixel1 on an image with %d channels", m_channels));
+ return (Color1uint8*)m_byte;
+ }
+
+ /** Returns a pointer to the upper left pixel
+ as Color4uint8.
+ */
+ inline const Color4uint8* pixel4() const {
+ debugAssertM(m_channels == 4, format("Tried to call GImage::pixel4 on an image with %d channels", m_channels));
+ return (Color4uint8*)m_byte;
+ }
+
+ inline Color4uint8* pixel4() {
+ debugAssert(m_channels == 4);
+ return (Color4uint8*)m_byte;
+ }
+
+ /** Returns a pointer to the upper left pixel
+ as Color3uint8.
+ */
+ inline const Color3uint8* pixel3() const {
+ debugAssertM(m_channels == 3, format("Tried to call GImage::pixel3 on an image with %d channels", m_channels));
+ return (Color3uint8*)m_byte;
+ }
+
+ inline Color3uint8* pixel3() {
+ debugAssert(m_channels == 3);
+ return (Color3uint8*)m_byte;
+ }
+
+ /** Returns the pixel at (x, y), where (0,0) is the upper left. */
+ inline const Color1uint8& pixel1(int x, int y) const {
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel1()[x + y * m_width];
+ }
+
+ /** Returns the pixel at (x, y), where (0,0) is the upper left. */
+ inline Color1uint8& pixel1(int x, int y) {
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel1()[x + y * m_width];
+ }
+
+ /** Returns the pixel at (x, y), where (0,0) is the upper left. */
+ inline const Color3uint8& pixel3(int x, int y) const {
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel3()[x + y * m_width];
+ }
+
+ inline Color3uint8& pixel3(int x, int y) {
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel3()[x + y * m_width];
+ }
+
+ /** Returns the pixel at (x, y), where (0,0) is the upper left. */
+ inline const Color4uint8& pixel4(int x, int y) const {
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel4()[x + y * m_width];
+ }
+
+ inline Color4uint8& pixel4(int x, int y) {
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel4()[x + y * m_width];
+ }
+
+ inline uint8* byte() {
+ return m_byte;
+ }
+
+private:
+
+ void encodeBMP(
+ BinaryOutput& out) const;
+
+ /**
+ The TGA file will be either 24- or 32-bit depending
+ on the number of channels.
+ */
+ void encodeTGA(
+ BinaryOutput& out) const;
+
+ /**
+ Converts this image into a JPEG
+ */
+ void encodeJPEG(
+ BinaryOutput& out) const;
+
+ /**
+ Converts this image into a JPEG
+ */
+ void encodePNG(
+ BinaryOutput& out) const;
+
+ void encodePPM(
+ BinaryOutput& out) const;
+
+ void encodePPMASCII(
+ BinaryOutput& out) const;
+
+ void decodeTGA(
+ BinaryInput& input);
+
+ void decodeBMP(
+ BinaryInput& input);
+
+ void decodeJPEG(
+ BinaryInput& input);
+
+ void decodePCX(
+ BinaryInput& input);
+
+ void decodeICO(
+ BinaryInput& input);
+
+ void decodePNG(
+ BinaryInput& input);
+
+ void decodePPM(
+ BinaryInput& input);
+
+ void decodePPMASCII(
+ BinaryInput& input);
+
+ /**
+ Given [maybe] a filename, memory buffer, and [maybe] a format,
+ returns the most likely format of this file.
+ */
+ static Format resolveFormat(
+ const std::string& filename,
+ const uint8* data,
+ int dataLen,
+ Format maybeFormat);
+
+ void _copy(
+ const GImage& other);
+
+public:
+
+ /** Predicts the image file format of \a filename */
+ static Format resolveFormat(const std::string& filename);
+
+ void flipHorizontal();
+ void flipVertical();
+ void rotate90CW(int numTimes = 1);
+
+ /**
+ Create an empty image of the given size.
+ \sa load()
+ */
+ GImage(
+ int width = 0,
+ int height = 0,
+ int channels = 3,
+ const MemoryManager::Ref& m = MemoryManager::create());
+
+ /**
+ Load an encoded image from disk and decode it.
+ Throws GImage::Error if something goes wrong.
+ */
+ GImage(
+ const std::string& filename,
+ Format format = AUTODETECT,
+ const MemoryManager::Ref& m = MemoryManager::create());
+
+ /**
+ Decodes an image stored in a buffer.
+ */
+ GImage(
+ const unsigned char*data,
+ int length,
+ Format format = AUTODETECT,
+ const MemoryManager::Ref& m = MemoryManager::create());
+
+ GImage(
+ const GImage& other,
+ const MemoryManager::Ref& m = MemoryManager::create());
+
+ GImage& operator=(const GImage& other);
+
+ /**
+ Returns a new GImage that has 4 channels. RGB is
+ taken from this GImage and the alpha from the red
+ channel of the supplied image. The new GImage is passed
+ as a reference parameter for speed.
+ */
+ void insertRedAsAlpha(const GImage& alpha, GImage& output) const;
+
+ /**
+ Returns a new GImage with 3 channels, removing
+ the alpha channel if there is one. The new GImage
+ is passed as a reference parameter for speed.
+ */
+ void stripAlpha(GImage& output) const;
+
+ /**
+ Loads an image from disk (clearing the old one first),
+ using the existing memory manager.
+ */
+ void load(
+ const std::string& filename,
+ Format format = AUTODETECT);
+
+ /**
+ Frees memory and resets to a 0x0 image.
+ */
+ void clear();
+
+ /**
+ Deallocates the pixels.
+ */
+ virtual ~GImage();
+
+ /**
+ Resizes the internal buffer to (\a width x \a height) with the
+ number of \a channels specified.
+
+ \param zero If true, all data is set to 0 (black).
+ */
+ void resize(int width, int height, int channels, bool zero = true);
+
+ /**
+ Copies src sub-image data into dest at a certain offset.
+ The dest variable must already contain an image that is large
+ enough to contain the src sub-image at the specified offset.
+ Returns true on success and false if the src sub-image cannot
+ completely fit within dest at the specified offset. Both
+ src and dest must have the same number of channels.
+ */
+ static bool pasteSubImage(
+ GImage& dest,
+ const GImage& src,
+ int destX,
+ int destY,
+ int srcX,
+ int srcY,
+ int srcWidth,
+ int srcHeight);
+
+ /**
+ creates dest from src sub-image data.
+ Returns true on success and false if the src sub-image
+ is not within src.
+ */
+ static bool copySubImage(GImage & dest, const GImage & src,
+ int srcX, int srcY, int srcWidth, int srcHeight);
+
+ void convertToRGBA();
+
+ void convertToRGB();
+
+ /** Averages color channels if they exist */
+ void convertToL8();
+
+ /**
+ Returns true if format is supported. Format
+ should be an extension string (e.g. "BMP").
+ */
+ static bool supportedFormat(
+ const std::string& format);
+
+ /**
+ Converts a string to an enum, returns UNKNOWN if not recognized.
+ */
+ static Format stringToFormat(
+ const std::string& format);
+
+ /**
+ Encode and save to disk.
+ */
+ void save(
+ const std::string& filename,
+ Format format = AUTODETECT) const;
+
+ /**
+ The caller must delete the returned buffer.
+ TODO: provide a memory manager
+ */
+ void encode(
+ Format format,
+ uint8*& outData,
+ int& outLength) const;
+
+ /**
+ Does not commit the BinaryOutput when done.
+ */
+ void encode(
+ Format format,
+ BinaryOutput& out) const;
+
+ /**
+ Decodes the buffer into this image.
+ @param format Must be the correct format.
+ */
+ void decode(
+ BinaryInput& input,
+ Format format);
+
+ /** Returns the size of this object in bytes */
+ int sizeInMemory() const;
+
+ /** Ok for in == out */
+ static void R8G8B8_to_Y8U8V8(int width, int height, const uint8* in, uint8* out);
+
+ /** Ok for in == out */
+ static void Y8U8V8_to_R8G8B8(int width, int height, const uint8* in, uint8* out);
+
+ /**
+ @param in RGB buffer of numPixels * 3 bytes
+ @param out Buffer of numPixels * 4 bytes
+ @param numPixels Number of RGB pixels to convert
+ */
+ static void RGBtoRGBA(
+ const uint8* in,
+ uint8* out,
+ int numPixels);
+
+ static void RGBtoARGB(
+ const uint8* in,
+ uint8* out,
+ int numPixels);
+
+ static void LtoRGB
+ (const uint8* in,
+ uint8* out,
+ int numPixels);
+
+ static void LtoRGBA
+ (const uint8* in,
+ uint8* out,
+ int numPixels);
+
+ /** Safe for in == out */
+ static void RGBtoBGR(
+ const uint8* in,
+ uint8* out,
+ int numPixels);
+
+ /**
+ Win32 32-bit HDC format.
+ */
+ static void RGBtoBGRA(
+ const uint8* in,
+ uint8* out,
+ int numPixels);
+
+ static void RGBAtoRGB(
+ const uint8* in,
+ uint8* out,
+ int numPixels);
+ /**
+ Uses the red channel of the second image as an alpha channel.
+ */
+ static void RGBxRGBtoRGBA(
+ const uint8* colorRGB,
+ const uint8* alphaRGB,
+ uint8* out,
+ int numPixels);
+
+ /**
+ Flips the image along the vertical axis.
+ Safe for in == out.
+ */
+ static void flipRGBVertical(
+ const uint8* in,
+ uint8* out,
+ int width,
+ int height);
+
+ static void flipRGBAVertical(
+ const uint8* in,
+ uint8* out,
+ int width,
+ int height);
+
+ /**
+ Given a tangent space bump map, computes a new image where the
+ RGB channels are a tangent space normal map and the alpha channel
+ is the original bump map. Assumes the input image is tileable.
+
+ In the resulting image, x = red = tangent, y = green = binormal, and z = blue = normal.
+
+ Particularly useful as part of the idiom:
+ <PRE>
+ GImage normal;
+ computeNormalMap(GImage(filename), normal);
+ return Texture::fromGImage(filename, normal);
+ </PRE>
+
+ */
+ static void computeNormalMap(
+ const class GImage& bump,
+ class GImage& normal,
+ const BumpMapPreprocess& preprocess = BumpMapPreprocess());
+
+ static void computeNormalMap
+ (int width,
+ int height,
+ int channels,
+ const uint8* src,
+ GImage& normal,
+ const BumpMapPreprocess& preprocess = BumpMapPreprocess());
+
+ /**
+ Bayer demosaicing using the filter proposed in
+
+ HIGH-QUALITY LINEAR INTERPOLATION FOR DEMOSAICING OF BAYER-PATTERNED COLOR IMAGES
+ Henrique S. Malvar, Li-wei He, and Ross Cutler
+
+ The filter wraps at the image boundaries.
+
+ Assumes in != out.
+ */
+ static void BAYER_G8B8_R8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out);
+ static void BAYER_G8R8_B8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out);
+ static void BAYER_R8G8_G8B8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out);
+ static void BAYER_B8G8_G8R8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out);
+
+ /** Fast conversion; the output has 1/2 the size of the input in each direction. Assumes in != out.
+ See G3D::BAYER_G8B8_R8G8_to_R8G8B8_MHC for a much better result. */
+ static void BAYER_G8B8_R8G8_to_Quarter_R8G8B8
+ (int inWidth,
+ int inHeight,
+ const uint8* in,
+ uint8* out);
+
+ /** Attempt to undo fast conversion of G3D::BAYER_G8B8_R8G8_to_Quarter_R8G8B8;
+ the green channel will lose data. Assumes in != out
+ The input should have size 3 * inWidth * inHeight. The output should have size
+ 2 * inWidth * 2 * inHeight.
+ */
+ static void Quarter_R8G8B8_to_BAYER_G8B8_R8G8
+ (int inWidth,
+ int inHeight,
+ const uint8* in,
+ uint8* out);
+
+ /** Overwrites every pixel with one of the two colors in a checkerboard pattern.
+ The fields used from the two colors depend on the current number of channels in @a im.
+ */
+ static void makeCheckerboard
+ (GImage& im,
+ int checkerSize = 1,
+ const Color4uint8& color1 = Color4uint8(255,255,255,255),
+ const Color4uint8& color2 = Color4uint8(0,0,0,255));
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/GLight.h b/dep/include/g3dlite/G3D/GLight.h
new file mode 100644
index 00000000000..3a95f1a8114
--- /dev/null
+++ b/dep/include/g3dlite/G3D/GLight.h
@@ -0,0 +1,106 @@
+/**
+ @file GLight.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-11-12
+ @edited 2009-11-08
+*/
+
+#ifndef G3D_GLight_h
+#define G3D_GLight_h
+
+#include "G3D/platform.h"
+#include "G3D/Vector4.h"
+#include "G3D/Vector3.h"
+#include "G3D/Color4.h"
+
+namespace G3D {
+class Any;
+
+/**
+ A light representation that closely follows the OpenGL light format.
+ */
+class GLight {
+public:
+ /** World space position (for a directional light, w = 0 */
+ Vector4 position;
+
+ /** For a spot or directional light, this is the "right vector" that will be used when constructing
+ a reference frame(). */
+ Vector3 rightDirection;
+
+ /** Direction in which the light faces, if a spot light. This is the "look vector" of the light source. */
+ Vector3 spotDirection;
+
+ /** In <B>degrees</B>. 180 = no cutoff (point/dir). Values less than 90 = spot light */
+ float spotCutoff;
+
+ /** If true, G3D::SuperShader will render a cone of light large
+ enough to encompass the entire square that bounds the cutoff
+ angle. This produces a square prism instead of a cone of light
+ when used with a G3D::ShadowMap. for an unshadowed light this
+ has no effect.*/
+ bool spotSquare;
+
+ /** Constant, linear, quadratic */
+ float attenuation[3];
+
+ /** May be outside the range [0, 1] */
+ Color3 color;
+
+ /** If false, this light is ignored */
+ bool enabled;
+
+ /** If false, this light does not create specular highlights
+ (useful when using negative lights). */
+ bool specular;
+
+ /** If false, this light does not create diffuse illumination
+ (useful when rendering a specular-only pass). */
+ bool diffuse;
+
+ GLight();
+
+ /** Accepted forms:
+ - GLight::directional( vector3, color3, [bool, [bool]])
+ - GLight::spot(vector3, vector3, #, color3, [#, [#, [#, [#, [bool, [bool]]]])
+ - GLight::point(vector3, color3, [#, [#, [#, [#, [bool, [bool]]]])
+ - GLight { [all fields] }
+ */
+ GLight(const Any& any);
+
+ /** Converts the Color3 to an Any. */
+ operator Any() const;
+
+ /** @param toLight will be normalized */
+ static GLight directional(const Vector3& toLight, const Color3& color, bool specular = true, bool diffuse = true);
+
+ static GLight point(const Vector3& pos, const Color3& color, float constAtt = 1, float linAtt = 0, float quadAtt = 0.5f, bool specular = true, bool diffuse = true);
+
+ /** @param pointDirection Will be normalized. Points in the
+ direction that light propagates.
+
+ @param cutOffAngleDegrees Must be on the range [0, 90]. This
+ is the angle from the point direction to the edge of the light
+ cone. I.e., a value of 45 produces a light with a 90-degree
+ cone of view.
+ */
+ static GLight spot(const Vector3& pos, const Vector3& pointDirection, float cutOffAngleDegrees,
+ const Color3& color, float constAtt = 1, float linAtt = 0, float quadAtt = 0,
+ bool specular = true, bool diffuse = true);
+
+ /** Returns the sphere within which this light has some noticable effect. May be infinite.
+ @param cutoff The value at which the light intensity is considered negligible. */
+ class Sphere effectSphere(float cutoff = 30.0f / 255) const;
+
+ /** Computes a reference frame (e.g., for use with G3D::ShadowMap */
+ class CoordinateFrame frame() const;
+
+ bool operator==(const GLight& other) const;
+ bool operator!=(const GLight& other) const;
+};
+
+} // namespace
+#endif
+
diff --git a/dep/include/g3dlite/G3D/GMutex.h b/dep/include/g3dlite/G3D/GMutex.h
new file mode 100644
index 00000000000..3469b812736
--- /dev/null
+++ b/dep/include/g3dlite/G3D/GMutex.h
@@ -0,0 +1,123 @@
+/**
+ @file GMutex.h
+
+ @created 2005-09-22
+ @edited 2009-03-25
+ */
+
+#ifndef G3D_GMutex_h
+#define G3D_GMutex_h
+
+#include "G3D/platform.h"
+#include "G3D/AtomicInt32.h"
+#include "G3D/debugAssert.h"
+#include <string>
+
+#ifndef G3D_WIN32
+# include <pthread.h>
+# include <signal.h>
+#endif
+
+
+namespace G3D {
+
+/**
+ \brief A mutual exclusion lock that busy-waits when locking.
+
+ On a machine with one (significant) thread per processor core,
+ a spinlock may be substantially faster than a mutex.
+
+ \sa G3D::GThread, G3D::GMutex, G3D::AtomicInt32
+ */
+class Spinlock {
+private:
+
+ AtomicInt32 x;
+
+public:
+
+ inline Spinlock() : x(0) {}
+
+ /** Busy waits until the lock is unlocked, then locks it
+ exclusively. Returns true if the lock succeeded on the first
+ try (indicating no contention). */
+ inline bool lock() {
+ bool first = true;
+ while (x.compareAndSet(0, 1) == 1) {
+ first = false;
+# ifdef G3D_WIN32
+ Sleep(0);
+# else
+ usleep(0);
+# endif
+ }
+ return first;
+ }
+
+ inline void unlock() {
+ x.compareAndSet(1, 0);
+ }
+
+};
+
+/**
+ \brief Mutual exclusion lock used for synchronization.
+
+ @sa G3D::GThread, G3D::AtomicInt32, G3D::Spinlock
+*/
+class GMutex {
+private:
+# ifdef G3D_WIN32
+ CRITICAL_SECTION m_handle;
+# else
+ pthread_mutex_t m_handle;
+ pthread_mutexattr_t m_attr;
+# endif
+
+ // Not implemented on purpose, don't use
+ GMutex(const GMutex &mlock);
+ GMutex &operator=(const GMutex &);
+ bool operator==(const GMutex&);
+
+public:
+ GMutex();
+ ~GMutex();
+
+ /** Locks the mutex or blocks until available. */
+ void lock();
+
+ /** Locks the mutex if it not already locked.
+ Returns true if lock successful, false otherwise. */
+ bool tryLock();
+
+ /** Unlocks the mutex. */
+ void unlock();
+};
+
+
+/**
+ Automatically locks while in scope.
+*/
+class GMutexLock {
+private:
+ GMutex* m;
+
+ // Not implemented on purpose, don't use
+ GMutexLock(const GMutexLock &mlock);
+ GMutexLock &operator=(const GMutexLock &);
+ bool operator==(const GMutexLock&);
+
+public:
+ GMutexLock(GMutex* mutex) {
+ m = mutex;
+ m->lock();
+ }
+
+ ~GMutexLock() {
+ m->unlock();
+ }
+};
+
+} // G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/GThread.h b/dep/include/g3dlite/G3D/GThread.h
new file mode 100644
index 00000000000..58437efc3fb
--- /dev/null
+++ b/dep/include/g3dlite/G3D/GThread.h
@@ -0,0 +1,121 @@
+/**
+ @file GThread.h
+
+ @created 2005-09-22
+ @edited 2007-01-31
+
+ */
+
+#ifndef G3D_GTHREAD_H
+#define G3D_GTHREAD_H
+
+#include "G3D/platform.h"
+#include "G3D/ReferenceCount.h"
+#include <string>
+
+#ifndef G3D_WIN32
+# include <pthread.h>
+# include <signal.h>
+#endif
+
+
+namespace G3D {
+
+typedef ReferenceCountedPointer<class GThread> GThreadRef;
+
+/**
+ Platform independent thread implementation. You can either subclass and
+ override GThread::threadMain or call the create method with a method.
+
+ Beware of reference counting and threads. If circular references exist between
+ GThread subclasses then neither class will ever be deallocated. Also,
+ dropping all pointers (and causing deallocation) of a GThread does NOT
+ stop the underlying process.
+
+ @sa G3D::GMutex, G3D::Spinlock, G3D::AtomicInt32
+*/
+class GThread : public ReferenceCountedObject {
+private:
+ // "Status" is a reserved work on FreeBSD
+ enum GStatus {STATUS_CREATED, STATUS_STARTED, STATUS_RUNNING, STATUS_COMPLETED};
+
+ // Not implemented on purpose, don't use
+ GThread(const GThread &);
+ GThread& operator=(const GThread&);
+ bool operator==(const GThread&);
+
+#ifdef G3D_WIN32
+ static DWORD WINAPI internalThreadProc(LPVOID param);
+#else
+ static void* internalThreadProc(void* param);
+#endif //G3D_WIN32
+
+ volatile GStatus m_status;
+
+ // Thread handle to hold HANDLE and pthread_t
+#ifdef G3D_WIN32
+ HANDLE m_handle;
+ HANDLE m_event;
+#else
+ pthread_t m_handle;
+#endif //G3D_WIN32
+
+ std::string m_name;
+
+protected:
+
+ /** Overriden by the thread implementor */
+ virtual void threadMain() = 0;
+
+public:
+ typedef ReferenceCountedPointer<class GThread> Ref;
+ enum SpawnBehavior {USE_NEW_THREAD, USE_CURRENT_THREAD};
+
+ GThread(const std::string& name);
+
+ virtual ~GThread();
+
+ /** Constructs a basic GThread without requiring a subclass.
+
+ @param proc The global or static function for the threadMain() */
+ static GThreadRef create(const std::string& name, void (*proc)(void*), void* param = NULL);
+
+ /** Starts the thread and executes threadMain(). Returns false if
+ the thread failed to start (either because it was already started
+ or because the OS refused).
+
+ @param behavior If USE_CURRENT_THREAD, rather than spawning a new thread, this routine
+ runs threadMain on the current thread.
+ */
+ bool start(SpawnBehavior behavior = USE_NEW_THREAD);
+
+ /** Terminates the thread without notifying or
+ waiting for a cancelation point. */
+ void terminate();
+
+ /**
+ Returns true if threadMain is currently executing. This will
+ only be set when the thread is actually running and might not
+ be set when start() returns. */
+ bool running() const;
+
+ /** True after start() has been called, even through the thread
+ may have already completed(), or be currently running().*/
+ bool started() const;
+
+ /** Returns true if the thread has exited. */
+ bool completed() const;
+
+ /** Waits for the thread to finish executing. */
+ void waitForCompletion();
+
+ /** Returns thread name */
+ inline const std::string& name() {
+ return m_name;
+ }
+};
+
+
+} // namespace G3D
+
+#endif //G3D_GTHREAD_H
diff --git a/dep/include/g3dlite/G3D/GUniqueID.h b/dep/include/g3dlite/G3D/GUniqueID.h
new file mode 100644
index 00000000000..c8b775c2e66
--- /dev/null
+++ b/dep/include/g3dlite/G3D/GUniqueID.h
@@ -0,0 +1,69 @@
+/**
+ @file GUniqueID.h
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ */
+#ifndef G3D_GUNIQUEID_H
+#define G3D_GUNIQUEID_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Table.h"
+
+namespace G3D {
+
+/** Globally unique identifiers. The probability of two different
+ programs generating the same value from UniqueID::create is
+ vanishingly small.
+
+ UniqueIDs optionally contain a 10-bit application specific tag
+ that distinguishes their type.
+*/
+class GUniqueID {
+private:
+
+ uint64 id;
+
+public:
+
+ GUniqueID() : id(0) {}
+
+ bool uninitialized() const {
+ return id == 0;
+ }
+
+ uint16 tag() const {
+ return id >> 54;
+ }
+
+ operator uint64() const {
+ return id;
+ }
+
+ bool operator==(const GUniqueID& other) const {
+ return id == other.id;
+ }
+
+ bool operator!=(const GUniqueID& other) const {
+ return id != other.id;
+ }
+
+ void serialize(class BinaryOutput& b) const;
+
+ void deserialize(class BinaryInput& b);
+
+ void serialize(class TextOutput& t) const;
+
+ void deserialize(class TextInput& t);
+
+ /** Create a new ID */
+ static GUniqueID create(uint16 tag = 0);
+};
+
+} // G3D
+
+/** For Table and Set */
+template<> struct HashTrait<class G3D::GUniqueID> {
+ static size_t hashCode(G3D::GUniqueID id) { return (size_t)(G3D::uint64)id; }
+};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/HashTrait.h b/dep/include/g3dlite/G3D/HashTrait.h
new file mode 100644
index 00000000000..ca35da48643
--- /dev/null
+++ b/dep/include/g3dlite/G3D/HashTrait.h
@@ -0,0 +1,92 @@
+/**
+ @file HashTrait.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2008-10-01
+ @edited 2009-11-01
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_HashTrait_h
+#define G3D_HashTrait_h
+
+#include "G3D/platform.h"
+#include "G3D/Crypto.h"
+#include "G3D/g3dmath.h"
+#include "G3D/uint128.h"
+
+/** Must be specialized for custom types.
+ @see G3D::Table for specialization requirements.
+*/
+template <typename T> struct HashTrait{};
+
+template <typename T> struct HashTrait<T*> {
+ static size_t hashCode(const void* k) { return reinterpret_cast<size_t>(k); }
+};
+
+#if 0
+template <> struct HashTrait <int> {
+ static size_t hashCode(int k) { return static_cast<size_t>(k); }
+};
+#endif
+
+template <> struct HashTrait <G3D::int16> {
+ static size_t hashCode(G3D::int16 k) { return static_cast<size_t>(k); }
+};
+
+template <> struct HashTrait <G3D::uint16> {
+ static size_t hashCode(G3D::uint16 k) { return static_cast<size_t>(k); }
+};
+
+//template <> struct HashTrait <int> {
+// static size_t hashCode(int k) { return static_cast<size_t>(k); }
+//};
+
+template <> struct HashTrait <G3D::int32> {
+ static size_t hashCode(G3D::int32 k) { return static_cast<size_t>(k); }
+};
+
+template <> struct HashTrait <G3D::uint32> {
+ static size_t hashCode(G3D::uint32 k) { return static_cast<size_t>(k); }
+};
+
+#if 0
+template <> struct HashTrait <long unsigned int> {
+ static size_t hashCode(G3D::uint32 k) { return static_cast<size_t>(k); }
+};
+#endif
+
+template <> struct HashTrait <G3D::int64> {
+ static size_t hashCode(G3D::int64 k) { return static_cast<size_t>(k); }
+};
+
+template <> struct HashTrait <G3D::uint64> {
+ static size_t hashCode(G3D::uint64 k) { return static_cast<size_t>(k); }
+};
+
+template <> struct HashTrait <std::string> {
+ static size_t hashCode(const std::string& k) { return static_cast<size_t>(G3D::Crypto::crc32(k.c_str(), k.size())); }
+};
+
+template <> struct HashTrait<G3D::uint128> {
+ // Use the FNV-1 hash (http://isthe.com/chongo/tech/comp/fnv/#FNV-1).
+ static size_t hashCode(G3D::uint128 key) {
+ static const G3D::uint128 FNV_PRIME_128(1 << 24, 0x159);
+ static const G3D::uint128 FNV_OFFSET_128(0xCF470AAC6CB293D2ULL, 0xF52F88BF32307F8FULL);
+
+ G3D::uint128 hash = FNV_OFFSET_128;
+ G3D::uint128 mask(0, 0xFF);
+ for (int i = 0; i < 16; ++i) {
+ hash *= FNV_PRIME_128;
+ hash ^= (mask & key);
+ key >>= 8;
+ }
+
+ G3D::uint64 foldedHash = hash.hi ^ hash.lo;
+ return static_cast<size_t>((foldedHash >> 32) ^ (foldedHash & 0xFFFFFFFF));
+ }
+};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Image1.h b/dep/include/g3dlite/G3D/Image1.h
new file mode 100644
index 00000000000..711e83f2079
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Image1.h
@@ -0,0 +1,81 @@
+/**
+ @file Image1.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+
+#ifndef G3D_IMAGE1_H
+#define G3D_IMAGE1_H
+
+#include "G3D/platform.h"
+#include "G3D/Map2D.h"
+#include "G3D/Color1.h"
+#include "G3D/GImage.h"
+
+namespace G3D {
+
+typedef ReferenceCountedPointer<class Image1> Image1Ref;
+
+/**
+ Luminance image with 32-bit floating point storage.
+
+ See also G3D::Image1uint8, G3D::GImage.
+ */
+class Image1 : public Map2D<Color1, Color1> {
+public:
+
+ typedef Image1 Type;
+ typedef ReferenceCountedPointer<class Image1> Ref;
+ typedef Color1 Storage;
+ typedef Color1 Compute;
+
+protected:
+
+ Image1(int w, int h, WrapMode wrap);
+
+ void copyGImage(const class GImage& im);
+ void copyArray(const Color1* src, int w, int h);
+ void copyArray(const Color3* src, int w, int h);
+ void copyArray(const Color4* src, int w, int h);
+ void copyArray(const Color1uint8* src, int w, int h);
+ void copyArray(const Color3uint8* src, int w, int h);
+ void copyArray(const Color4uint8* src, int w, int h);
+
+public:
+
+ const class ImageFormat* format() const;
+
+ /** Creates an all-zero width x height image. */
+ static Ref createEmpty(int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ /** Creates a 0 x 0 image. */
+ static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
+
+ static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromImage1uint8(const ReferenceCountedPointer<class Image1uint8>& im);
+
+ static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
+
+ /** Loads from any of the file formats supported by G3D::GImage. If there is an alpha channel on the input,
+ it is stripped. */
+ void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Saves in any of the formats supported by G3D::GImage. */
+ void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+};
+
+} // G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Image1uint8.h b/dep/include/g3dlite/G3D/Image1uint8.h
new file mode 100644
index 00000000000..f32e022e92a
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Image1uint8.h
@@ -0,0 +1,80 @@
+/**
+ @file Image1uint8.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+#ifndef G3D_IMAGE1UINT8_H
+#define G3D_IMAGE1UINT8_H
+
+#include "G3D/platform.h"
+#include "G3D/Map2D.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/Color1.h"
+#include "G3D/GImage.h"
+
+namespace G3D {
+
+typedef ReferenceCountedPointer<class Image1uint8> Image1uint8Ref;
+
+/**
+ Compact storage for luminance 8-bit images.
+
+ See also G3D::Image3, G3D::GImage
+ */
+class Image1uint8 : public Map2D<Color1uint8, Color1> {
+public:
+
+ typedef Image1uint8 Type;
+ typedef Image1uint8Ref Ref;
+
+protected:
+
+ Image1uint8(int w, int h, WrapMode wrap);
+
+ void copyGImage(const class GImage& im);
+ void copyArray(const Color1* src, int w, int h);
+ void copyArray(const Color3* src, int w, int h);
+ void copyArray(const Color4* src, int w, int h);
+ void copyArray(const Color1uint8* src, int w, int h);
+ void copyArray(const Color3uint8* src, int w, int h);
+ void copyArray(const Color4uint8* src, int w, int h);
+
+public:
+
+ const class ImageFormat* format() const;
+
+ /** Creates an all-zero width x height image. */
+ static Ref createEmpty(int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ /** Creates a 0 x 0 image. */
+ static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
+
+ static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromImage1(const ReferenceCountedPointer<class Image1>& im);
+ static Ref fromImage3uint8(const ReferenceCountedPointer<class Image3uint8>& im);
+
+ /** Loads from any of the file formats supported by G3D::GImage. If there is an alpha channel on the input,
+ it is stripped. */
+ void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Saves in any of the formats supported by G3D::GImage. */
+ void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+};
+
+} // G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Image3.h b/dep/include/g3dlite/G3D/Image3.h
new file mode 100644
index 00000000000..13cb8fa7faf
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Image3.h
@@ -0,0 +1,81 @@
+/**
+ @file Image3.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+
+#ifndef G3D_IMAGE3_H
+#define G3D_IMAGE3_H
+
+#include "G3D/platform.h"
+#include "G3D/Map2D.h"
+#include "G3D/Color3.h"
+#include "G3D/GImage.h"
+
+namespace G3D {
+
+typedef ReferenceCountedPointer<class Image3> Image3Ref;
+
+/**
+ RGB image with 32-bit floating point storage for each channel.
+
+ See also G3D::Image3uint8, G3D::GImage.
+ */
+class Image3 : public Map2D<Color3, Color3> {
+public:
+
+ typedef Image3 Type;
+ typedef ReferenceCountedPointer<class Image3> Ref;
+ typedef Color3 Storage;
+ typedef Color3 Compute;
+
+protected:
+
+ Image3(int w, int h, WrapMode wrap);
+
+ void copyGImage(const class GImage& im);
+ void copyArray(const Color1* src, int w, int h);
+ void copyArray(const Color3* src, int w, int h);
+ void copyArray(const Color4* src, int w, int h);
+ void copyArray(const Color1uint8* src, int w, int h);
+ void copyArray(const Color3uint8* src, int w, int h);
+ void copyArray(const Color4uint8* src, int w, int h);
+
+public:
+
+ const class ImageFormat* format() const;
+
+ /** Creates an all-zero width x height image. */
+ static Ref createEmpty(int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ /** Creates a 0 x 0 image. */
+ static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
+
+ static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromImage3uint8(const ReferenceCountedPointer<class Image3uint8>& im);
+
+ static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
+
+ /** Loads from any of the file formats supported by G3D::GImage. If there is an alpha channel on the input,
+ it is stripped. */
+ void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Saves in any of the formats supported by G3D::GImage. */
+ void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+};
+
+} // G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Image3uint8.h b/dep/include/g3dlite/G3D/Image3uint8.h
new file mode 100644
index 00000000000..d4fdbc169ca
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Image3uint8.h
@@ -0,0 +1,85 @@
+/**
+ @file Image3uint8.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+#ifndef G3D_IMAGE3UINT8_H
+#define G3D_IMAGE3UINT8_H
+
+#include "G3D/platform.h"
+#include "G3D/Map2D.h"
+#include "G3D/Color3uint8.h"
+#include "G3D/Color3.h"
+#include "G3D/GImage.h"
+
+namespace G3D {
+
+typedef ReferenceCountedPointer<class Image3uint8> Image3uint8Ref;
+
+/**
+ Compact storage for RGB 8-bit per channel images.
+
+ See also G3D::Image3, G3D::GImage
+ */
+class Image3uint8 : public Map2D<Color3uint8, Color3> {
+public:
+
+ typedef Image3uint8 Type;
+ typedef Image3uint8Ref Ref;
+
+protected:
+
+ Image3uint8(int w, int h, WrapMode wrap);
+
+ void copyGImage(const class GImage& im);
+ void copyArray(const Color1* src, int w, int h);
+ void copyArray(const Color3* src, int w, int h);
+ void copyArray(const Color4* src, int w, int h);
+ void copyArray(const Color1uint8* src, int w, int h);
+ void copyArray(const Color3uint8* src, int w, int h);
+ void copyArray(const Color4uint8* src, int w, int h);
+
+public:
+
+ const class ImageFormat* format() const;
+
+ /** Creates an all-zero width x height image. */
+ static Ref createEmpty(int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+
+ /** Creates a 0 x 0 image. */
+ static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
+
+
+ static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
+
+ static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromImage3(const ReferenceCountedPointer<class Image3>& im);
+ static Ref fromImage1uint8(const ReferenceCountedPointer<class Image1uint8>& im);
+
+ /** Loads from any of the file formats supported by G3D::GImage. If there is an alpha channel on the input,
+ it is stripped. */
+ void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Saves in any of the formats supported by G3D::GImage. */
+ void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Extracts color channel 0 <= c <= 2 and returns it as a new monochrome image. */
+ ReferenceCountedPointer<class Image1uint8> getChannel(int c) const;
+};
+
+} // G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Image4.h b/dep/include/g3dlite/G3D/Image4.h
new file mode 100644
index 00000000000..21d7f1e79b1
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Image4.h
@@ -0,0 +1,86 @@
+/**
+ @file Image4.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+
+#ifndef G3D_IMAGE4_H
+#define G3D_IMAGE4_H
+
+#include "G3D/platform.h"
+#include "G3D/Map2D.h"
+#include "G3D/Color4.h"
+#include "G3D/GImage.h"
+
+namespace G3D {
+
+typedef ReferenceCountedPointer<class Image4> Image4Ref;
+
+/**
+ RGBA image with 32-bit floating point storage for each channel.
+
+ Whenever a method needs to convert from RGB to RGBA, A=1 is assumed.
+
+ Bilinear interpolation on Image4 is about 8x faster than on
+ Image4uint8 due to the large cost of converting int->float on modern
+ machines.
+
+ @sa G3D::Image4uint8, G3D::GImage.
+ */
+class Image4 : public Map2D<Color4, Color4> {
+public:
+
+ typedef Image4 Type;
+ typedef ReferenceCountedPointer<class Image4> Ref;
+ typedef Color4 Storage;
+ typedef Color4 Compute;
+
+protected:
+
+ Image4(int w, int h, WrapMode wrap);
+
+ void copyGImage(const class GImage& im);
+ void copyArray(const Color1* src, int w, int h);
+ void copyArray(const Color3* src, int w, int h);
+ void copyArray(const Color4* src, int w, int h);
+ void copyArray(const Color1uint8* src, int w, int h);
+ void copyArray(const Color3uint8* src, int w, int h);
+ void copyArray(const Color4uint8* src, int w, int h);
+
+public:
+
+ const class ImageFormat* format() const;
+
+ /** Creates an all-zero width x height image. */
+ static Ref createEmpty(int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ /** Creates a 0 x 0 image. */
+ static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
+
+ static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromImage4uint8(const ReferenceCountedPointer<class Image4uint8>& im);
+
+ static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
+
+ /** Loads from any of the file formats supported by G3D::GImage. */
+ void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Saves in any of the formats supported by G3D::GImage. */
+ void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+};
+
+} // G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Image4uint8.h b/dep/include/g3dlite/G3D/Image4uint8.h
new file mode 100644
index 00000000000..46df6b490b4
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Image4uint8.h
@@ -0,0 +1,85 @@
+/**
+ @file Image4uint8.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+#ifndef G3D_IMAGE4UINT8_H
+#define G3D_IMAGE4UINT8_H
+
+#include "G3D/platform.h"
+#include "G3D/Map2D.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/Color4.h"
+#include "G3D/GImage.h"
+#include "G3D/Image1uint8.h"
+
+namespace G3D {
+
+typedef ReferenceCountedPointer<class Image4uint8> Image4uint8Ref;
+
+/**
+ Compact storage for RGBA 8-bit per channel images.
+
+ See also G3D::Image4, G3D::GImage
+ */
+class Image4uint8 : public Map2D<Color4uint8, Color4> {
+public:
+
+ typedef Image4uint8 Type;
+ typedef Image4uint8Ref Ref;
+
+protected:
+
+ Image4uint8(int w, int h, WrapMode wrap);
+
+ void copyGImage(const class GImage& im);
+ void copyArray(const Color1* src, int w, int h);
+ void copyArray(const Color3* src, int w, int h);
+ void copyArray(const Color4* src, int w, int h);
+ void copyArray(const Color1uint8* src, int w, int h);
+ void copyArray(const Color3uint8* src, int w, int h);
+ void copyArray(const Color4uint8* src, int w, int h);
+
+public:
+
+ const class ImageFormat* format() const;
+
+ /** Creates an all-zero width x height image. */
+ static Ref createEmpty(int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+
+ /** Creates a 0 x 0 image. */
+ static Ref createEmpty(WrapMode wrap = WrapMode::ERROR);
+
+
+ static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
+
+ static Ref fromGImage(const class GImage& im, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color3* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color4* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+
+ static Ref fromImage4(const ReferenceCountedPointer<class Image4>& im);
+
+ /** Loads from any of the file formats supported by G3D::GImage. If there is an alpha channel on the input,
+ it is stripped. */
+ void load(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Saves in any of the formats supported by G3D::GImage. */
+ void save(const std::string& filename, GImage::Format fmt = GImage::AUTODETECT);
+
+ /** Extracts color channel 0 <= c <= 3 and returns it as a new monochrome image. */
+ ReferenceCountedPointer<class Image1uint8> getChannel(int c) const;
+};
+
+} // G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/ImageFormat.h b/dep/include/g3dlite/G3D/ImageFormat.h
new file mode 100644
index 00000000000..7f098322d26
--- /dev/null
+++ b/dep/include/g3dlite/G3D/ImageFormat.h
@@ -0,0 +1,419 @@
+/**
+ @file ImageFormat.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-05-23
+ @edited 2010-01-01
+*/
+
+#ifndef GLG3D_ImageFormat_H
+#define GLG3D_ImageFormat_H
+
+#include "G3D/platform.h"
+#include "G3D/Table.h"
+#include "G3D/enumclass.h"
+
+namespace G3D {
+
+/** Information about common image formats.
+ Don't construct these; use the methods provided.
+
+ For most formats, the number indicates the number of bits per channel and a suffix of "F" indicates
+ floating point. This does not hold for the YUV and DXT formats.*/
+class ImageFormat {
+public:
+
+ // Must update ImageFormat::name() when this enum changes.
+ enum Code {
+ CODE_NONE = -1,
+ CODE_L8,
+ CODE_L16,
+ CODE_L16F,
+ CODE_L32F,
+
+ CODE_A8,
+ CODE_A16,
+ CODE_A16F,
+ CODE_A32F,
+
+ CODE_LA4,
+ CODE_LA8,
+ CODE_LA16,
+ CODE_LA16F,
+ CODE_LA32F,
+
+ CODE_RGB5,
+ CODE_RGB5A1,
+ CODE_RGB8,
+ CODE_RGB10,
+ CODE_RGB10A2,
+ CODE_RGB16,
+ CODE_RGB16F,
+ CODE_RGB32F,
+ CODE_R11G11B10F,
+ CODE_RGB9E5F,
+
+ CODE_RGB8I,
+ CODE_RGB8UI,
+
+ CODE_ARGB8,
+ CODE_BGR8,
+
+ CODE_RG8,
+ CODE_RG8I,
+ CODE_RG8UI,
+
+ CODE_RGBA8,
+ CODE_RGBA16,
+ CODE_RGBA16F,
+ CODE_RGBA32F,
+
+ CODE_RGBA32UI,
+
+ CODE_BAYER_RGGB8,
+ CODE_BAYER_GRBG8,
+ CODE_BAYER_GBRG8,
+ CODE_BAYER_BGGR8,
+ CODE_BAYER_RGGB32F,
+ CODE_BAYER_GRBG32F,
+ CODE_BAYER_GBRG32F,
+ CODE_BAYER_BGGR32F,
+
+ CODE_HSV8,
+ CODE_HSV32F,
+
+ CODE_YUV420_PLANAR,
+ CODE_YUV422,
+ CODE_YUV444,
+
+ CODE_RGB_DXT1,
+ CODE_RGBA_DXT1,
+ CODE_RGBA_DXT3,
+ CODE_RGBA_DXT5,
+
+ CODE_SRGB8,
+ CODE_SRGBA8,
+
+ CODE_SL8,
+ CODE_SLA8,
+
+ CODE_SRGB_DXT1,
+ CODE_SRGBA_DXT1,
+ CODE_SRGBA_DXT3,
+ CODE_SRGBA_DXT5,
+
+ CODE_DEPTH16,
+ CODE_DEPTH24,
+ CODE_DEPTH32,
+ CODE_DEPTH32F,
+
+ CODE_STENCIL1,
+ CODE_STENCIL4,
+ CODE_STENCIL8,
+ CODE_STENCIL16,
+
+ CODE_DEPTH24_STENCIL8,
+
+ CODE_NUM
+ };
+
+ enum ColorSpace {
+ COLOR_SPACE_NONE,
+ COLOR_SPACE_RGB,
+ COLOR_SPACE_HSV,
+ COLOR_SPACE_YUV,
+ COLOR_SPACE_SRGB
+ };
+
+ enum BayerPattern {
+ BAYER_PATTERN_NONE,
+ BAYER_PATTERN_RGGB,
+ BAYER_PATTERN_GRBG,
+ BAYER_PATTERN_GBRG,
+ BAYER_PATTERN_BGGR
+ };
+
+ /** Number of channels (1 for a depth texture). */
+ int numComponents;
+ bool compressed;
+
+ /** Useful for serializing. */
+ Code code;
+
+ ColorSpace colorSpace;
+
+ /** If this is a Bayer format, what is the pattern. */
+ BayerPattern bayerPattern;
+
+ /** The OpenGL format equivalent to this one, e.g, GL_RGB8 Zero if there is no equivalent. This is actually a GLenum */
+ int openGLFormat;
+
+ /** The OpenGL base format equivalent to this one (e.g., GL_RGB, GL_ALPHA). Zero if there is no equivalent. */
+ int openGLBaseFormat;
+
+ int luminanceBits;
+
+ /** Number of bits per pixel storage for alpha values; Zero for compressed textures and non-RGB. */
+ int alphaBits;
+
+ /** Number of bits per pixel storage for red values; Zero for compressed textures and non-RGB. */
+ int redBits;
+
+ /** Number of bits per pixel storage for green values; Zero for compressed textures and non-RGB. */
+ int greenBits;
+
+ /** Number of bits per pixel storage for blue values; Zero for compressed textures and non-RGB. */
+ int blueBits;
+
+ /** Number of bits per pixel */
+ int stencilBits;
+
+ /** Number of depth bits (for depth textures; e.g. shadow maps) */
+ int depthBits;
+
+ /** Amount of CPU memory per pixel when packed into an array, discounting any end-of-row padding. */
+ int cpuBitsPerPixel;
+
+ /** Amount of CPU memory per pixel when packed into an array, discounting any end-of-row padding.
+ @deprecated Use cpuBitsPerPixel*/
+ int packedBitsPerTexel;
+
+ /**
+ Amount of GPU memory per pixel on most graphics cards, for formats supported by OpenGL. This is
+ only an estimate--the actual amount of memory may be different on your actual card.
+
+ This may be greater than the sum of the per-channel bits
+ because graphics cards need to pad to the nearest 1, 2, or
+ 4 bytes.
+ */
+ int openGLBitsPerPixel;
+
+ /** @deprecated Use openGLBitsPerPixel */
+ int hardwareBitsPerTexel;
+
+ /** The OpenGL bytes (type) format of the data buffer used with this texture format, e.g., GL_UNSIGNED_BYTE */
+ int openGLDataFormat;
+
+ /** True if there is no alpha channel for this texture. */
+ bool opaque;
+
+ /** True if the bit depths specified are for float formats. */
+ bool floatingPoint;
+
+ /** Human readable name of this format.*/
+ const std::string& name() const;
+
+ /** Takes the same values that name() returns */
+ static const ImageFormat* fromString(const std::string& s);
+
+private:
+
+ ImageFormat
+ (int numComponents,
+ bool compressed,
+ int glFormat,
+ int glBaseFormat,
+ int luminanceBits,
+ int alphaBits,
+ int redBits,
+ int greenBits,
+ int blueBits,
+ int depthBits,
+ int stencilBits,
+ int hardwareBitsPerTexel,
+ int packedBitsPerTexel,
+ int glDataFormat,
+ bool opaque,
+ bool floatingPoint,
+ Code code,
+ ColorSpace colorSpace,
+ BayerPattern bayerPattern = BAYER_PATTERN_NONE);
+
+public:
+
+ static const ImageFormat* L8();
+
+ static const ImageFormat* L16();
+
+ static const ImageFormat* L16F();
+
+ static const ImageFormat* L32F();
+
+ static const ImageFormat* A8();
+
+ static const ImageFormat* A16();
+
+ static const ImageFormat* A16F();
+
+ static const ImageFormat* A32F();
+
+ static const ImageFormat* LA4();
+
+ static const ImageFormat* LA8();
+
+ static const ImageFormat* LA16();
+
+ static const ImageFormat* LA16F();
+
+ static const ImageFormat* LA32F();
+
+ static const ImageFormat* BGR8();
+
+ static const ImageFormat* RG8();
+ static const ImageFormat* RG8I();
+ static const ImageFormat* RG8UI();
+
+ static const ImageFormat* RGB5();
+
+ static const ImageFormat* RGB5A1();
+
+ static const ImageFormat* RGB8();
+
+ static const ImageFormat* RGB10();
+
+ static const ImageFormat* RGB10A2();
+
+ static const ImageFormat* RGB16();
+
+ static const ImageFormat* RGB16F();
+
+ static const ImageFormat* RGB32F();
+
+ static const ImageFormat* RGBA8();
+
+ static const ImageFormat* RGBA16();
+
+ static const ImageFormat* RGBA16F();
+
+ static const ImageFormat* RGBA32F();
+
+ static const ImageFormat* RGBA32UI();
+
+ static const ImageFormat* R11G11B10F();
+
+ static const ImageFormat* RGB9E5F();
+
+ static const ImageFormat* RGB8I();
+
+ static const ImageFormat* RGB8UI();
+
+ static const ImageFormat* RGB_DXT1();
+
+ static const ImageFormat* RGBA_DXT1();
+
+ static const ImageFormat* RGBA_DXT3();
+
+ static const ImageFormat* RGBA_DXT5();
+
+ static const ImageFormat* SRGB8();
+
+ static const ImageFormat* SRGBA8();
+
+ static const ImageFormat* SL8();
+
+ static const ImageFormat* SLA8();
+
+ static const ImageFormat* SRGB_DXT1();
+
+ static const ImageFormat* SRGBA_DXT1();
+
+ static const ImageFormat* SRGBA_DXT3();
+
+ static const ImageFormat* SRGBA_DXT5();
+
+ static const ImageFormat* DEPTH16();
+
+ static const ImageFormat* DEPTH24();
+
+ static const ImageFormat* DEPTH32();
+
+ static const ImageFormat* DEPTH32F();
+
+ static const ImageFormat* STENCIL1();
+
+ static const ImageFormat* STENCIL4();
+
+ static const ImageFormat* STENCIL8();
+
+ static const ImageFormat* STENCIL16();
+
+ static const ImageFormat* DEPTH24_STENCIL8();
+
+ static const ImageFormat* YUV420_PLANAR();
+
+ static const ImageFormat* YUV422();
+
+ static const ImageFormat* YUV444();
+
+ /**
+ NULL pointer; indicates that the G3D::Texture class should choose
+ either RGBA8 or RGB8 depending on the presence of an alpha channel
+ in the input.
+ */
+ static const ImageFormat* AUTO() { return NULL; }
+
+ /** Returns DEPTH16, DEPTH24, or DEPTH32 according to the bits
+ specified. You can use "glGetInteger(GL_DEPTH_BITS)" to match
+ the screen's format.*/
+ static const ImageFormat* depth(int depthBits = 24);
+
+ /** Returns STENCIL1, STENCIL4, STENCIL8 or STENCIL16 according to the bits
+ specified. You can use "glGetInteger(GL_STENCIL_BITS)" to match
+ the screen's format.*/
+ static const ImageFormat* stencil(int bits = 8);
+
+ /** Returns the matching ImageFormat* identified by the Code. May return NULL
+ if this format's code is reserved but not yet implemented by G3D. */
+ static const ImageFormat* fromCode(ImageFormat::Code code);
+
+
+
+ /** For use with ImageFormat::convert. */
+ class BayerAlgorithm {
+ public:
+ enum Value {
+ NEAREST,
+ BILINEAR,
+ MHC,
+ HIGH_QUALITY = MHC
+ };
+ private:
+
+ Value value;
+
+ public:
+
+ G3D_DECLARE_ENUM_CLASS_METHODS(BayerAlgorithm);
+ };
+
+ /** Converts between arbitrary formats on the CPU. Not all format conversions are supported or directly supported.
+ Formats without direct conversions will attempt to convert through RGBA first.
+
+ A conversion routine might only support source or destination padding or y inversion or none.
+ If support is needed and not available in any of the direct conversion routines, then no conversion is done.
+
+ YUV422 expects data in YUY2 format (Y, U, Y2, v). Most YUV formats require width and heights that are multiples of 2.
+
+ Returns true if a conversion was available, false if none occurred.
+ */
+ static bool convert(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits,
+ const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits,
+ bool invertY = false, BayerAlgorithm bayerAlg = BayerAlgorithm::HIGH_QUALITY);
+
+ /* Checks if a conversion between two formats is available. */
+ static bool conversionAvailable(const ImageFormat* srcFormat, int srcRowPadBits, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY = false);
+};
+
+typedef ImageFormat TextureFormat;
+
+}
+
+template <>
+struct HashTrait<const G3D::ImageFormat*> {
+ static size_t hashCode(const G3D::ImageFormat* key) { return reinterpret_cast<size_t>(key); }
+};
+
+
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Intersect.h b/dep/include/g3dlite/G3D/Intersect.h
new file mode 100644
index 00000000000..4a3c8fb4540
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Intersect.h
@@ -0,0 +1,55 @@
+/**
+ @file Intersect.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-06-29
+ @edited 2009-06-29
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+
+ From the G3D Innovation Engine
+ http://g3d.sf.net
+ */
+#ifndef G3D_Intersect
+#define G3D_Intersect
+
+#include "G3D/platform.h"
+#include "G3D/Ray.h"
+#include "G3D/AABox.h"
+
+namespace G3D {
+
+/**
+ @beta
+ */
+class Intersect {
+public:
+
+ /** \brief Returns true if the intersection of the ray and the solid box is non-empty.
+
+ \cite "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
+ by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
+ Computer Graphics Lab, TU Braunschweig, Germany and
+ University of Koblenz-Landau, Germany
+ */
+ static bool __fastcall rayAABox(const Ray& ray, const AABox& box);
+
+ /** \brief Returns true if the intersection of the ray and the solid box is non-empty.
+
+ \param time If there is an intersection, set to the time to that intersection. If the ray origin is inside the box,
+ this is a negative value indicating the distance backwards from the ray origin to the first intersection.
+ \a time is not set if there is no intersection.
+
+ \cite Slope-Mul method from "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
+ by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
+ Computer Graphics Lab, TU Braunschweig, Germany and
+ University of Koblenz-Landau, Germany
+ */
+ static bool __fastcall rayAABox(const Ray& ray, const AABox& box, float& time);
+};
+
+}
+
+#endif
diff --git a/src/shared/vmap/AABSPTree.h b/dep/include/g3dlite/G3D/KDTree.h
index 1a7b17cdaa2..4785ef2baea 100644
--- a/src/shared/vmap/AABSPTree.h
+++ b/dep/include/g3dlite/G3D/KDTree.h
@@ -1,88 +1,100 @@
/**
- @file AABSPTree.h
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+ @file KDTree.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2004-01-11
- @edited 2007-02-16
-
- Copyright 2000-2007, Morgan McGuire.
- All rights reserved.
+ @edited 2009-12-28
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
*/
-#ifndef G3D_AABSPTREE_H
-#define G3D_AABSPTREE_H
-
-#include "VMapTools.h"
+#ifndef G3D_KDTREE_H
+#define G3D_KDTREE_H
#include "G3D/platform.h"
#include "G3D/Array.h"
#include "G3D/Table.h"
+#include "G3D/Vector2.h"
#include "G3D/Vector3.h"
+#include "G3D/Vector4.h"
#include "G3D/AABox.h"
#include "G3D/Sphere.h"
#include "G3D/Box.h"
#include "G3D/Triangle.h"
#include "G3D/Ray.h"
#include "G3D/GCamera.h"
-#if 0
#include "G3D/BinaryInput.h"
#include "G3D/BinaryOutput.h"
-#endif
#include "G3D/CollisionDetection.h"
#include "G3D/GCamera.h"
+#include "G3D/BoundsTrait.h"
#include <algorithm>
// If defined, in debug mode the tree is checked for consistency
// as a way of detecting corruption due to implementation bugs
// #define VERIFY_TREE
-inline void getBounds(const G3D::Vector3& v, G3D::AABox& out) {
- out = G3D::AABox(v);
-}
+template<> struct BoundsTrait<class G3D::Vector2> {
+ static void getBounds(const G3D::Vector2& v, G3D::AABox& out) { out = G3D::AABox(G3D::Vector3(v, 0)); }
+};
-inline void getBounds(const G3D::AABox& a, G3D::AABox& out) {
- out = a;
-}
+template<> struct BoundsTrait<class G3D::Vector3> {
+ static void getBounds(const G3D::Vector3& v, G3D::AABox& out) { out = G3D::AABox(v); }
+};
-inline void getBounds(const G3D::Sphere& s, G3D::AABox& out) {
- s.getBounds(out);
-}
+template<> struct BoundsTrait<class G3D::Vector4> {
+ static void getBounds(const G3D::Vector4& v, G3D::AABox& out) { out = G3D::AABox(v.xyz()); }
+};
-inline void getBounds(const G3D::Box& b, G3D::AABox& out) {
- b.getBounds(out);
-}
+template<> struct BoundsTrait<class G3D::AABox> {
+ static void getBounds(const G3D::AABox& v, G3D::AABox& out) { out = v; }
+};
-inline void getBounds(const G3D::Triangle& t, G3D::AABox& out) {
- t.getBounds(out);
-}
+template<> struct BoundsTrait<class G3D::Sphere> {
+ static void getBounds(const G3D::Sphere& s, G3D::AABox& out) { s.getBounds(out); }
+};
-inline void getBounds(const G3D::Vector3* v, G3D::AABox& out) {
- out = G3D::AABox(*v);
-}
+template<> struct BoundsTrait<class G3D::Box> {
+ static void getBounds(const G3D::Box& b, G3D::AABox& out) { b.getBounds(out); }
+};
-inline void getBounds(const G3D::AABox* a, G3D::AABox& out) {
- getBounds(*a, out);
-}
+template<> struct BoundsTrait<class G3D::Vector2*> {
+ static void getBounds(const G3D::Vector2*& v, G3D::AABox& out) { out = G3D::AABox(G3D::Vector3(*v, 0)); }
+};
-inline void getBounds(const G3D::Sphere* s, G3D::AABox& out) {
- s->getBounds(out);
-}
+template<> struct BoundsTrait<class G3D::Vector3*> {
+ static void getBounds(const G3D::Vector3*& v, G3D::AABox& out) { out = G3D::AABox(*v); }
+};
-inline void getBounds(const G3D::Box* b, G3D::AABox& out) {
- b->getBounds(out);
-}
+template<> struct BoundsTrait<class G3D::Vector4*> {
+ static void getBounds(const G3D::Vector4*& v, G3D::AABox& out) { out = G3D::AABox(v->xyz()); }
+};
+
+template<> struct BoundsTrait<class G3D::AABox*> {
+ static void getBounds(const G3D::AABox*& v, G3D::AABox& out) { out = *v; }
+};
+
+template<> struct BoundsTrait<class G3D::Sphere*> {
+ static void getBounds(const G3D::Sphere*& s, G3D::AABox& out) { s->getBounds(out); }
+};
+
+template<> struct BoundsTrait<class G3D::Box*> {
+ static void getBounds(const G3D::Box*& b, G3D::AABox& out) { b->getBounds(out); }
+};
+
+
+template<> struct BoundsTrait<class G3D::Triangle*> {
+ static void getBounds(const G3D::Triangle*& t, G3D::AABox& out) { t->getBounds(out); }
+};
-inline void getBounds(const G3D::Triangle* t, G3D::AABox& out) {
- t->getBounds(out);
-}
namespace G3D {
namespace _internal {
/**
Wraps a pointer value so that it can be treated as the instance itself;
- convenient for inserting pointers into a Table but using the
+ convenient for inserting pointers into a Table but using the
object equality instead of pointer equality.
*/
template<class Type>
@@ -95,11 +107,11 @@ namespace G3D {
inline Indirector() : handle(NULL) {}
/** Returns true iff the values referenced by the handles are equivalent. */
- inline bool operator==(const Indirector& m) {
+ inline bool operator==(const Indirector& m) const {
return *handle == *(m.handle);
}
- inline bool operator==(const Type& m) {
+ inline bool operator==(const Type& m) const {
return *handle == m;
}
@@ -110,28 +122,26 @@ namespace G3D {
} // namespace internal
} // namespace G3D
-template <class Handle>
-struct GHashCode< G3D::_internal::Indirector<Handle> >
-{
- size_t operator()(const G3D::_internal::Indirector<Handle>& key) const { return key.hashCode(); }
+template <class Handle> struct HashTrait<typename G3D::_internal::Indirector<Handle> > {
+ static size_t hashCode(const G3D::_internal::Indirector<Handle>& key) { return key.hashCode(); }
};
namespace G3D {
/**
- A set that supports spatial queries using an axis-aligned
- BSP tree for speed.
+ A set that supports spatial queries using a KD tree (axis-aligned
+ BSP tree) for speed.
- AABSPTree allows you to quickly find objects in 3D that lie within
+ KDTree allows you to quickly find objects in 3D that lie within
a box or along a ray. For large sets of objects it is much faster
than testing each object for a collision.
- AABSPTree is as powerful as but more general than a Quad Tree, Oct
- Tree, or KD Tree, but less general than an unconstrained BSP tree
+ KDTree is as powerful as but more general than a Quad Tree, Oct
+ Tree, or regular KD tree that cycles through axes, but less general than an unconstrained BSP tree
(which is much slower to create).
-
+
Internally, objects
- are arranged into an axis-aligned BSP-tree according to their
+ are arranged into a tree according to their
axis-aligned bounds. This increases the cost of insertion to
O(log n) but allows fast overlap queries.
@@ -139,10 +149,11 @@ namespace G3D {
<DT>The template parameter <I>T</I> must be one for which
the following functions are all overloaded:
- <P><CODE>void ::getBounds(const T&, G3D::AABox&);</CODE>
- <DT><CODE>bool ::operator==(const T&, const T&);</CODE>
- <DT><CODE>unsigned int ::hashCode(const T&);</CODE>
- <DT><CODE>T::T();</CODE> <I>(public constructor of no arguments)</I>
+ <pre>
+ T::T(); // public constructor of no arguments
+ template <> struct HashTrait<T> { static size_t hashCode(int key); };
+ template<> struct BoundsTrait<T> { static void getBounds(const T& obj, G3D::AABox& out); };
+ </pre>
G3D provides these for common classes like G3D::Vector3 and G3D::Sphere.
If you use a custom class, or a pointer to a custom class, you will need
@@ -150,19 +161,20 @@ namespace G3D {
<B>Moving %Set Members</B>
<DT>It is important that objects do not move without updating the
- AABSPTree. If the axis-aligned bounds of an object are about
- to change, AABSPTree::remove it before they change and
- AABSPTree::insert it again afterward. For objects
- where the hashCode and == operator are invariant with respect
+ KDTree. If the axis-aligned bounds of an object are about
+ to change, KDTree::remove it before they change and
+ KDTree::insert it again afterward. For objects
+ where the hashCode and == operator are invariant with respect
to the 3D position,
- you can use the AABSPTree::update method as a shortcut to
+ you can use the KDTree::update method as a shortcut to
insert/remove an object in one step after it has moved.
+
- Note: Do not mutate any value once it has been inserted into AABSPTree. Values
- are copied interally. All AABSPTree iterators convert to pointers to constant
+ Note: Do not mutate any value once it has been inserted into KDTree. Values
+ are copied interally. All KDTree iterators convert to pointers to constant
values to reinforce this.
- If you want to mutate the objects you intend to store in a AABSPTree
+ If you want to mutate the objects you intend to store in a KDTree
simply insert <I>pointers</I> to your objects instead of the objects
themselves, and ensure that the above operations are defined. (And
actually, because values are copied, if your values are large you may
@@ -170,23 +182,28 @@ namespace G3D {
operation faster.)
<B>Dimensions</B>
- Although designed as a 3D-data structure, you can use the AABSPTree
+ Although designed as a 3D-data structure, you can use the KDTree
for data distributed along 2 or 1 axes by simply returning bounds
that are always zero along one or more dimensions.
*/
-namespace _AABSPTree {
+template< class T,
+ class BoundsFunc = BoundsTrait<T>,
+ class HashFunc = HashTrait<T>,
+ class EqualsFunc = EqualsTrait<T> >
+class KDTree {
+protected:
+#define TreeType KDTree<T, BoundsFunc, HashFunc, EqualsFunc>
- /** Wrapper for a value that includes a cache of its bounds.
+ /** Wrapper for a value that includes a cache of its bounds.
Except for the test value used in a set-query operation, there
- is only ever one instance of the handle associated with any
+ is only ever one instance of the handle associated with any
value and the memberTable and Nodes maintain pointers to that
heap-allocated value.
*/
- template<class TValue>
class Handle {
public:
- /** The bounds of each object are constrained to AABox::maxFinite */
+ /** The bounds of each object are constrained to AABox::large */
AABox bounds;
/** Center of bounds. We cache this value to avoid recomputing it
@@ -195,73 +212,46 @@ namespace _AABSPTree {
a floating point roundoff issue, where B<A and A<B both are true).*/
Vector3 center;
- TValue value;
-
- Handle<TValue>() {}
-
- inline Handle<TValue>(const TValue& v) : value(v) {
- getBounds(v, bounds);
- bounds = bounds.intersect(AABox::maxFinite());
- center = bounds.center();
- }
-
- inline bool operator==(const Handle<TValue>& other) const {
- return (*value).operator==(*other.value);
- }
-
- inline size_t hashCode() const {
- return value->hashCode();
- }
- };
-
- template<>
- class Handle<Triangle> {
- public:
- /** The bounds of each object are constrained to AABox::maxFinite */
- AABox bounds;
+ T value;
- /** Center of bounds. We cache this value to avoid recomputing it
- during the median sort, and because MSVC 6 std::sort goes into
- an infinite loop if we compute the midpoint on the fly (possibly
- a floating point roundoff issue, where B<A and A<B both are true).*/
- Vector3 center;
-
- Triangle value;
-
- Handle<Triangle>() {}
+ Handle() {}
- inline Handle<Triangle>(const Triangle& v) : value(v) {
- getBounds(v, bounds);
- bounds = bounds.intersect(AABox::maxFinite());
+ inline Handle(const T& v) : value(v) {
+ BoundsFunc::getBounds(v, bounds);
+ bounds = bounds.intersect(AABox::large());
center = bounds.center();
}
- inline bool operator==(const Handle<Triangle>& other) const {
- return value.operator==(other.value);
+ inline bool operator==(const Handle& other) const {
+ return EqualsFunc::equals(value, other.value);
}
inline size_t hashCode() const {
- return value.hashCode();
+ return HashFunc::hashCode(value);
}
};
-}
-
-template<class T> class AABSPTree {
-protected:
-public:
/** Returns the bounds of the sub array. Used by makeNode. */
static AABox computeBounds(
- const Array<_AABSPTree::Handle<T>*>& point,
+ const Array<Handle*>& point,
int beginIndex,
int endIndex) {
-
+
Vector3 lo = Vector3::inf();
Vector3 hi = -lo;
+ debugAssertM(beginIndex <= endIndex, "No points");
for (int p = beginIndex; p <= endIndex; ++p) {
- lo = lo.min(point[p]->bounds.low());
- hi = hi.max(point[p]->bounds.high());
+ // This code is written with the vector min and max expanded
+ // because otherwise it compiles incorrectly with -O3 on
+ // gcc 3.4
+
+ const Vector3& pLo = point[p]->bounds.low();
+ const Vector3& pHi = point[p]->bounds.high();
+ for (int a = 0; a < 3; ++a) {
+ lo[a] = G3D::min(lo[a], pLo[a]);
+ hi[a] = G3D::max(hi[a], pHi[a]);
+ }
}
return AABox(lo, hi);
@@ -270,11 +260,11 @@ public:
/** Compares centers */
class CenterComparator {
public:
- Vector3::Axis sortAxis;
+ Vector3::Axis sortAxis;
- CenterComparator(Vector3::Axis a) : sortAxis(a) {}
+ CenterComparator(Vector3::Axis a) : sortAxis(a) {}
- inline int operator()(_AABSPTree::Handle<T>* A, const _AABSPTree::Handle<T>* B) const {
+ inline int operator()(Handle* A, const Handle* B) const {
float a = A->center[sortAxis];
float b = B->center[sortAxis];
@@ -285,17 +275,18 @@ public:
} else {
return 0;
}
- }
+ }
};
+
/** Compares bounds for strict >, <, or overlap*/
class BoundsComparator {
public:
- Vector3::Axis sortAxis;
+ Vector3::Axis sortAxis;
- BoundsComparator(Vector3::Axis a) : sortAxis(a) {}
+ BoundsComparator(Vector3::Axis a) : sortAxis(a) {}
- inline int operator()(_AABSPTree::Handle<T>* A, const _AABSPTree::Handle<T>* B) const {
+ inline int operator()(Handle* A, const Handle* B) const {
const AABox& a = A->bounds;
const AABox& b = B->bounds;
@@ -306,32 +297,34 @@ public:
} else {
return 0;
}
- }
+ }
};
+
/** Compares bounds to the sort location */
class Comparator {
public:
- Vector3::Axis sortAxis;
- float sortLocation;
+ Vector3::Axis sortAxis;
+ float sortLocation;
- Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
+ Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
- inline int operator()(_AABSPTree::Handle<T>* /*ignore*/, const _AABSPTree::Handle<T>* handle) const {
+ inline int operator()(Handle* ignore, const Handle* handle) const {
+ (void)ignore;
const AABox& box = handle->bounds;
debugAssert(ignore == NULL);
- if (box.high()[sortAxis] < sortLocation) {
+ if (box.high()[sortAxis] < sortLocation) {
// Box is strictly below the sort location
return -1;
- } else if (box.low()[sortAxis] > sortLocation) {
+ } else if (box.low()[sortAxis] > sortLocation) {
// Box is strictly above the sort location
- return 1;
- } else {
+ return 1;
+ } else {
// Box overlaps the sort location
- return 0;
- }
- }
+ return 0;
+ }
+ }
};
// Using System::malloc with this class provided no speed improvement.
@@ -346,8 +339,8 @@ public:
/** Location along the specified axis */
float splitLocation;
-
- /** child[0] contains all values strictly
+
+ /** child[0] contains all values strictly
smaller than splitLocation along splitAxis.
child[1] contains all values strictly
@@ -360,15 +353,15 @@ public:
/** Array of values at this node (i.e., values
straddling the split plane + all values if
- this is a leaf node).
+ this is a leaf node).
This is an array of pointers because that minimizes
- data movement during tree building, which accounts
+ data movement during tree building, which accounts
for about 15% of the time cost of tree building.
*/
- Array<_AABSPTree::Handle<T> * > valueArray;
+ Array<Handle*> valueArray;
- /** For each object in the value array, a copy of its bounds.
+ /** For each object in the value array, a copy of its bounds.
Packing these into an array at the node level
instead putting them in the valueArray improves
cache coherence, which is about a 3x performance
@@ -392,7 +385,7 @@ public:
Node(const Node& other) : valueArray(other.valueArray), boundsArray(other.boundsArray) {
splitAxis = other.splitAxis;
splitLocation = other.splitLocation;
- splitBounds = other.splitBounds;
+ splitBounds = other.splitBounds;
for (int i = 0; i < 2; ++i) {
child[i] = NULL;
}
@@ -400,7 +393,7 @@ public:
/** Copies the specified subarray of pt into point, NULLs the children.
Assumes a second pass will set splitBounds. */
- Node(const Array<_AABSPTree::Handle<T> * >& pt) : valueArray(pt) {
+ Node(const Array<Handle*>& pt) : valueArray(pt) {
splitAxis = Vector3::X_AXIS;
splitLocation = 0;
for (int i = 0; i < 2; ++i) {
@@ -425,11 +418,12 @@ public:
return (child[0] == NULL) && (child[1] == NULL);
}
+
/**
Recursively appends all handles and children's handles
to the array.
*/
- void getHandles(Array<_AABSPTree::Handle<T> * >& handleArray) const {
+ void getHandles(Array<Handle*>& handleArray) const {
handleArray.append(valueArray);
for (int i = 0; i < 2; ++i) {
if (child[i] != NULL) {
@@ -439,46 +433,48 @@ public:
}
void verifyNode(const Vector3& lo, const Vector3& hi) {
- // debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
- // splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
-
- debugAssert(lo == splitBounds.low());
+ // debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
+ // splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
+
+ debugAssertM(lo == splitBounds.low(),
+ format("lo = %s, splitBounds.lo = %s",
+ lo.toString().c_str(), splitBounds.low().toString().c_str()));
debugAssert(hi == splitBounds.high());
-
+
for (int i = 0; i < valueArray.length(); ++i) {
const AABox& b = valueArray[i]->bounds;
debugAssert(b == boundsArray[i]);
-
- for (int axis = 0; axis < 3; ++axis) {
+
+ for(int axis = 0; axis < 3; ++axis) {
debugAssert(b.low()[axis] <= b.high()[axis]);
debugAssert(b.low()[axis] >= lo[axis]);
debugAssert(b.high()[axis] <= hi[axis]);
}
}
-
+
if (child[0] || child[1]) {
debugAssert(lo[splitAxis] < splitLocation);
debugAssert(hi[splitAxis] > splitLocation);
}
-
+
Vector3 newLo = lo;
newLo[splitAxis] = splitLocation;
Vector3 newHi = hi;
newHi[splitAxis] = splitLocation;
-
+
if (child[0] != NULL) {
child[0]->verifyNode(lo, newHi);
}
-
+
if (child[1] != NULL) {
child[1]->verifyNode(newLo, hi);
}
}
+
-#if 0
/**
Stores the locations of the splitting planes (the structure but not the content)
- so that the tree can be quickly rebuilt from a previous configuration without
+ so that the tree can be quickly rebuilt from a previous configuration without
calling balance.
*/
static void serializeStructure(const Node* n, BinaryOutput& bo) {
@@ -507,9 +503,10 @@ public:
for (int c = 0; c < 2; ++c) {
n->child[c] = deserializeStructure(bi);
}
+ return n;
}
}
-#endif
+
/** Returns the deepest node that completely contains bounds. */
Node* findDeepestContainingNode(const AABox& bounds) {
@@ -533,13 +530,14 @@ public:
return this;
}
- /** Appends all members that intersect the box.
+
+ /** Appends all members that intersect the box.
If useSphere is true, members that pass the box test
face a second test against the sphere. */
void getIntersectingMembers(
const AABox& box,
const Sphere& sphere,
- Array<T>& members,
+ Array<T*>& members,
bool useSphere) const {
// Test all values at this node
@@ -547,7 +545,7 @@ public:
const AABox& bounds = boundsArray[v];
if (bounds.intersects(box) &&
(! useSphere || bounds.intersects(sphere))) {
- members.append(valueArray[v]->value);
+ members.append(& (valueArray[v]->value));
}
}
@@ -591,32 +589,30 @@ public:
// See if the ray will ever hit this node or its children
Vector3 location;
bool alreadyInsideBounds = false;
- bool rayWillHitBounds =
- VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
- ray.origin, ray.direction, splitBounds, location, alreadyInsideBounds);
-
- bool canHitThisNode = (alreadyInsideBounds ||
- (rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
+ bool rayWillHitBounds =
+ CollisionDetection::collisionLocationForMovingPointFixedAABox(
+ ray.origin(), ray.direction(), splitBounds, location, alreadyInsideBounds);
+
+ bool canHitThisNode = (alreadyInsideBounds ||
+ (rayWillHitBounds && ((location - ray.origin()).squaredLength() < square(distance))));
return canHitThisNode;
}
template<typename RayCallback>
void intersectRay(
- const Ray& ray,
- RayCallback& intersectCallback,
+ const Ray& ray,
+ RayCallback& intersectCallback,
float& distance,
- bool pStopAtFirstHit,
bool intersectCallbackIsFast) const {
- float enterDistance = distance;
-
+
if (! intersects(ray, distance)) {
// The ray doesn't hit this node, so it can't hit the children of the node.
return;
}
// Test for intersection against every object at this node.
- for (int v = 0; v < valueArray.size(); ++v) {
+ for (int v = 0; v < valueArray.size(); ++v) {
bool canHitThisObject = true;
if (! intersectCallbackIsFast) {
@@ -624,26 +620,24 @@ public:
Vector3 location;
const AABox& bounds = boundsArray[v];
bool alreadyInsideBounds = false;
- bool rayWillHitBounds =
- VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
- ray.origin, ray.direction, bounds, location, alreadyInsideBounds);
+ bool rayWillHitBounds =
+ CollisionDetection::collisionLocationForMovingPointFixedAABox(
+ ray.origin(), ray.direction(), bounds, location, alreadyInsideBounds);
- canHitThisObject = (alreadyInsideBounds ||
- (rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
+ canHitThisObject = (alreadyInsideBounds ||
+ (rayWillHitBounds && ((location - ray.origin()).squaredLength() < square(distance))));
}
if (canHitThisObject) {
// It is possible that this ray hits this object. Look for the intersection using the
// callback.
const T& value = valueArray[v]->value;
- intersectCallback(ray, value, pStopAtFirstHit, distance);
+ intersectCallback(ray, value, distance);
}
- if(pStopAtFirstHit && distance < enterDistance)
- return;
}
// There are three cases to consider next:
- //
+ //
// 1. the ray can start on one side of the splitting plane and never enter the other,
// 2. the ray can start on one side and enter the other, and
// 3. the ray can travel exactly down the splitting plane
@@ -652,30 +646,30 @@ public:
int firstChild = NONE;
int secondChild = NONE;
- if (ray.origin[splitAxis] < splitLocation) {
-
+ if (ray.origin()[splitAxis] < splitLocation) {
+
// The ray starts on the small side
firstChild = 0;
- if (ray.direction[splitAxis] > 0) {
+ if (ray.direction()[splitAxis] > 0) {
// The ray will eventually reach the other side
secondChild = 1;
}
- } else if (ray.origin[splitAxis] > splitLocation) {
+ } else if (ray.origin()[splitAxis] > splitLocation) {
// The ray starts on the large side
firstChild = 1;
- if (ray.direction[splitAxis] < 0) {
+ if (ray.direction()[splitAxis] < 0) {
secondChild = 0;
}
} else {
// The ray starts on the splitting plane
- if (ray.direction[splitAxis] < 0) {
+ if (ray.direction()[splitAxis] < 0) {
// ...and goes to the small side
firstChild = 0;
- } else if (ray.direction[splitAxis] > 0) {
+ } else if (ray.direction()[splitAxis] > 0) {
// ...and goes to the large side
firstChild = 1;
}
@@ -683,15 +677,13 @@ public:
// Test on the side closer to the ray origin.
if ((firstChild != NONE) && child[firstChild]) {
- child[firstChild]->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast);
- if(pStopAtFirstHit && distance < enterDistance)
- return;
+ child[firstChild]->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
}
- if (ray.direction[splitAxis] != 0) {
- // See if there was an intersection before hitting the splitting plane.
+ if (ray.direction()[splitAxis] != 0) {
+ // See if there was an intersection before hitting the splitting plane.
// If so, there is no need to look on the far side and recursion terminates.
- float distanceToSplittingPlane = (splitLocation - ray.origin[splitAxis]) / ray.direction[splitAxis];
+ float distanceToSplittingPlane = (splitLocation - ray.origin()[splitAxis]) / ray.direction()[splitAxis];
if (distanceToSplittingPlane > distance) {
// We aren't going to hit anything else before hitting the splitting plane,
// so don't bother looking on the far side of the splitting plane at the other
@@ -702,51 +694,52 @@ public:
// Test on the side farther from the ray origin.
if ((secondChild != NONE) && child[secondChild]) {
- child[secondChild]->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast);
+ child[secondChild]->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
}
}
};
+
/**
Recursively subdivides the subarray.
-
+
Clears the source array as soon as it is no longer needed.
Call assignSplitBounds() on the root node after making a tree.
*/
Node* makeNode(
- Array<_AABSPTree::Handle<T> * >& source,
- int valuesPerNode,
+ Array<Handle*>& source,
+ int valuesPerNode,
int numMeanSplits,
- Array<_AABSPTree::Handle<T> * >& temp) {
-
- Node* node = NULL;
-
- if (source.size() <= valuesPerNode) {
- // Make a new leaf node
- node = new Node(source);
-
- // Set the pointers in the memberTable
- for (int i = 0; i < source.size(); ++i) {
- memberTable.set(Member(source[i]), node);
- }
+ Array<Handle*>& temp) {
+
+ Node* node = NULL;
+
+ if (source.size() <= valuesPerNode) {
+ // Make a new leaf node
+ node = new Node(source);
+
+ // Set the pointers in the memberTable
+ for (int i = 0; i < source.size(); ++i) {
+ memberTable.set(Member(source[i]), node);
+ }
source.clear();
-
+
} else {
- // Make a new internal node
- node = new Node();
-
- const AABox bounds = computeBounds(source, 0, source.size() - 1);
- const Vector3 extent = bounds.high() - bounds.low();
-
- Vector3::Axis splitAxis = extent.primaryAxis();
-
+ // Make a new internal node
+ node = new Node();
+
+ const AABox& bounds = computeBounds(source, 0, source.size() - 1);
+ const Vector3& extent = bounds.high() - bounds.low();
+
+ Vector3::Axis splitAxis = extent.primaryAxis();
+
float splitLocation;
// Arrays for holding the children
- Array<_AABSPTree::Handle<T> * > lt, gt;
-
+ Array<Handle*> lt, gt;
+
if (numMeanSplits <= 0) {
source.medianPartition(lt, node->valueArray, gt, temp, CenterComparator(splitAxis));
@@ -774,13 +767,13 @@ public:
// is swapped in in its place.
gt.fastRemove(i); --i;
}
- }
+ }
if ((node->valueArray.size() > (source.size() / 2)) &&
(source.size() > 6)) {
- // This was a bad partition; we ended up putting the splitting plane right in the middle of most of the
- // objects. We could try to split on a different axis, or use a different partition (e.g., the extents mean,
- // or geometric mean). This implementation falls back on the extents mean, since that case is already handled
+ // This was a bad partition; we ended up putting the splitting plane right in the middle of most of the
+ // objects. We could try to split on a different axis, or use a different partition (e.g., the extents mean,
+ // or geometric mean). This implementation falls back on the extents mean, since that case is already handled
// below.
numMeanSplits = 1;
}
@@ -791,18 +784,23 @@ public:
if (numMeanSplits > 0) {
// Split along the mean
- splitLocation = (bounds.high()[splitAxis] +
- bounds.low()[splitAxis]) / 2.0;
+ splitLocation =
+ bounds.high()[splitAxis] * 0.5f +
+ bounds.low()[splitAxis] * 0.5f;
+
+ debugAssertM(isFinite(splitLocation),
+ "Internal error: split location must be finite.");
source.partition(NULL, lt, node->valueArray, gt, Comparator(splitAxis, splitLocation));
// The Comparator ensures that elements are strictly on the correct side of the split
}
+
# if defined(G3D_DEBUG) && defined(VERIFY_TREE)
debugAssert(lt.size() + node->valueArray.size() + gt.size() == source.size());
// Verify that all objects ended up on the correct side of the split.
- // (i.e., make sure that the Array partition was correct)
+ // (i.e., make sure that the Array partition was correct)
for (int i = 0; i < lt.size(); ++i) {
const AABox& bounds = lt[i]->bounds;
debugAssert(bounds.high()[splitAxis] < splitLocation);
@@ -829,22 +827,22 @@ public:
// Update the bounds array and member table
node->boundsArray.resize(node->valueArray.size());
for (int i = 0; i < node->valueArray.size(); ++i) {
- _AABSPTree::Handle<T> * v = node->valueArray[i];
+ Handle* v = node->valueArray[i];
node->boundsArray[i] = v->bounds;
- memberTable.set(Member(v), node);
- }
-
- if (lt.size() > 0) {
- node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp);
- }
-
- if (gt.size() > 0) {
- node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp);
+ memberTable.set(Member(v), node);
}
- }
-
- return node;
+ if (lt.size() > 0) {
+ node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp);
+ }
+
+ if (gt.size() > 0) {
+ node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp);
+ }
+
+ }
+
+ return node;
}
/**
@@ -874,7 +872,7 @@ public:
Wrapper for a Handle; used to create a memberTable that acts like Table<Handle, Node*> but
stores only Handle* internally to avoid memory copies.
*/
- typedef _internal::Indirector<_AABSPTree::Handle<T> > Member;
+ typedef _internal::Indirector<Handle> Member;
typedef Table<Member, Node*> MemberTable;
@@ -886,21 +884,24 @@ public:
public:
/** To construct a balanced tree, insert the elements and then call
- AABSPTree::balance(). */
- AABSPTree() : root(NULL) {}
+ KDTree::balance(). */
+ KDTree() : root(NULL) {}
+
- AABSPTree(const AABSPTree& src) : root(NULL) {
+ KDTree(const KDTree& src) : root(NULL) {
*this = src;
}
- AABSPTree& operator=(const AABSPTree& src) {
+
+ KDTree& operator=(const KDTree& src) {
delete root;
// Clone tree takes care of filling out the memberTable.
root = cloneTree(src.root);
return *this;
}
- ~AABSPTree() {
+
+ ~KDTree() {
clear();
}
@@ -908,8 +909,8 @@ public:
Throws out all elements of the set.
*/
void clear() {
- typedef typename Table<_internal::Indirector<_AABSPTree::Handle<T> >, Node* >::Iterator It;
-
+ typedef typename Table<_internal::Indirector<Handle>, Node*>::Iterator It;
+
// Delete all handles stored in the member table
It cur = memberTable.begin();
It end = memberTable.end();
@@ -925,7 +926,7 @@ public:
root = NULL;
}
- size_t size() const {
+ int size() const {
return memberTable.size();
}
@@ -940,7 +941,7 @@ public:
return;
}
- _AABSPTree::Handle<T>* h = new _AABSPTree::Handle<T>(value);
+ Handle* h = new Handle(value);
if (root == NULL) {
// This is the first node; create a root node
@@ -952,7 +953,7 @@ public:
// Insert into the node
node->valueArray.append(h);
node->boundsArray.append(h->bounds);
-
+
// Insert into the node table
Member m(h);
memberTable.set(m, node);
@@ -974,7 +975,7 @@ public:
// Insert in opposite order so that we have the exact same
// data structure as if we inserted each (i.e., order is reversed
// from array).
- _AABSPTree::Handle<T>* h = new _AABSPTree::Handle<T>(valueArray[i]);
+ Handle* h = new Handle(valueArray[i]);
int j = valueArray.size() - i - 1;
root->valueArray[j] = h;
root->boundsArray[j] = h->bounds;
@@ -989,21 +990,23 @@ public:
}
}
+
/**
Returns true if this object is in the set, otherwise
returns false. O(1) time.
*/
bool contains(const T& value) {
// Temporarily create a handle and member
- _AABSPTree::Handle<T> h(value);
+ Handle h(value);
return memberTable.containsKey(Member(&h));
}
+
/**
Removes an object from the set in O(1) time.
It is an error to remove members that are not already
- present. May unbalance the tree.
-
+ present. May unbalance the tree.
+
Removing an element never causes a node (split plane) to be removed...
nodes are only changed when the tree is rebalanced. This behavior
is desirable because it allows the split planes to be serialized,
@@ -1012,15 +1015,15 @@ public:
void remove(const T& value) {
debugAssertM(contains(value),
"Tried to remove an element from a "
- "AABSPTree that was not present");
+ "KDTree that was not present");
// Get the list of elements at the node
- _AABSPTree::Handle<T> h(value);
+ Handle h(value);
Member m(&h);
- Array<_AABSPTree::Handle<T> * >& list = memberTable[m]->valueArray;
+ Array<Handle*>& list = memberTable[m]->valueArray;
- _AABSPTree::Handle<T>* ptr = NULL;
+ Handle* ptr = NULL;
// Find the element and remove it
for (int i = list.length() - 1; i >= 0; --i) {
@@ -1046,6 +1049,7 @@ public:
ptr = NULL;
}
+
/**
If the element is in the set, it is removed.
The element is then inserted.
@@ -1054,7 +1058,7 @@ public:
on <I>T</I> are independent of the bounds. In
that case, you may call update(v) to insert an
element for the first time and call update(v)
- again every time it moves to keep the tree
+ again every time it moves to keep the tree
up to date.
*/
void update(const T& value) {
@@ -1064,20 +1068,21 @@ public:
insert(value);
}
+
/**
Rebalances the tree (slow). Call when objects
have moved substantially from their original positions
(which unbalances the tree and causes the spatial
queries to be slow).
-
+
@param valuesPerNode Maximum number of elements to put at
a node.
- @param numMeanSplits numMeanSplits = 0 gives a
+ @param numMeanSplits numMeanSplits = 0 gives a
fully axis aligned BSP-tree, where the balance operation attempts to balance
the tree so that every splitting plane has an equal number of left
- and right children (i.e. it is a <B>median</B> split along that axis).
- This tends to maximize average performance.
+ and right children (i.e. it is a <B>median</B> split along that axis).
+ This tends to maximize average performance.
You can override this behavior by
setting a number of <B>mean</B> (average) splits. numMeanSplits = MAX_INT
@@ -1103,10 +1108,10 @@ public:
}
}
- Array<_AABSPTree::Handle<T> * > temp;
- // Make a new root. Work with a copy of the value array because
+ Array<Handle*> temp;
+ // Make a new root. Work with a copy of the value array because
// makeNode clears the source array as it progresses
- Array<_AABSPTree::Handle<T> * > copy(oldRoot->valueArray);
+ Array<Handle*> copy(oldRoot->valueArray);
root = makeNode(copy, valuesPerNode, numMeanSplits, temp);
// Throw away the old root node
@@ -1115,14 +1120,26 @@ public:
// Walk the tree, assigning splitBounds. We start with unbounded
// space. This will override the current member table.
- root->assignSplitBounds(AABox::maxFinite());
+ const AABox& LARGE = AABox::large();
+ root->assignSplitBounds(LARGE);
# ifdef _DEBUG
- // Ensure that the balanced tree is till correct
- root->verifyNode(Vector3::minFinite(), Vector3::maxFinite());
+ {
+ // Ensure that the balanced tree is still correct
+ root->verifyNode(LARGE.low(), LARGE.high());
+ }
# endif
}
+
+ /** Clear, set the contents to the values in the array, and then balance */
+ void setContents(const Array<T>& array, int valuesPerNode = 5, int numMeanSplits = 3) {
+ clear();
+ insert(array);
+ balance(valuesPerNode, numMeanSplits);
+ }
+
+
protected:
/**
@@ -1130,7 +1147,7 @@ protected:
*/
static void getIntersectingMembers(
const Array<Plane>& plane,
- Array<T>& members,
+ Array<T*>& members,
Node* node,
uint32 parentMask) {
@@ -1139,7 +1156,7 @@ protected:
if (parentMask == 0) {
// None of these planes can cull anything
for (int v = node->valueArray.size() - 1; v >= 0; --v) {
- members.append(node->valueArray[v]->value);
+ members.append(& (node->valueArray[v]->value));
}
// Iterate through child nodes
@@ -1153,7 +1170,7 @@ protected:
// Test values at this node against remaining planes
for (int v = node->boundsArray.size() - 1; v >= 0; --v) {
if (! node->boundsArray[v].culledBy(plane, dummy, parentMask)) {
- members.append(node->valueArray[v]->value);
+ members.append(&(node->valueArray[v]->value));
}
}
@@ -1173,10 +1190,10 @@ protected:
public:
/**
- Returns all members inside the set of planes.
+ Returns all members inside the set of planes.
@param members The results are appended to this array.
*/
- void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
+ void getIntersectingMembers(const Array<Plane>& plane, Array<T*>& members) const {
if (root == NULL) {
return;
}
@@ -1184,10 +1201,18 @@ public:
getIntersectingMembers(plane, members, root, 0xFFFFFF);
}
+ void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(plane, temp, root, 0xFFFFFF);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
+ }
+
/**
Typically used to find all visible
objects inside the view frustum (see also GCamera::getClipPlanes)... i.e. all objects
- <B>not<B> culled by frustum.
+ <B>not</B> culled by frustum.
Example:
<PRE>
@@ -1197,9 +1222,9 @@ public:
</PRE>
@param members The results are appended to this array.
*/
- void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
+ void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T*>& members) const {
Array<Plane> plane;
-
+
for (int i = 0; i < frustum.faceArray.size(); ++i) {
plane.append(frustum.faceArray[i].plane);
}
@@ -1207,6 +1232,14 @@ public:
getIntersectingMembers(plane, members);
}
+ void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(frustum, temp);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
+ }
+
/**
C++ STL style iterator variable. See beginBoxIntersection().
The iterator overloads the -> (dereference) operator, so this
@@ -1219,7 +1252,7 @@ public:
// and allowing the computation to be restarted.
class BoxIntersectionIterator {
private:
- friend class AABSPTree<T>;
+ friend class TreeType;
/** True if this is the "end" iterator instance */
bool isEnd;
@@ -1238,14 +1271,14 @@ public:
// caller uses post increment (which they shouldn't!).
Array<Node*> stack;
- /** The next index of current->valueArray to return.
+ /** The next index of current->valueArray to return.
Undefined when isEnd is true.*/
int nextValueArrayIndex;
BoxIntersectionIterator() : isEnd(true) {}
-
- BoxIntersectionIterator(const AABox& b, const Node* root) :
- isEnd(root == NULL), box(b),
+
+ BoxIntersectionIterator(const AABox& b, const Node* root) :
+ isEnd(root == NULL), box(b),
node(const_cast<Node*>(root)), nextValueArrayIndex(-1) {
// We intentionally start at the "-1" index of the current
@@ -1268,10 +1301,10 @@ public:
} else if (other.isEnd) {
return false;
} else {
- // Two non-end iterators; see if they match. This is kind of
+ // Two non-end iterators; see if they match. This is kind of
// silly; users shouldn't call == on iterators in general unless
// one of them is the end iterator.
- if ((box != other.box) || (node != other.node) ||
+ if ((box != other.box) || (node != other.node) ||
(nextValueArrayIndex != other.nextValueArrayIndex) ||
(stack.length() != other.stack.length())) {
return false;
@@ -1300,27 +1333,27 @@ public:
// Search for the next node if we've exhausted this one
while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) {
- // If we entered this loop, then the iterator has exhausted the elements at
+ // If we entered this loop, then the iterator has exhausted the elements at
// node (possibly because it just switched to a child node with no members).
// This loop continues until it finds a node with members or reaches
// the end of the whole intersection search.
-
+
// If the right child overlaps the box, push it onto the stack for
// processing.
if ((node->child[1] != NULL) &&
(box.high()[node->splitAxis] > node->splitLocation)) {
stack.push(node->child[1]);
}
-
+
// If the left child overlaps the box, push it onto the stack for
// processing.
if ((node->child[0] != NULL) &&
(box.low()[node->splitAxis] < node->splitLocation)) {
stack.push(node->child[0]);
}
-
+
if (stack.length() > 0) {
- // Go on to the next node (which may be either one of the ones we
+ // Go on to the next node (which may be either one of the ones we
// just pushed, or one from farther back the tree).
node = stack.pop();
nextValueArrayIndex = 0;
@@ -1329,14 +1362,14 @@ public:
isEnd = true;
}
}
-
+
// Search for the next intersection at this node until we run out of children
while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
if (box.intersects(node->boundsArray[nextValueArrayIndex])) {
foundIntersection = true;
} else {
++nextValueArrayIndex;
- // If we exhaust this node, we'll loop around the master loop
+ // If we exhaust this node, we'll loop around the master loop
// to find a new node.
}
}
@@ -1347,7 +1380,8 @@ public:
private:
/**
- Post increment (much slower than preincrement!). Intentionally overloaded to preclude accidentally slow code.
+ Post increment (much slower than preincrement!).
+ Intentionally overloaded to preclude accidentally slow code.
*/
BoxIntersectionIterator operator++(int);
/*{
@@ -1380,6 +1414,7 @@ public:
}
};
+
/**
Iterates through the members that intersect the box
*/
@@ -1394,27 +1429,36 @@ public:
/**
Appends all members whose bounds intersect the box.
- See also AABSPTree::beginBoxIntersection.
+ See also KDTree::beginBoxIntersection.
*/
- void getIntersectingMembers(const AABox& box, Array<T>& members) const {
+ void getIntersectingMembers(const AABox& box, Array<T*>& members) const {
if (root == NULL) {
return;
}
root->getIntersectingMembers(box, Sphere(Vector3::zero(), 0), members, false);
}
+ void getIntersectingMembers(const AABox& box, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(box, temp);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
+ }
+
+
/**
Invoke a callback for every member along a ray until the closest intersection is found.
@param callback either a function or an instance of a class with an overloaded operator() of the form:
+
+ <code>void callback(const Ray& ray, const T& object, float& distance)</code>. If the ray hits the object
+ before travelling distance <code>distance</code>, updates <code>distance</code> with the new distance to
+ the intersection, otherwise leaves it unmodified. A common example is:
- <code>void callback(const Ray& ray, const T& object, float& distance)</code>. If the ray hits the object
- before travelling distance <code>distance</code>, updates <code>distance</code> with the new distance to
- the intersection, otherwise leaves it unmodified. A common example is:
-
- <pre>
- class Entity {
- public:
+ <pre>
+ class Entity {
+ public:
void intersect(const Ray& ray, float& maxDist, Vector3& outLocation, Vector3& outNormal) {
float d = maxDist;
@@ -1442,35 +1486,42 @@ public:
}
};
- AABSPTree<Entity*> scene;
+ KDTree<Entity*> scene;
Intersection intersection;
- float distance = inf();
+ float distance = finf();
scene.intersectRay(camera.worldRay(x, y), intersection, distance);
</pre>
- @param distance When the method is invoked, this is the maximum distance that the tree should search for an intersection.
- On return, this is set to the distance to the first intersection encountered.
- @param intersectCallbackIsFast If false, each object's bounds are tested before the intersectCallback is invoked.
- If the intersect callback runs at the same speed or faster than AABox-ray intersection, set this to true.
+ @param distance When the method is invoked, this is the maximum
+ distance that the tree should search for an intersection. On
+ return, this is set to the distance to the first intersection
+ encountered.
+
+ @param intersectCallbackIsFast If false, each object's bounds are
+ tested before the intersectCallback is invoked. If the
+ intersect callback runs at the same speed or faster than
+ AABox-ray intersection, set this to true.
*/
template<typename RayCallback>
void intersectRay(
- const Ray& ray,
- RayCallback& intersectCallback,
+ const Ray& ray,
+ RayCallback& intersectCallback,
float& distance,
- bool pStopAtFirstHit,
bool intersectCallbackIsFast = false) const {
-
- root->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast);
-
+
+ root->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
}
+
/**
+ @brief Finds all members whose bounding boxes intersect the sphere. The actual
+ elements may not intersect the sphere.
+
@param members The results are appended to this array.
*/
- void getIntersectingMembers(const Sphere& sphere, Array<T>& members) const {
+ void getIntersectingMembers(const Sphere& sphere, Array<T*>& members) const {
if (root == NULL) {
return;
}
@@ -1478,12 +1529,19 @@ public:
AABox box;
sphere.getBounds(box);
root->getIntersectingMembers(box, sphere, members, true);
+ }
+ void getIntersectingMembers(const Sphere& sphere, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(sphere, temp);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
}
-#if 0
+
/**
Stores the locations of the splitting planes (the structure but not the content)
- so that the tree can be quickly rebuilt from a previous configuration without
+ so that the tree can be quickly rebuilt from a previous configuration without
calling balance.
*/
void serializeStructure(BinaryOutput& bo) const {
@@ -1495,18 +1553,35 @@ public:
clear();
root = Node::deserializeStructure(bi);
}
-#endif
+
/**
- Returns an array of all members of the set. See also AABSPTree::begin.
+ Returns an array of all members of the set. See also KDTree::begin.
*/
void getMembers(Array<T>& members) const {
Array<Member> temp;
memberTable.getKeys(temp);
for (int i = 0; i < temp.size(); ++i) {
- members.append(temp[i].handle->value);
+ members.append(*(temp.handle));
}
}
+
+ /** If a value that is EqualsFunc to @a value is present, returns a pointer to the
+ version stored in the data structure, otherwise returns NULL.
+ */
+ const T* getPointer(const T& value) const {
+ // Temporarily create a handle and member
+ Handle h(value);
+ const Member* member = memberTable.getKeyPointer(Member(&h));
+ if (member == NULL) {
+ // Not found
+ return NULL;
+ } else {
+ return &(member->handle->value);
+ }
+ }
+
+
/**
C++ STL style iterator variable. See begin().
Overloads the -> (dereference) operator, so this acts like a pointer
@@ -1514,7 +1589,7 @@ public:
*/
class Iterator {
private:
- friend class AABSPTree<T>;
+ friend class TreeType;
// Note: this is a Table iterator, we are currently defining
// Set iterator
@@ -1564,16 +1639,18 @@ public:
}
};
+
/**
- C++ STL style iterator method. Returns the first member.
+ C++ STL style iterator method. Returns the first member.
Use preincrement (++entry) to get to the next element (iteration
- order is arbitrary).
+ order is arbitrary).
Do not modify the set while iterating.
*/
Iterator begin() const {
return Iterator(memberTable.begin());
}
+
/**
C++ STL style iterator method. Returns one after the last iterator
element.
@@ -1581,10 +1658,10 @@ public:
Iterator end() const {
return Iterator(memberTable.end());
}
+#undef TreeType
};
+
}
#endif
-
-
diff --git a/dep/include/g3dlite/G3D/Line.h b/dep/include/g3dlite/G3D/Line.h
index fedcb4d8cf0..3579a6becec 100644
--- a/dep/include/g3dlite/G3D/Line.h
+++ b/dep/include/g3dlite/G3D/Line.h
@@ -1,10 +1,10 @@
/**
@file Line.h
-
+
Line class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2001-06-02
@edited 2006-02-28
*/
@@ -38,6 +38,12 @@ public:
/** Undefined (provided for creating Array<Line> only) */
inline Line() {}
+ Line(class BinaryInput& b);
+
+ void serialize(class BinaryOutput& b) const;
+
+ void deserialize(class BinaryInput& b);
+
virtual ~Line() {}
/**
@@ -77,9 +83,23 @@ public:
is no intersection, returns a point at infinity.
*/
Vector3 intersection(const Plane &plane) const;
+
+
+ /** Finds the closest point to the two lines.
+
+ @param minDist Returns the minimum distance between the lines.
+
+ @cite http://objectmix.com/graphics/133793-coordinates-closest-points-pair-skew-lines.html
+ */
+ Vector3 closestPoint(const Line& B, float& minDist) const;
+
+ inline Vector3 closestPoint(const Line& B) const {
+ float m;
+ return closestPoint(B, m);
+ }
};
};// namespace
-#endif
+#endif
diff --git a/dep/include/g3dlite/G3D/LineSegment.h b/dep/include/g3dlite/G3D/LineSegment.h
new file mode 100644
index 00000000000..70210ec7e00
--- /dev/null
+++ b/dep/include/g3dlite/G3D/LineSegment.h
@@ -0,0 +1,115 @@
+/**
+ @file LineSegment.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-02-08
+ @edited 2008-02-02
+ */
+
+#ifndef G3D_LINESEGMENT_H
+#define G3D_LINESEGMENT_H
+
+#include "G3D/platform.h"
+#include "G3D/Vector3.h"
+
+namespace G3D {
+
+/**
+ An finite segment of an infinite 3D line.
+ */
+class LineSegment {
+protected:
+
+ Vector3 _point;
+
+ /** Not normalized */
+ Vector3 direction;
+
+ LineSegment(const Vector3& __point, const Vector3& _direction) : _point(__point), direction(_direction) {
+ }
+
+public:
+
+ inline LineSegment() : _point(Vector3::zero()), direction(Vector3::zero()) {}
+
+ LineSegment(class BinaryInput& b);
+
+ void serialize(class BinaryOutput& b) const;
+
+ void deserialize(class BinaryInput& b);
+
+ virtual ~LineSegment() {}
+
+ /**
+ * Constructs a line from two (not equal) points.
+ */
+ static LineSegment fromTwoPoints(const Vector3 &point1, const Vector3 &point2) {
+ return LineSegment(point1, point2 - point1);
+ }
+
+ /** Call with 0 or 1 */
+ Vector3 point(int i) const;
+
+ inline float length() const {
+ return direction.magnitude();
+ }
+
+ /**
+ * Returns the closest point on the line segment to point.
+ */
+ Vector3 closestPoint(const Vector3 &point) const;
+
+ /**
+ Returns the distance between point and the line
+ */
+ double distance(const Vector3& p) const {
+ return (closestPoint(p) - p).magnitude();
+ }
+
+ double distanceSquared(const Vector3& p) const {
+ return (closestPoint(p) - p).squaredMagnitude();
+ }
+
+ /** Returns true if some part of this segment is inside the sphere */
+ bool intersectsSolidSphere(const class Sphere& s) const;
+
+ Vector3 randomPoint() const;
+
+};
+
+
+class LineSegment2D {
+private:
+
+ Vector2 m_origin;
+
+ /** Not normalized */
+ Vector2 m_direction;
+
+ /** Length of m_direction */
+ float m_length;
+
+public:
+
+ LineSegment2D() {}
+
+ static LineSegment2D fromTwoPoints(const Vector2& p0, const Vector2& p1);
+
+ /** Returns the intersection of these segements (including
+ testing endpoints), or Vector2::inf() if they do not intersect. */
+ Vector2 intersection(const LineSegment2D& other) const;
+
+ Vector2 point(int i) const;
+
+ Vector2 closestPoint(const Vector2& Q) const;
+
+ float distance(const Vector2& p) const;
+
+ float length() const;
+};
+
+} // namespace
+
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Log.h b/dep/include/g3dlite/G3D/Log.h
new file mode 100644
index 00000000000..d252d0c1a17
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Log.h
@@ -0,0 +1,109 @@
+/**
+ @file Log.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Backtrace by Aaron Orenstein
+ @created 2001-08-04
+ @edited 2005-11-04
+ */
+
+#ifndef G3D_LOG_H
+#define G3D_LOG_H
+
+#include <stdio.h>
+#include <string>
+#include "G3D/platform.h"
+
+#ifndef G3D_WIN32
+ #include <stdarg.h>
+#endif
+
+namespace G3D {
+
+/** Prints to the common system log, log.txt, which is usually
+ in the working directory of the program. If your disk is
+ not writable or is slow, it will attempt to write to "c:/tmp/log.txt" or
+ "c:/temp/log.txt" on Windows systems instead.
+
+ Unlike printf or debugPrintf,
+ this function guarantees that all output is committed before it returns.
+ This is very useful for debugging a crash, which might hide the last few
+ buffered print statements otherwise.
+
+ Many G3D routines write useful warnings and debugging information to the
+ system log, which makes it a good first place to go when tracking down
+ a problem.
+ */
+void logPrintf(const char* fmt, ...);
+
+/** Does not flush the buffer; follow up with a logPrintf to force the flush. */
+void logLazyPrintf(const char* fmt, ...);
+
+/**
+ System log for debugging purposes. The first log opened
+ is the "common log" and can be accessed with the static
+ method common(). If you access common() and a common log
+ does not yet exist, one is created for you.
+ */
+class Log {
+private:
+
+ /**
+ Log messages go here.
+ */
+ FILE* logFile;
+
+ std::string filename;
+
+ static Log* commonLog;
+
+ int stripFromStackBottom;
+
+public:
+
+ /**
+ @param stripFromStackBottom Number of call stacks to strip from the
+ bottom of the stack when printing a trace. Useful for hiding
+ routines like "main" and "WinMain". If the specified file cannot
+ be opened for some reason, tries to open "c:/tmp/log.txt" or
+ "c:/temp/log.txt" instead.
+ */
+ Log(const std::string& filename = "log.txt",
+ int stripFromStackBottom = 0);
+
+ virtual ~Log();
+
+ /**
+ Returns the handle to the file log.
+ */
+ FILE* getFile() const;
+
+ /**
+ Marks the beginning of a logfile section.
+ */
+ void section(const std::string& s);
+
+ /**
+ Given arguments like printf, writes characters to the debug text overlay.
+ */
+ // We want G3D_CHECK_PRINTF_ARGS here, but that conflicts with the
+ // overload.
+ void __cdecl printf(const char* fmt, ...) G3D_CHECK_PRINTF_METHOD_ARGS;
+
+ void __cdecl vprintf(const char*, va_list argPtr) G3D_CHECK_VPRINTF_METHOD_ARGS;
+ /** Does not flush */
+ void __cdecl lazyvprintf(const char*, va_list argPtr) G3D_CHECK_VPRINTF_METHOD_ARGS;
+
+ static Log* common();
+
+ static std::string getCommonLogFilename();
+
+ void print(const std::string& s);
+
+
+ void println(const std::string& s);
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Map2D.h b/dep/include/g3dlite/G3D/Map2D.h
new file mode 100644
index 00000000000..9af9f7242c1
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Map2D.h
@@ -0,0 +1,667 @@
+/**
+ @file Map2D.h
+
+ More flexible support than provided by G3D::GImage.
+
+ @maintainer Morgan McGuire, morgan@cs.brown.edu
+ @created 2004-10-10
+ @edited 2009-03-24
+ */
+#ifndef G3D_Map2D_h
+#define G3D_Map2D_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Array.h"
+#include "G3D/vectorMath.h"
+#include "G3D/Vector2int16.h"
+#include "G3D/ReferenceCount.h"
+#include "G3D/AtomicInt32.h"
+#include "G3D/GThread.h"
+#include "G3D/Rect2D.h"
+#include "G3D/WrapMode.h"
+
+#include <string>
+
+namespace G3D {
+namespace _internal {
+
+/** The default compute type for a type is the type itself. */
+template<typename Storage> class _GetComputeType {
+public:
+ typedef Storage Type;
+};
+
+} // _internal
+} // G3D
+
+// This weird syntax is needed to support VC6, which doesn't
+// properly implement template overloading.
+#define DECLARE_COMPUTE_TYPE(StorageType, ComputeType) \
+namespace G3D { \
+ namespace _internal { \
+ template<> class _GetComputeType < StorageType > { \
+ public: \
+ typedef ComputeType Type; \
+ }; \
+ } \
+}
+
+DECLARE_COMPUTE_TYPE( float32, float64)
+DECLARE_COMPUTE_TYPE( float64, float64)
+
+DECLARE_COMPUTE_TYPE( int8, float32)
+DECLARE_COMPUTE_TYPE( int16, float32)
+DECLARE_COMPUTE_TYPE( int32, float64)
+DECLARE_COMPUTE_TYPE( int64, float64)
+
+DECLARE_COMPUTE_TYPE( uint8, float32)
+DECLARE_COMPUTE_TYPE( uint16, float32)
+DECLARE_COMPUTE_TYPE( uint32, float64)
+DECLARE_COMPUTE_TYPE( uint64, float64)
+
+DECLARE_COMPUTE_TYPE( Vector2, Vector2)
+DECLARE_COMPUTE_TYPE( Vector2int16, Vector2)
+
+DECLARE_COMPUTE_TYPE( Vector3, Vector3)
+DECLARE_COMPUTE_TYPE( Vector3int16, Vector3)
+
+DECLARE_COMPUTE_TYPE( Vector4, Vector4)
+
+DECLARE_COMPUTE_TYPE( Color3, Color3)
+DECLARE_COMPUTE_TYPE( Color3uint8, Color3)
+
+DECLARE_COMPUTE_TYPE( Color4, Color4)
+DECLARE_COMPUTE_TYPE( Color4uint8, Color4)
+#undef DECLARE_COMPUTE_TYPE
+
+namespace G3D {
+
+/**
+ Map of values across a discrete 2D plane. Can be thought of as a generic class for 2D images,
+ allowing flexibility as to pixel format and convenient methods.
+ In fact, the "pixels" can be any values
+ on a grid that can be sensibly interpolated--RGB colors, scalars, 4D vectors, and so on.
+
+ Other "image" classes in G3D:
+
+ G3D::GImage - Supports file formats, fast, Color3uint8 and Color4uint8 formats. No interpolation.
+
+ G3D::Texture::Ref - Represents image on the graphics card (not directly readable on the CPU). Supports 2D, 3D, and a variety of interpolation methods, loads file formats.
+
+ G3D::Image3 - A subclass of Map2D<Color3> that supports image loading and saving and conversion to Texture.
+
+ G3D::Image4 - A subclass of Map2D<Color4> that supports image loading and saving and conversion to Texture.
+
+ G3D::Image3uint8 - A subclass of Map2D<Color3uint8> that supports image loading and saving and conversion to Texture.
+
+ G3D::Image4uint8 - A subclass of Map2D<Color4uint8> that supports image loading and saving and conversion to Texture.
+
+ There are two type parameters-- the first (@ Storage) is the type
+ used to store the "pixel" values efficiently and
+ the second (@a Compute) is
+ the type operated on by computation. The Compute::Compute(Storage&) constructor
+ is used to convert between storage and computation types.
+ @a Storage is often an integer version of @a Compute, for example
+ <code>Map2D<double, uint8></code>. By default, the computation type is:
+
+ <pre>
+ Storage Computation
+
+ uint8 float32
+ uint16 float32
+ uint32 float64
+ uint64 float64
+
+ int8 float32
+ int16 float32
+ int32 float64
+ int64 float64
+
+ float32 float64
+ float64 float64
+
+ Vector2 Vector2
+ Vector2int16 Vector2
+
+ Vector3 Vector3
+ Vector3int16 Vector3
+
+ Vector4 Vector4
+
+ Color3 Color3
+ Color3uint8 Color3
+
+ Color4 Color4
+ Color4uint8 Color4
+ </pre>
+ Any other storage type defaults to itself as the computation type.
+
+ The computation type can be any that
+ supports lerp, +, -, *, /, and an empty constructor.
+
+ Assign value:
+
+ <code>im->set(x, y, 7);</code> or
+ <code>im->get(x, y) = 7;</code>
+
+ Read value:
+
+ <code>int c = im(x, y);</code>
+
+ Can also sample with nearest neighbor, bilinear, and bicubic
+ interpolation.
+
+ Sampling follows OpenGL conventions, where
+ pixel values represent grid points and (0.5, 0.5) is half-way
+ between two vertical and two horizontal grid points.
+ To draw an image of dimensions w x h with nearest neighbor
+ sampling, render pixels from [0, 0] to [w - 1, h - 1].
+
+ Under the WrapMode::CLAMP wrap mode, the value of bilinear interpolation
+ becomes constant outside [1, w - 2] horizontally. Nearest neighbor
+ interpolation is constant outside [0, w - 1] and bicubic outside
+ [3, w - 4]. The class does not offer quadratic interpolation because
+ the interpolation filter could not center over a pixel.
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ */
+template< typename Storage,
+typename Compute = typename G3D::_internal::_GetComputeType<Storage>::Type>
+class Map2D : public ReferenceCountedObject {
+
+//
+// It doesn't make sense to automatically convert from Compute back to Storage
+// because the rounding rule (and scaling) is application dependent.
+// Thus the interpolation methods all return type Compute.
+//
+
+public:
+
+ typedef Storage StorageType;
+ typedef Compute ComputeType;
+ typedef Map2D<Storage, Compute> Type;
+ typedef ReferenceCountedPointer<Map2D> Ref;
+
+protected:
+
+ Storage ZERO;
+
+ /** Width, in pixels. */
+ uint32 w;
+
+ /** Height, in pixels. */
+ uint32 h;
+
+ WrapMode _wrapMode;
+
+ /** 0 if no mutating method has been invoked
+ since the last call to setChanged(); */
+ AtomicInt32 m_changed;
+
+ Array<Storage> data;
+
+ /** Handles the exceptional cases from get */
+ const Storage& slowGet(int x, int y, WrapMode wrap) {
+ switch (wrap) {
+ case WrapMode::CLAMP:
+ return fastGet(iClamp(x, 0, w - 1), iClamp(y, 0, h - 1));
+
+ case WrapMode::TILE:
+ return fastGet(iWrap(x, w), iWrap(y, h));
+
+ case WrapMode::ZERO:
+ return ZERO;
+
+ case WrapMode::ERROR:
+ alwaysAssertM(((uint32)x < w) && ((uint32)y < h),
+ format("Index out of bounds: (%d, %d), w = %d, h = %d",
+ x, y, w, h));
+
+ // intentionally fall through
+ case WrapMode::IGNORE:
+ // intentionally fall through
+ default:
+ {
+ static Storage temp;
+ return temp;
+ }
+ }
+ }
+
+public:
+
+ /** Unsafe access to the underlying data structure with no wrapping support; requires that (x, y) is in bounds. */
+ inline const Storage& fastGet(int x, int y) const {
+ debugAssert(((uint32)x < w) && ((uint32)y < h));
+ return data[x + y * w];
+ }
+
+ /** Unsafe access to the underlying data structure with no wrapping support; requires that (x, y) is in bounds. */
+ inline void fastSet(int x, int y, const Storage& v) {
+ debugAssert(((uint32)x < w) && ((uint32)y < h));
+ data[x + y * w] = v;
+ }
+
+protected:
+
+ /** Given four control points and a value on the range [0, 1)
+ evaluates the Catmull-rom spline between the times of the
+ middle two control points */
+ Compute bicubic(const Compute* ctrl, double s) const {
+
+ // f = B * S * ctrl'
+
+ // B matrix: Catmull-Rom spline basis
+ static const double B[4][4] = {
+ { 0.0, -0.5, 1.0, -0.5},
+ { 1.0, 0.0, -2.5, 1.5},
+ { 0.0, 0.5, 2.0, -1.5},
+ { 0.0, 0.0, -0.5, 0.5}};
+
+ // S: Powers of the fraction
+ double S[4];
+ double s2 = s * s;
+ S[0] = 1.0;
+ S[1] = s;
+ S[2] = s2;
+ S[3] = s2 * s;
+
+ Compute sum(ZERO);
+
+ for (int c = 0; c < 4; ++c) {
+ double coeff = 0.0;
+ for (int power = 0; power < 4; ++power) {
+ coeff += B[c][power] * S[power];
+ }
+ sum += ctrl[c] * coeff;
+ }
+
+ return sum;
+ }
+
+
+ Map2D(int w, int h, WrapMode wrap) : w(0), h(0), _wrapMode(wrap), m_changed(1) {
+ ZERO = Storage(Compute(Storage()) * 0);
+ resize(w, h);
+ }
+
+public:
+
+ /**
+ Although Map2D is not threadsafe (except for the setChanged() method),
+ you can use this mutex to create your own threadsafe access to a Map2D.
+ Not used by the default implementation.
+ */
+ GMutex mutex;
+
+ static Ref create(int w = 0, int h = 0, WrapMode wrap = WrapMode::ERROR) {
+ return new Map2D(w, h, wrap);
+ }
+
+ /** Resizes without clearing, leaving garbage.
+ */
+ void resize(uint32 newW, uint32 newH) {
+ if ((newW != w) || (newH != h)) {
+ w = newW;
+ h = newH;
+ data.resize(w * h);
+ setChanged(true);
+ }
+ }
+
+ /**
+ Returns true if this map has been written to since the last call to setChanged(false).
+ This is useful if you are caching a texture map other value that must be recomputed
+ whenever this changes.
+ */
+ bool changed() {
+ return m_changed.value() != 0;
+ }
+
+ /** Set/unset the changed flag. */
+ void setChanged(bool c) {
+ m_changed = c ? 1 : 0;
+ }
+
+ /** Returns a pointer to the underlying row-major data. There is no padding at the end of the row.
+ Be careful--this will be reallocated during a resize. You should call setChanged(true) if you mutate the array.*/
+ Storage* getCArray() {
+ return data.getCArray();
+ }
+
+
+ const Storage* getCArray() const {
+ return data.getCArray();
+ }
+
+
+ /** Row-major array. You should call setChanged(true) if you mutate the array. */
+ Array<Storage>& getArray() {
+ return data;
+ }
+
+
+ const Array<Storage>& getArray() const {
+ return data;
+ }
+
+ /** is (x, y) strictly within the image bounds, or will it trigger some kind of wrap mode */
+ inline bool inBounds(int x, int y) const {
+ return (((uint32)x < w) && ((uint32)y < h));
+ }
+
+ /** is (x, y) strictly within the image bounds, or will it trigger some kind of wrap mode */
+ inline bool inBounds(const Vector2int16& v) const {
+ return inBounds(v.x, v.y);
+ }
+
+ /** Get the value at (x, y).
+
+ Note that the type of image->get(x, y) is
+ the storage type, not the computation
+ type. If the constructor promoting Storage to Compute rescales values
+ (as, for example Color3(Color3uint8&) does), this will not match the value
+ returned by Map2D::nearest.
+ */
+ inline const Storage& get(int x, int y, WrapMode wrap) const {
+ if (((uint32)x < w) && ((uint32)y < h)) {
+ return data[x + y * w];
+ } else {
+ // Remove the const to allow a slowGet on this object
+ // (we're returning a const reference so this is ok)
+ return const_cast<Type*>(this)->slowGet(x, y, wrap);
+ }
+# ifndef G3D_WIN32
+ // gcc gives a useless warning that the above code might reach the end of the function;
+ // we use this line to supress the warning.
+ return ZERO;
+# endif
+ }
+
+ inline const Storage& get(int x, int y) const {
+ return get(x, y, _wrapMode);
+ }
+
+ inline const Storage& get(const Vector2int16& p) const {
+ return get(p.x, p.y, _wrapMode);
+ }
+
+ inline const Storage& get(const Vector2int16& p, WrapMode wrap) const {
+ return get(p.x, p.y, wrap);
+ }
+
+ inline Storage& get(int x, int y, WrapMode wrap) {
+ return const_cast<Storage&>(const_cast<const Type*>(this)->get(x, y, wrap));
+# ifndef G3D_WIN32
+ // gcc gives a useless warning that the above code might reach the end of the function;
+ // we use this line to supress the warning.
+ return ZERO;
+# endif
+ }
+
+ inline Storage& get(int x, int y) {
+ return const_cast<Storage&>(const_cast<const Type*>(this)->get(x, y));
+# ifndef G3D_WIN32
+ // gcc gives a useless warning that the above code might reach the end of the function;
+ // we use this line to supress the warning.
+ return ZERO;
+# endif
+ }
+
+ inline Storage& get(const Vector2int16& p) {
+ return get(p.x, p.y);
+ }
+
+ /** Sets the changed flag to true */
+ inline void set(const Vector2int16& p, const Storage& v) {
+ set(p.x, p.y, v);
+ }
+
+ /** Sets the changed flag to true */
+ void set(int x, int y, const Storage& v, WrapMode wrap) {
+ setChanged(true);
+ if (((uint32)x < w) && ((uint32)y < h)) {
+ // In bounds, wrapping isn't an issue.
+ data[x + y * w] = v;
+ } else {
+ const_cast<Storage&>(slowGet(x, y, wrap)) = v;
+ }
+ }
+
+ void set(int x, int y, const Storage& v) {
+ set(x, y, v, _wrapMode);
+ }
+
+
+ void setAll(const Storage& v) {
+ for(int i = 0; i < data.size(); ++i) {
+ data[i] = v;
+ }
+ setChanged(true);
+ }
+
+ /** flips if @a flip is true*/
+ void maybeFlipVertical(bool flip) {
+ if (flip) {
+ flipVertical();
+ }
+ }
+
+ virtual void flipVertical() {
+ int halfHeight = h/2;
+ Storage* d = data.getCArray();
+ for (int y = 0; y < halfHeight; ++y) {
+ int o1 = y * w;
+ int o2 = (h - y - 1) * w;
+ for (int x = 0; x < (int)w; ++x) {
+ int i1 = o1 + x;
+ int i2 = o2 + x;
+ Storage temp = d[i1];
+ d[i1] = d[i2];
+ d[i2] = temp;
+ }
+ }
+ setChanged(true);
+ }
+
+ virtual void flipHorizontal() {
+ int halfWidth = w / 2;
+ Storage* d = data.getCArray();
+ for (int x = 0; x < halfWidth; ++x) {
+ for (int y = 0; y < (int)h; ++y) {
+ int i1 = y * w + x;
+ int i2 = y * w + (w - x - 1);
+ Storage temp = d[i1];
+ d[i1] = d[i2];
+ d[i2] = temp;
+ }
+ }
+ setChanged(true);
+ }
+
+ /**
+ Crops this map so that it only contains pixels between (x, y) and (x + w - 1, y + h - 1) inclusive.
+ */
+ virtual void crop(int newX, int newY, int newW, int newH) {
+ alwaysAssertM(newX + newW <= (int)w, "Cannot grow when cropping");
+ alwaysAssertM(newY + newH <= (int)h, "Cannot grow when cropping");
+ alwaysAssertM(newX >= 0 && newY >= 0, "Origin out of bounds.");
+
+ // Always safe to copy towards the upper left, provided
+ // that we're iterating towards the lower right. This lets us avoid
+ // reallocating the underlying array.
+ for (int y = 0; y < newH; ++y) {
+ for (int x = 0; x < newW; ++x) {
+ data[x + y * newW] = data[(x + newX) + (y + newY) * w];
+ }
+ }
+
+ resize(newW, newH);
+ }
+
+ /** iRounds to the nearest x0 and y0. */
+ virtual void crop(const Rect2D& rect) {
+ crop(iRound(rect.x0()), iRound(rect.y0()), iRound(rect.x1()) - iRound(rect.x0()), iRound(rect.y1()) - iRound(rect.y0()));
+ }
+
+ /** Returns the nearest neighbor. Pixel values are considered
+ to be at the upper left corner, so <code>image->nearest(x, y) == image(x, y)</code>
+ */
+ inline Compute nearest(float x, float y, WrapMode wrap) const {
+ int ix = iRound(x);
+ int iy = iRound(y);
+ return Compute(get(ix, iy, wrap));
+ }
+
+ inline Compute nearest(float x, float y) const {
+ return nearest(x, y, _wrapMode);
+ }
+
+ inline Compute nearest(const Vector2& p) const {
+ return nearest(p.x, p.y);
+ }
+
+ /** Returns the average value of all elements of the map */
+ Compute average() const {
+ if ((w == 0) || (h == 0)) {
+ return ZERO;
+ }
+
+ // To avoid overflows, compute the average of row averages
+
+ Compute rowSum = ZERO;
+ for (unsigned int y = 0; y < h; ++y) {
+ Compute sum = ZERO;
+ int offset = y * w;
+ for (unsigned int x = 0; x < w; ++x) {
+ sum += Compute(data[offset + x]);
+ }
+ rowSum += sum * (1.0f / w);
+ }
+
+ return rowSum * (1.0f / h);
+ }
+
+ /**
+ Needs to access elements from (floor(x), floor(y))
+ to (floor(x) + 1, floor(y) + 1) and will use
+ the wrap mode appropriately (possibly generating
+ out of bounds errors).
+
+ Guaranteed to match nearest(x, y) at integers. */
+ Compute bilinear(float x, float y, WrapMode wrap) const {
+ const int i = iFloor(x);
+ const int j = iFloor(y);
+
+ const float fX = x - i;
+ const float fY = y - j;
+
+ // Horizontal interpolation, first row
+ const Compute& t0 = get(i, j, wrap);
+ const Compute& t1 = get(i + 1, j, wrap);
+
+ // Horizontal interpolation, second row
+ const Compute& t2 = get(i, j + 1, wrap);
+ const Compute& t3 = get(i + 1, j + 1, wrap);
+
+ const Compute& A = lerp(t0, t1, fX);
+ const Compute& B = lerp(t2, t3, fX);
+
+ // Vertical interpolation
+ return lerp(A, B, fY);
+ }
+
+ Compute bilinear(float x, float y) const {
+ return bilinear(x, y, _wrapMode);
+ }
+
+ inline Compute bilinear(const Vector2& p) const {
+ return bilinear(p.x, p.y, _wrapMode);
+ }
+
+ inline Compute bilinear(const Vector2& p, WrapMode wrap) const {
+ return bilinear(p.x, p.y, wrap);
+ }
+
+ /**
+ Uses Catmull-Rom splines to interpolate between grid
+ values. Guaranteed to match nearest(x, y) at integers.
+ */
+ Compute bicubic(float x, float y, WrapMode wrap) const {
+ int i = iFloor(x);
+ int j = iFloor(y);
+ float fX = x - i;
+ float fY = y - j;
+
+ Compute vsample[4];
+ for (int v = 0; v < 4; ++v) {
+
+ // Horizontal interpolation
+ Compute hsample[4];
+ for (int u = 0; u < 4; ++u) {
+ hsample[u] = Compute(get(i + u - 1, j + v - 1, wrap));
+ }
+
+ vsample[v] = bicubic(hsample, fX);
+ }
+
+ // Vertical interpolation
+ return bicubic(vsample, fY);
+ }
+
+ Compute bicubic(float x, float y) const {
+ return bicubic(x, y, _wrapMode);
+ }
+
+ inline Compute bicubic(const Vector2& p, WrapMode wrap) const {
+ return bicubic(p.x, p.y, wrap);
+ }
+
+ inline Compute bicubic(const Vector2& p) const {
+ return bicubic(p.x, p.y, _wrapMode);
+ }
+
+ /** Pixel width */
+ inline int32 width() const {
+ return (int32)w;
+ }
+
+
+ /** Pixel height */
+ inline int32 height() const {
+ return (int32)h;
+ }
+
+
+ /** Dimensions in pixels */
+ Vector2int16 size() const {
+ return Vector2int16(w, h);
+ }
+
+ /** Rectangle from (0, 0) to (w, h) */
+ Rect2D rect2DBounds() const {
+ return Rect2D::xywh(0, 0, w, h);
+ }
+
+ /** Number of bytes occupied by the image data and this structure */
+ size_t sizeInMemory() const {
+ return data.size() * sizeof(Storage) + sizeof(*this);
+ }
+
+
+ WrapMode wrapMode() const {
+ return _wrapMode;
+ }
+
+
+ void setWrapMode(WrapMode m) {
+ _wrapMode = m;
+ }
+};
+
+
+
+}
+
+#endif // G3D_IMAGE_H
diff --git a/dep/include/g3dlite/G3D/Matrix.h b/dep/include/g3dlite/G3D/Matrix.h
new file mode 100644
index 00000000000..3c5394d9a76
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Matrix.h
@@ -0,0 +1,634 @@
+/**
+ @file Matrix.h
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2005-10-23
+ @edited 2007-07-18
+ */
+
+#ifndef G3D_MATRIX_H
+#define G3D_MATRIX_H
+
+#include "G3D/g3dmath.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector4.h"
+#include "G3D/Matrix3.h"
+#include "G3D/Matrix4.h"
+#include "G3D/ReferenceCount.h"
+
+namespace G3D {
+
+/**
+ N x M matrix.
+
+ The actual data is tracked internally by a reference counted pointer;
+ it is efficient to pass and assign Matrix objects because no data is actually copied.
+ This avoids the headache of pointers and allows natural math notation:
+
+ <PRE>
+ Matrix A, B, C;
+ // ...
+
+ C = A * f(B);
+ C = C.inverse();
+
+ A = Matrix::identity(4);
+ C = A;
+ C.set(0, 0, 2.0); // Triggers a copy of the data so that A remains unchanged.
+
+ // etc.
+
+ </PRE>
+
+ The Matrix::debugNumCopyOps and Matrix::debugNumAllocOps counters
+ increment every time an operation forces the copy and allocation of matrices. You
+ can use these to detect slow operations when efficiency is a major concern.
+
+ Some methods accept an output argument instead of returning a value. For example,
+ <CODE>A = B.transpose()</CODE> can also be invoked as <CODE>B.transpose(A)</CODE>.
+ The latter may be more efficient, since Matrix may be able to re-use the storage of
+ A (if it has approximatly the right size and isn't currently shared with another matrix).
+
+ @sa G3D::Matrix3, G3D::Matrix4, G3D::Vector2, G3D::Vector3, G3D::Vector4, G3D::CoordinateFrame
+
+ @beta
+ */
+class Matrix {
+public:
+ /**
+ Internal precision. Currently float, but this may become a templated class in the future
+ to allow operations like Matrix<double> and Matrix<ComplexFloat>.
+
+ Not necessarily a plain-old-data type (e.g., could ComplexFloat), but must be something
+ with no constructor, that can be safely memcpyd, and that has a bit pattern of all zeros
+ when zero.*/
+ typedef float T;
+
+ /** Incremented every time the elements of a matrix are copied. Useful for profiling your
+ own code that uses Matrix to determine when it is slow due to copying.*/
+ static int debugNumCopyOps;
+
+ /** Incremented every time a new matrix object is allocated. Useful for profiling your
+ own code that uses Matrix to determine when it is slow due to allocation.*/
+ static int debugNumAllocOps;
+
+private:
+public:
+
+ /** Used internally by Matrix.
+
+ Does not throw exceptions-- assumes the caller has taken care of
+ argument checking. */
+ class Impl : public ReferenceCountedObject {
+ public:
+
+ static void* operator new(size_t size) {
+ return System::malloc(size);
+ }
+
+ static void operator delete(void* p) {
+ System::free(p);
+ }
+
+ ~Impl();
+
+ private:
+ friend class Matrix;
+
+ /** elt[r][c] = the element. Pointers into data.*/
+ T** elt;
+
+ /** Row major data for the entire matrix. */
+ T* data;
+
+ /** The number of rows */
+ int R;
+
+ /** The number of columns */
+ int C;
+
+ int dataSize;
+
+ /** If R*C is much larger or smaller than the current, deletes all previous data
+ and resets to random data. Otherwise re-uses existing memory and just resets
+ R, C, and the row pointers. */
+ void setSize(int newRows, int newCols);
+
+ inline Impl() : elt(NULL), data(NULL), R(0), C(0), dataSize(0) {}
+
+ Impl(const Matrix3& M);
+
+ Impl(const Matrix4& M);
+
+ inline Impl(int r, int c) : elt(NULL), data(NULL), R(0), C(0), dataSize(0) {
+ setSize(r, c);
+ }
+
+ Impl& operator=(const Impl& m);
+
+ inline Impl(const Impl& B) : elt(NULL), data(NULL), R(0), C(0), dataSize(0) {
+ // Use the assignment operator
+ *this = B;
+ }
+
+ void setZero();
+
+ inline void set(int r, int c, T v) {
+ debugAssert(r < R);
+ debugAssert(c < C);
+ elt[r][c] = v;
+ }
+
+ inline const T& get(int r, int c) const {
+ debugAssert(r < R);
+ debugAssert(c < C);
+ return elt[r][c];
+ }
+
+ /** Multiplies this by B and puts the result in out. */
+ void mul(const Impl& B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void add(const Impl& B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void add(T B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void sub(const Impl& B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void sub(T B, Impl& out) const;
+
+ /** B - this */
+ void lsub(T B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void arrayMul(const Impl& B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void mul(T B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void arrayDiv(const Impl& B, Impl& out) const;
+
+ /** Ok if out == this or out == B */
+ void div(T B, Impl& out) const;
+
+ void negate(Impl& out) const;
+
+ /** Slow way of computing an inverse; for reference */
+ void inverseViaAdjoint(Impl& out) const;
+
+ /** Use Gaussian elimination with pivots to solve for the inverse destructively in place. */
+ void inverseInPlaceGaussJordan();
+
+ void adjoint(Impl& out) const;
+
+ /** Matrix of all cofactors */
+ void cofactor(Impl& out) const;
+
+ /**
+ Cofactor [r][c] is defined as C[r][c] = -1 ^(r+c) * det(A[r][c]),
+ where A[r][c] is the (R-1)x(C-1) matrix formed by removing row r and
+ column c from the original matrix.
+ */
+ T cofactor(int r, int c) const;
+
+ /** Ok if out == this or out == B */
+ void transpose(Impl& out) const;
+
+ T determinant() const;
+
+ /** Determinant computed without the given row and column */
+ T determinant(int r, int c) const;
+
+ void arrayLog(Impl& out) const;
+
+ void arrayExp(Impl& out) const;
+
+ void arraySqrt(Impl& out) const;
+
+ void arrayCos(Impl& out) const;
+
+ void arraySin(Impl& out) const;
+
+ void swapRows(int r0, int r1);
+
+ void swapAndNegateCols(int c0, int c1);
+
+ void mulRow(int r, const T& v);
+
+ void abs(Impl& out) const;
+
+ /** Makes a (R-1)x(C-1) copy of this matrix */
+ void withoutRowAndCol(int excludeRow, int excludeCol, Impl& out) const;
+
+ bool anyNonZero() const;
+
+ bool allNonZero() const;
+
+ void setRow(int r, const T* vals);
+
+ void setCol(int c, const T* vals);
+ };
+private:
+
+ typedef ReferenceCountedPointer<Impl> ImplRef;
+
+ ImplRef impl;
+
+ inline Matrix(ImplRef i) : impl(i) {}
+ inline Matrix(Impl* i) : impl(ImplRef(i)) {}
+
+ /** Used by SVD */
+ class SortRank {
+ public:
+ T value;
+ int col;
+
+ inline bool operator>(const SortRank& x) const {
+ return x.value > value;
+ }
+
+ inline bool operator<(const SortRank& x) const {
+ return x.value < value;
+ }
+
+ inline bool operator>=(const SortRank& x) const {
+ return x.value >= value;
+ }
+
+ inline bool operator<=(const SortRank& x) const {
+ return x.value <= value;
+ }
+
+ inline bool operator==(const SortRank& x) const {
+ return x.value == value;
+ }
+
+ inline bool operator!=(const SortRank& x) const {
+ return x.value != value;
+ }
+ };
+
+ Matrix vectorPseudoInverse() const;
+ Matrix partitionPseudoInverse() const;
+ Matrix colPartPseudoInverse() const;
+ Matrix rowPartPseudoInverse() const;
+
+ Matrix col2PseudoInverse(const Matrix& B) const;
+ Matrix col3PseudoInverse(const Matrix& B) const;
+ Matrix col4PseudoInverse(const Matrix& B) const;
+ Matrix row2PseudoInverse(const Matrix& B) const;
+ Matrix row3PseudoInverse(const Matrix& B) const;
+ Matrix row4PseudoInverse(const Matrix& B) const;
+
+public:
+
+ Matrix() : impl(new Impl(0, 0)) {}
+
+ Matrix(const Matrix3& M) : impl(new Impl(M)) {}
+
+ Matrix(const Matrix4& M) : impl(new Impl(M)) {}
+
+ template<class S>
+ static Matrix fromDiagonal(const Array<S>& d) {
+ Matrix D = zero(d.length(), d.length());
+ for (int i = 0; i < d.length(); ++i) {
+ D.set(i, i, d[i]);
+ }
+ return D;
+ }
+
+ static Matrix fromDiagonal(const Matrix& d);
+
+ /** Returns a new matrix that is all zero. */
+ Matrix(int R, int C) : impl(new Impl(R, C)) {
+ impl->setZero();
+ }
+
+ /** Returns a new matrix that is all zero. */
+ static Matrix zero(int R, int C);
+
+ /** Returns a new matrix that is all one. */
+ static Matrix one(int R, int C);
+
+ /** Returns a new identity matrix */
+ static Matrix identity(int N);
+
+ /** Uniformly distributed values between zero and one. */
+ static Matrix random(int R, int C);
+
+ /** The number of rows */
+ inline int rows() const {
+ return impl->R;
+ }
+
+ /** Number of columns */
+ inline int cols() const {
+ return impl->C;
+ }
+
+ /** Generally more efficient than A * B */
+ Matrix& operator*=(const T& B);
+
+ /** Generally more efficient than A / B */
+ Matrix& operator/=(const T& B);
+
+ /** Generally more efficient than A + B */
+ Matrix& operator+=(const T& B);
+
+ /** Generally more efficient than A - B */
+ Matrix& operator-=(const T& B);
+
+ /** No performance advantage over A * B because
+ matrix multiplication requires intermediate
+ storage. */
+ Matrix& operator*=(const Matrix& B);
+
+ /** Generally more efficient than A + B */
+ Matrix& operator+=(const Matrix& B);
+
+ /** Generally more efficient than A - B */
+ Matrix& operator-=(const Matrix& B);
+
+ /** Returns a new matrix that is a subset of this one,
+ from r1:r2 to c1:c2, inclusive.*/
+ Matrix subMatrix(int r1, int r2, int c1, int c2) const;
+
+ /** Matrix multiplication. To perform element-by-element multiplication,
+ see arrayMul. */
+ inline Matrix operator*(const Matrix& B) const {
+ Matrix C(impl->R, B.impl->C);
+ impl->mul(*B.impl, *C.impl);
+ return C;
+ }
+
+ /** See also A *= B, which is more efficient in many cases */
+ inline Matrix operator*(const T& B) const {
+ Matrix C(impl->R, impl->C);
+ impl->mul(B, *C.impl);
+ return C;
+ }
+
+ /** See also A += B, which is more efficient in many cases */
+ inline Matrix operator+(const Matrix& B) const {
+ Matrix C(impl->R, impl->C);
+ impl->add(*B.impl, *C.impl);
+ return C;
+ }
+
+ /** See also A -= B, which is more efficient in many cases */
+ inline Matrix operator-(const Matrix& B) const {
+ Matrix C(impl->R, impl->C);
+ impl->sub(*B.impl, *C.impl);
+ return C;
+ }
+
+ /** See also A += B, which is more efficient in many cases */
+ inline Matrix operator+(const T& v) const {
+ Matrix C(impl->R, impl->C);
+ impl->add(v, *C.impl);
+ return C;
+ }
+
+ /** See also A -= B, which is more efficient in many cases */
+ inline Matrix operator-(const T& v) const {
+ Matrix C(impl->R, impl->C);
+ impl->sub(v, *C.impl);
+ return C;
+ }
+
+
+ Matrix operator>(const T& scalar) const;
+
+ Matrix operator<(const T& scalar) const;
+
+ Matrix operator>=(const T& scalar) const;
+
+ Matrix operator<=(const T& scalar) const;
+
+ Matrix operator==(const T& scalar) const;
+
+ Matrix operator!=(const T& scalar) const;
+
+ /** scalar B - this */
+ inline Matrix lsub(const T& B) const {
+ Matrix C(impl->R, impl->C);
+ impl->lsub(B, *C.impl);
+ return C;
+ }
+
+ inline Matrix arrayMul(const Matrix& B) const {
+ Matrix C(impl->R, impl->C);
+ impl->arrayMul(*B.impl, *C.impl);
+ return C;
+ }
+
+ Matrix3 toMatrix3() const;
+
+ Matrix4 toMatrix4() const;
+
+ Vector2 toVector2() const;
+
+ Vector3 toVector3() const;
+
+ Vector4 toVector4() const;
+
+ /** Mutates this */
+ void arrayMulInPlace(const Matrix& B);
+
+ /** Mutates this */
+ void arrayDivInPlace(const Matrix& B);
+
+ // Declares an array unary method and its explicit-argument counterpart
+# define DECLARE_METHODS_1(method)\
+ inline Matrix method() const {\
+ Matrix C(impl->R, impl->C);\
+ impl->method(*C.impl);\
+ return C;\
+ }\
+ void method(Matrix& out) const;
+
+
+ DECLARE_METHODS_1(abs)
+ DECLARE_METHODS_1(arrayLog)
+ DECLARE_METHODS_1(arrayExp)
+ DECLARE_METHODS_1(arraySqrt)
+ DECLARE_METHODS_1(arrayCos)
+ DECLARE_METHODS_1(arraySin)
+ DECLARE_METHODS_1(negate)
+
+# undef DECLARE_METHODS_1
+
+ inline Matrix operator-() const {
+ return negate();
+ }
+
+ /**
+ A<SUP>-1</SUP> computed using the Gauss-Jordan algorithm,
+ for square matrices.
+ Run time is <I>O(R<sup>3</sup>)</I>, where <I>R</i> is the
+ number of rows.
+ */
+ inline Matrix inverse() const {
+ Impl* A = new Impl(*impl);
+ A->inverseInPlaceGaussJordan();
+ return Matrix(A);
+ }
+
+ inline T determinant() const {
+ return impl->determinant();
+ }
+
+ /**
+ A<SUP>T</SUP>
+ */
+ inline Matrix transpose() const {
+ Impl* A = new Impl(cols(), rows());
+ impl->transpose(*A);
+ return Matrix(A);
+ }
+
+ /** Transpose in place; more efficient than transpose */
+ void transpose(Matrix& out) const;
+
+ inline Matrix adjoint() const {
+ Impl* A = new Impl(cols(), rows());
+ impl->adjoint(*A);
+ return Matrix(A);
+ }
+
+ /**
+ (A<SUP>T</SUP>A)<SUP>-1</SUP>A<SUP>T</SUP>) computed
+ using SVD.
+
+ @param tolerance Use -1 for automatic tolerance.
+ */
+ Matrix pseudoInverse(float tolerance = -1) const;
+
+ /** Called from pseudoInverse when the matrix has size > 4 along some dimension.*/
+ Matrix svdPseudoInverse(float tolerance = -1) const;
+
+ /**
+ (A<SUP>T</SUP>A)<SUP>-1</SUP>A<SUP>T</SUP>) computed
+ using Gauss-Jordan elimination.
+ */
+ inline Matrix gaussJordanPseudoInverse() const {
+ Matrix trans = transpose();
+ return (trans * (*this)).inverse() * trans;
+ }
+
+ /** Singular value decomposition. Factors into three matrices
+ such that @a this = @a U * fromDiagonal(@a d) * @a V.transpose().
+
+ The matrix must have at least as many rows as columns.
+
+ Run time is <I>O(C<sup>2</sup>*R)</I>.
+
+ @param sort If true (default), the singular values
+ are arranged so that D is sorted from largest to smallest.
+ */
+ void svd(Matrix& U, Array<T>& d, Matrix& V, bool sort = true) const;
+
+ void set(int r, int c, T v);
+
+ void setCol(int c, const Matrix& vec);
+
+ void setRow(int r, const Matrix& vec);
+
+ Matrix col(int c) const;
+
+ Matrix row(int r) const;
+
+ T get(int r, int c) const;
+
+ Vector2int16 size() const {
+ return Vector2int16(rows(), cols());
+ }
+
+ int numElements() const {
+ return rows() * cols();
+ }
+
+ void swapRows(int r0, int r1);
+
+ /** Swaps columns c0 and c1 and negates both */
+ void swapAndNegateCols(int c0, int c1);
+
+ void mulRow(int r, const T& v);
+
+ /** Returns true if any element is non-zero */
+ bool anyNonZero() const;
+
+ /** Returns true if all elements are non-zero */
+ bool allNonZero() const;
+
+ inline bool allZero() const {
+ return !anyNonZero();
+ }
+
+ inline bool anyZero() const {
+ return !allNonZero();
+ }
+
+ /** Serializes in Matlab source format */
+ void serialize(TextOutput& t) const;
+
+ std::string toString(const std::string& name) const;
+
+ std::string toString() const {
+ static const std::string name = "";
+ return toString(name);
+ }
+
+ /** 2-norm squared: sum(squares). (i.e., dot product with itself) */
+ double normSquared() const;
+
+ /** 2-norm (sqrt(sum(squares)) */
+ double norm() const;
+
+ /**
+ Low-level SVD functionality. Useful for applications that do not want
+ to construct a Matrix but need to perform the SVD operation.
+
+ this = U * D * V'
+
+ Assumes that rows >= cols
+
+ @return NULL on success, a string describing the error on failure.
+ @param U rows x cols matrix to be decomposed, gets overwritten with U, a rows x cols matrix with orthogonal columns.
+ @param D vector of singular values of a (diagonal of the D matrix). Length cols.
+ @param V returns the right orthonormal transformation matrix, size cols x cols
+
+ @cite Based on Dianne Cook's implementation, which is adapted from
+ svdecomp.c in XLISP-STAT 2.1, which is code from Numerical Recipes
+ adapted by Luke Tierney and David Betz. The Numerical Recipes code
+ is adapted from Forsythe et al, who based their code on Golub and
+ Reinsch's original implementation.
+ */
+ static const char* svdCore(float** U, int rows, int cols, float* D, float** V);
+
+};
+
+}
+
+inline G3D::Matrix operator-(const G3D::Matrix::T& v, const G3D::Matrix& M) {
+ return M.lsub(v);
+}
+
+inline G3D::Matrix operator*(const G3D::Matrix::T& v, const G3D::Matrix& M) {
+ return M * v;
+}
+
+inline G3D::Matrix operator+(const G3D::Matrix::T& v, const G3D::Matrix& M) {
+ return M + v;
+}
+
+inline G3D::Matrix abs(const G3D::Matrix& M) {
+ return M.abs();
+}
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/Matrix2.h b/dep/include/g3dlite/G3D/Matrix2.h
new file mode 100644
index 00000000000..eaf4aefa220
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Matrix2.h
@@ -0,0 +1,69 @@
+#ifndef G3D_MATRIX2_H
+#define G3D_MATRIX2_H
+
+#include "G3D/platform.h"
+#include "G3D/Vector2.h"
+
+namespace G3D {
+
+/** @beta */
+class Matrix2 {
+private:
+
+ float data[2][2];
+
+public:
+
+ inline Matrix2() {
+ data[0][0] = 1.0f; data[0][1] = 0.0f;
+ data[1][0] = 0.0f; data[1][1] = 1.0f;
+ }
+
+ inline Matrix2(float v00, float v01, float v10, float v11) {
+ data[0][0] = v00; data[0][1] = v01;
+ data[1][0] = v10; data[1][1] = v11;
+ }
+
+ inline Vector2 operator*(const Vector2& v) const {
+ return Vector2(data[0][0] * v[0] + data[0][1] * v[1],
+ data[1][0] * v[0] + data[1][1] * v[1]);
+ }
+
+ inline Matrix2 inverse() const {
+ return Matrix2(data[0][0], data[1][0],
+ data[0][1], data[1][1]) * (1.0f / determinant());
+ }
+
+ inline Matrix2 transpose() const {
+ return Matrix2(data[0][0], data[1][0],
+ data[0][1], data[1][1]);
+ }
+
+ inline float determinant() const {
+ return data[0][0] * data[1][1] - data[0][1] * data[1][0];
+ }
+
+ inline Matrix2 operator*(float f) const {
+ return Matrix2(data[0][0] * f, data[0][1] * f,
+ data[1][0] * f, data[1][1] * f);
+ }
+
+ inline Matrix2 operator/(float f) const {
+ return Matrix2(data[0][0] / f, data[0][1] / f,
+ data[1][0] / f, data[1][1] / f);
+ }
+
+ inline float* operator[](int i) {
+ debugAssert(i >= 0 && i <= 2);
+ return data[i];
+ }
+
+ inline const float* operator[](int i) const {
+ debugAssert(i >= 0 && i <= 1);
+ return data[i];
+ }
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Matrix3.h b/dep/include/g3dlite/G3D/Matrix3.h
index 99e049654ee..06ec7e67474 100644
--- a/dep/include/g3dlite/G3D/Matrix3.h
+++ b/dep/include/g3dlite/G3D/Matrix3.h
@@ -1,26 +1,36 @@
/**
@file Matrix3.h
-
+
3x3 matrix class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
-
+
@created 2001-06-02
@edited 2006-04-05
*/
-#ifndef G3D_MATRIX3_H
-#define G3D_MATRIX3_H
+#ifndef G3D_Matrix3_h
+#define G3D_Matrix3_h
#include "G3D/platform.h"
-#include "G3D/System.h"
#include "G3D/Vector3.h"
#include "G3D/Vector4.h"
+#include "G3D/debugAssert.h"
+
+#include <cstring>
namespace G3D {
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
+class Any;
+
/**
3x3 matrix. Do not subclass.
*/
@@ -37,23 +47,34 @@ private:
public:
- /** Initial values are undefined for performance. See also
+ Matrix3(const Any& any);
+
+ operator Any() const;
+
+ /** Initial values are undefined for performance. See also
Matrix3::zero(), Matrix3::identity(), Matrix3::fromAxisAngle, etc.*/
inline Matrix3() {}
+ Matrix3 (class BinaryInput& b);
Matrix3 (const float aafEntry[3][3]);
Matrix3 (const Matrix3& rkMatrix);
Matrix3 (float fEntry00, float fEntry01, float fEntry02,
float fEntry10, float fEntry11, float fEntry12,
float fEntry20, float fEntry21, float fEntry22);
- bool fuzzyEq(const Matrix3& b) const;
+ bool fuzzyEq(const Matrix3& b) const;
/** Constructs a matrix from a quaternion.
@cite Graphics Gems II, p. 351--354
- @cite Implementation from Watt and Watt, pg 362*/
+ @cite Implementation from Watt and Watt, pg 362*/
Matrix3(const class Quat& q);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ /** Returns true if column(0).cross(column(1)).dot(column(2)) > 0. */
+ bool isRightHanded() const;
+
/**
Sets all elements.
*/
@@ -83,15 +104,16 @@ public:
inline operator const float* () const{
return (const float*)&elt[0][0];
}
+
+ Vector3 column(int c) const;
+ const Vector3& row(int r) const;
- Vector3 getColumn (int iCol) const;
- Vector3 getRow (int iRow) const;
void setColumn(int iCol, const Vector3 &vector);
void setRow(int iRow, const Vector3 &vector);
// assignment and comparison
inline Matrix3& operator= (const Matrix3& rkMatrix) {
- System::memcpy(elt, rkMatrix.elt, 9 * sizeof(float));
+ memcpy(elt, rkMatrix.elt, 9 * sizeof(float));
return *this;
}
@@ -125,6 +147,7 @@ public:
return kProd;
}
+
/**
* vector * matrix [1x3 * 3x3 = 1x3]
*/
@@ -141,12 +164,16 @@ public:
friend Matrix3 operator* (float fScalar, const Matrix3& rkMatrix);
friend Matrix3 operator* (int fScalar, const Matrix3& rkMatrix);
+ Matrix3& operator*= (float k);
+ Matrix3& operator/= (float k);
+
+
private:
/** Multiplication where out != A and out != B */
static void _mul(const Matrix3& A, const Matrix3& B, Matrix3& out);
public:
- /** Optimized implementation of out = A * B. It is safe (but slow) to call
+ /** Optimized implementation of out = A * B. It is safe (but slow) to call
with A, B, and out possibly pointer equal to one another.*/
// This is a static method so that it is not ambiguous whether "this"
// is an input or output argument.
@@ -164,10 +191,10 @@ private:
static void _transpose(const Matrix3& A, Matrix3& out);
public:
- /** Optimized implementation of out = A.transpose(). It is safe (but slow) to call
+ /** Optimized implementation of out = A.transpose(). It is safe (but slow) to call
with A and out possibly pointer equal to one another.
-
- Note that <CODE>A.transpose() * v</CODE> can be computed
+
+ Note that <CODE>A.transpose() * v</CODE> can be computed
more efficiently as <CODE>v * A</CODE>.
*/
inline static void transpose(const Matrix3& A, Matrix3& out) {
@@ -200,11 +227,46 @@ public:
void qDUDecomposition (Matrix3& rkQ, Vector3& rkD,
Vector3& rkU) const;
+ /**
+ Polar decomposition of a matrix. Based on pseudocode from Nicholas J
+ Higham, "Computing the Polar Decomposition -- with Applications Siam
+ Journal of Science and Statistical Computing, Vol 7, No. 4, October
+ 1986.
+
+ Decomposes A into R*S, where R is orthogonal and S is symmetric.
+
+ Ken Shoemake's "Matrix animation and polar decomposition"
+ in Proceedings of the conference on Graphics interface '92
+ seems to be better known in the world of graphics, but Higham's version
+ uses a scaling constant that can lead to faster convergence than
+ Shoemake's when the initial matrix is far from orthogonal.
+ */
+ void polarDecomposition(Matrix3 &R, Matrix3 &S) const;
+
+ /**
+ * Matrix norms.
+ */
float spectralNorm () const;
+ float squaredFrobeniusNorm() const;
+
+ float frobeniusNorm() const;
+
+ float l1Norm() const;
+
+ float lInfNorm() const;
+
+ float diffOneNorm(const Matrix3 &y) const;
+
/** matrix must be orthonormal */
void toAxisAngle(Vector3& rkAxis, float& rfRadians) const;
+ static Matrix3 fromDiagonal(const Vector3& d) {
+ return Matrix3(d.x, 0, 0,
+ 0, d.y, 0,
+ 0, 0, d.z);
+ }
+
static Matrix3 fromAxisAngle(const Vector3& rkAxis, float fRadians);
/**
@@ -239,36 +301,31 @@ public:
Matrix3& rkProduct);
std::string toString() const;
- static const float EPSILON;
+ static const float EPSILON;
// Special values.
- // The unguaranteed order of initialization of static variables across
+ // The unguaranteed order of initialization of static variables across
// translation units can be a source of annoying bugs, so now the static
// special values (like Vector3::ZERO, Color3::WHITE, ...) are wrapped
- // inside static functions that return references to them.
- // These functions are intentionally not inlined, because:
- // "You might be tempted to write [...] them as inline functions
- // inside their respective header files, but this is something you
- // must definitely not do. An inline function can be duplicated
- // in every file in which it appears – and this duplication
- // includes the static object definition. Because inline functions
- // automatically default to internal linkage, this would result in
- // having multiple static objects across the various translation
- // units, which would certainly cause problems. So you must
- // ensure that there is only one definition of each wrapping
+ // inside static functions that return references to them.
+ // These functions are intentionally not inlined, because:
+ // "You might be tempted to write [...] them as inline functions
+ // inside their respective header files, but this is something you
+ // must definitely not do. An inline function can be duplicated
+ // in every file in which it appears œóõ½ and this duplication
+ // includes the static object definition. Because inline functions
+ // automatically default to internal linkage, this would result in
+ // having multiple static objects across the various translation
+ // units, which would certainly cause problems. So you must
+ // ensure that there is only one definition of each wrapping
// function, and this means not making the wrapping functions inline",
- // according to Chapter 10 of "Thinking in C++, 2nd ed. Volume 1" by Bruce Eckel,
+ // according to Chapter 10 of "Thinking in C++, 2nd ed. Volume 1" by Bruce Eckel,
// http://www.mindview.net/
static const Matrix3& zero();
- static const Matrix3& identity();
-
- // Deprecated.
- /** @deprecated Use Matrix3::zero() */
- static const Matrix3 ZERO;
- /** @deprecated Use Matrix3::identity() */
- static const Matrix3 IDENTITY;
+ static const Matrix3& identity();
protected:
+
// support for eigensolver
void tridiagonal (float afDiag[3], float afSubDiag[3]);
bool qLAlgorithm (float afDiag[3], float afSubDiag[3]);
@@ -286,6 +343,7 @@ protected:
};
+
//----------------------------------------------------------------------------
/** <code>v * M == M.transpose() * v</code> */
inline Vector3 operator* (const Vector3& rkPoint, const Matrix3& rkMatrix) {
@@ -301,8 +359,8 @@ inline Vector3 operator* (const Vector3& rkPoint, const Matrix3& rkMatrix) {
return kProd;
}
+
} // namespace
#endif
-
diff --git a/dep/include/g3dlite/G3D/Matrix4.h b/dep/include/g3dlite/G3D/Matrix4.h
new file mode 100644
index 00000000000..9ce87d875b8
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Matrix4.h
@@ -0,0 +1,249 @@
+/**
+ @file Matrix4.h
+
+ 4x4 matrix class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-10-02
+ @edited 2009-10-20
+ */
+
+#ifndef G3D_Matrix4_h
+#define G3D_Matrix4_h
+
+#ifdef _MSC_VER
+// Disable conditional expression is constant, which occurs incorrectly on inlined functions
+# pragma warning (push)
+# pragma warning( disable : 4127 )
+#endif
+
+#include "G3D/platform.h"
+#include "G3D/debugAssert.h"
+#include "G3D/Matrix3.h"
+#include "G3D/Vector3.h"
+
+namespace G3D {
+
+class Any;
+
+/**
+ A 4x4 matrix.
+
+ See also G3D::CoordinateFrame, G3D::Matrix3, G3D::Quat
+ */
+class Matrix4 {
+private:
+
+ float elt[4][4];
+
+ /**
+ Computes the determinant of the 3x3 matrix that lacks excludeRow
+ and excludeCol.
+ */
+ float subDeterminant(int excludeRow, int excludeCol) const;
+
+ // Hidden operators
+ bool operator<(const Matrix4&) const;
+ bool operator>(const Matrix4&) const;
+ bool operator<=(const Matrix4&) const;
+ bool operator>=(const Matrix4&) const;
+
+public:
+ /** Must be of the form: <code>Matrix4(#, #, # .... #)</code>*/
+ Matrix4(const Any& any);
+
+ operator Any() const;
+
+ Matrix4(
+ float r1c1, float r1c2, float r1c3, float r1c4,
+ float r2c1, float r2c2, float r2c3, float r2c4,
+ float r3c1, float r3c2, float r3c3, float r3c4,
+ float r4c1, float r4c2, float r4c3, float r4c4);
+
+ /**
+ init should be <B>row major</B>.
+ */
+ Matrix4(const float* init);
+
+ /**
+ a is the upper left 3x3 submatrix and b is the upper right 3x1 submatrix. The last row of the created matrix is (0,0,0,1).
+ */
+ Matrix4(const class Matrix3& upper3x3, const class Vector3& lastCol = Vector3::zero());
+
+ Matrix4(const class CoordinateFrame& c);
+
+ Matrix4(const double* init);
+
+ Matrix4();
+
+ /** Produces an RT transformation that nearly matches this Matrix4.
+ Because a Matrix4 may not be precisely a rotation and translation,
+ this may introduce error. */
+ class CoordinateFrame approxCoordinateFrame() const;
+
+ // Special values.
+ // Intentionally not inlined: see Matrix3::identity() for details.
+ static const Matrix4& identity();
+ static const Matrix4& zero();
+
+ /** If this is a perspective projection matrix created by
+ Matrix4::perspectiveProjection, extract its parameters. */
+ void getPerspectiveProjectionParameters
+ (float& left,
+ float& right,
+ float& bottom,
+ float& top,
+ float& nearval,
+ float& farval,
+ float updirection = -1.0f) const;
+
+ inline float* operator[](int r) {
+ debugAssert(r >= 0);
+ debugAssert(r < 4);
+ return (float*)&elt[r];
+ }
+
+ inline const float* operator[](int r) const {
+ debugAssert(r >= 0);
+ debugAssert(r < 4);
+ return (const float*)&elt[r];
+ }
+
+ inline operator float* () {
+ return (float*)&elt[0][0];
+ }
+
+ inline operator const float* () const {
+ return (const float*)&elt[0][0];
+ }
+
+ Matrix4 operator*(const Matrix4& other) const;
+
+ class Matrix3 upper3x3() const;
+
+ /** Homogeneous multiplication. Let k = M * [v w]^T. result = k.xyz() / k.w */
+ class Vector3 homoMul(const class Vector3& v, float w) const;
+
+ /**
+ Constructs an orthogonal projection matrix from the given parameters.
+ Near and far are the <b>NEGATIVE</b> of the near and far plane Z values
+ (to follow OpenGL conventions).
+
+ \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
+ 1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
+ */
+ static Matrix4 orthogonalProjection(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float nearval,
+ float farval,
+ float upDirection = -1.0f);
+
+
+ /** \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
+ 1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
+ */
+ static Matrix4 orthogonalProjection(
+ const class Rect2D& rect,
+ float nearval,
+ float farval,
+ float upDirection = -1.0f);
+
+ /** \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
+ 1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
+ */
+ static Matrix4 perspectiveProjection(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float nearval,
+ float farval,
+ float upDirection = -1.0f);
+
+ void setRow(int r, const class Vector4& v);
+ void setColumn(int c, const Vector4& v);
+
+ const Vector4& row(int r) const;
+ Vector4 column(int c) const;
+
+ Matrix4 operator*(const float s) const;
+ Vector4 operator*(const Vector4& vector) const;
+
+ Matrix4 transpose() const;
+
+ bool operator!=(const Matrix4& other) const;
+ bool operator==(const Matrix4& other) const;
+
+ float determinant() const;
+ Matrix4 inverse() const;
+
+ /**
+ Transpose of the cofactor matrix (used in computing the inverse).
+ Note: This is in fact only one type of adjoint. More generally,
+ an adjoint of a matrix is any mapping of a matrix which possesses
+ certain properties. This returns the so-called adjugate
+ or classical adjoint.
+ */
+ Matrix4 adjoint() const;
+ Matrix4 cofactor() const;
+
+ /** Serializes row-major */
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ std::string toString() const;
+
+ /** 3D scale matrix */
+ inline static Matrix4 scale(const Vector3& v) {
+ return Matrix4(v.x, 0, 0, 0,
+ 0, v.y, 0, 0,
+ 0, 0, v.z, 0,
+ 0, 0, 0, 1);
+ }
+
+ /** 3D scale matrix */
+ inline static Matrix4 scale(float x, float y, float z) {
+ return scale(Vector3(x, y, z));
+ }
+
+ /** 3D scale matrix */
+ inline static Matrix4 scale(float s) {
+ return scale(s,s,s);
+ }
+
+ /** 3D translation matrix */
+ inline static Matrix4 translation(const Vector3& v) {
+ return Matrix4(Matrix3::identity(), v);
+ }
+
+ inline static Matrix4 translation(float x, float y, float z) {
+ return Matrix4(Matrix3::identity(), Vector3(x, y, z));
+ }
+
+ /** Create a rotation matrix that rotates \a deg degrees around the Y axis */
+ inline static Matrix4 yawDegrees(float deg) {
+ return Matrix4(Matrix3::fromAxisAngle(Vector3::unitY(), toRadians(deg)));
+ }
+
+ inline static Matrix4 pitchDegrees(float deg) {
+ return Matrix4(Matrix3::fromAxisAngle(Vector3::unitX(), toRadians(deg)));
+ }
+
+ inline static Matrix4 rollDegrees(float deg) {
+ return Matrix4(Matrix3::fromAxisAngle(Vector3::unitZ(), toRadians(deg)));
+ }
+};
+
+
+
+} // namespace
+
+#ifdef _MSC_VER
+# pragma warning (pop)
+#endif
+
+#endif
diff --git a/dep/include/g3dlite/G3D/MemoryManager.h b/dep/include/g3dlite/G3D/MemoryManager.h
new file mode 100644
index 00000000000..15bf6d8be43
--- /dev/null
+++ b/dep/include/g3dlite/G3D/MemoryManager.h
@@ -0,0 +1,93 @@
+/**
+ @file MemoryManager.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2009-04-20
+ @edited 2009-04-20
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_MemoryManager_h
+#define G3D_MemoryManager_h
+
+#include "G3D/platform.h"
+#include "G3D/ReferenceCount.h"
+
+namespace G3D {
+
+/**
+ Abstraction of memory management.
+ Default implementation uses G3D::System::malloc and is threadsafe.
+
+ \sa CRTMemoryManager, AlignedMemoryManager, AreaMemoryManager */
+class MemoryManager : public ReferenceCountedObject {
+protected:
+
+ MemoryManager();
+
+public:
+
+ typedef ReferenceCountedPointer<class MemoryManager> Ref;
+
+ /** Return a pointer to \a s bytes of memory that are unused by
+ the rest of the program. The contents of the memory are
+ undefined */
+ virtual void* alloc(size_t s);
+
+ /** Invoke to declare that this memory will no longer be used by
+ the program. The memory manager is not required to actually
+ reuse or release this memory. */
+ virtual void free(void* ptr);
+
+ /** Returns true if this memory manager is threadsafe (i.e., alloc
+ and free can be called asychronously) */
+ virtual bool isThreadsafe() const;
+
+ /** Return the instance. There's only one instance of the default
+ MemoryManager; it is cached after the first creation. */
+ static MemoryManager::Ref create();
+};
+
+/**
+ Allocates memory on 16-byte boundaries.
+ \sa MemoryManager, CRTMemoryManager, AreaMemoryManager */
+class AlignedMemoryManager : public MemoryManager {
+protected:
+
+ AlignedMemoryManager();
+
+public:
+
+ typedef ReferenceCountedPointer<class AlignedMemoryManager> Ref;
+
+
+ virtual void* alloc(size_t s);
+
+ virtual void free(void* ptr);
+
+ virtual bool isThreadsafe() const;
+
+ static AlignedMemoryManager::Ref create();
+};
+
+
+/** MemoryManager implemented using the C runtime. */
+class CRTMemoryManager : public MemoryManager {
+protected:
+ CRTMemoryManager();
+
+public:
+ typedef ReferenceCountedPointer<class MemoryManager> Ref;
+ virtual void* alloc(size_t s);
+ virtual void free(void* ptr);
+ virtual bool isThreadsafe() const;
+
+ /** There's only one instance of this memory manager; it is
+ cached after the first creation. */
+ static CRTMemoryManager::Ref create();
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/MeshAlg.h b/dep/include/g3dlite/G3D/MeshAlg.h
new file mode 100644
index 00000000000..1decea10105
--- /dev/null
+++ b/dep/include/g3dlite/G3D/MeshAlg.h
@@ -0,0 +1,683 @@
+/**
+ @file MeshAlg.h
+
+ Indexed Mesh algorithms.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-09-14
+ @edited 2010-01-18
+*/
+
+#ifndef G3D_MeshAlg_h
+#define G3D_MeshAlg_h
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Vector3.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/SmallArray.h"
+#include "G3D/constants.h"
+#include "G3D/Image1.h"
+
+#ifdef G3D_WIN32
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+#pragma warning (disable : 4127)
+#endif
+
+namespace G3D {
+
+/**
+ Indexed <B>mesh alg</B>orithms. You have to build your own mesh class.
+ <P>
+ No mesh class is provided with G3D because there isn't an "ideal"
+ mesh format-- one application needs keyframed animation, another
+ skeletal animation, a third texture coordinates, a fourth
+ cannot precompute information, etc. Instead of compromising, this
+ class implements the hard parts of mesh computation and you can write
+ your own ideal mesh class on top of it.
+
+ \sa G3D::ArticulatedModel, G3D::IFSModel
+ */
+class MeshAlg {
+public:
+
+ /** \deprecated */
+ typedef PrimitiveType Primitive;
+
+ /** Adjacency information for a vertex.
+ Does not contain the vertex position or normal,
+ which are stored in the MeshAlg::Geometry object.
+ <CODE>Vertex</CODE>s must be stored in an array
+ parallel to (indexed in the same way as)
+ MeshAlg::Geometry::vertexArray.
+ */
+ class Vertex {
+ public:
+ Vertex() {}
+
+ /**
+ Array of edges adjacent to this vertex.
+ Let e = edgeIndex[i].
+ edge[(e >= 0) ? e : ~e].vertexIndex[0] == this
+ vertex index.
+
+ Edges may be listed multiple times if they are
+ degenerate.
+ */
+ SmallArray<int, 6> edgeIndex;
+
+ /**
+ Returns true if e or ~e is in the edgeIndex list.
+ */
+ inline bool inEdge(int e) const {
+ return edgeIndex.contains(~e) || edgeIndex.contains(e);
+ }
+
+ /**
+ Array of faces containing this vertex. Faces
+ may be listed multiple times if they are degenerate.
+ */
+ SmallArray<int, 6> faceIndex;
+
+ inline bool inFace(int f) const {
+ debugAssert(f >= 0);
+ return faceIndex.contains(f);
+ }
+ };
+
+
+ /**
+ Oriented, indexed triangle.
+ */
+ class Face {
+ public:
+ Face();
+
+ /**
+ Used by Edge::faceIndex to indicate a missing face.
+ This is a large negative value.
+ */
+ static const int NONE;
+
+
+ /**
+ Vertices in the face in counter-clockwise order.
+ Degenerate faces may include the same vertex multiple times.
+ */
+ int vertexIndex[3];
+
+ inline bool containsVertex(int v) const {
+ return contains(vertexIndex, 3, v);
+ }
+
+ /**
+ Edge indices in counter-clockwise order. Edges are
+ undirected, so it is important to know which way
+ each edge is pointing in a face. This is encoded
+ using negative indices.
+
+ If <CODE>edgeIndex[i] >= 0</CODE> then this face
+ contains the directed edge
+ between vertex indices
+ <CODE>edgeArray[face.edgeIndex[i]].vertexIndex[0]</CODE>
+ and
+ <CODE>edgeArray[face.edgeIndex[i]].vertexIndex[1]</CODE>.
+
+ If <CODE>edgeIndex[i] < 0</CODE> then
+ <CODE>~edgeIndex[i]</CODE> (i.e. the two's
+ complement of) is used and this face contains the directed
+ edge between vertex indices
+ <CODE>edgeArray[~face.edgeIndex[i]].vertexIndex[0]</CODE>
+ and
+ <CODE>edgeArray[~face.edgeIndex[i]].vertexIndex[1]</CODE>.
+
+ Degenerate faces may include the same edge multiple times.
+ */
+ // Temporarily takes on the value Face::NONE during adjacency
+ // computation to indicate an edge that has not yet been assigned.
+ int edgeIndex[3];
+
+ inline bool containsEdge(int e) const {
+ if (e < 0) {
+ e = ~e;
+ }
+ return contains(edgeIndex, 3, e) || contains(edgeIndex, 3, ~e);
+ }
+
+ /** Contains the forward edge e if e >= 0 and the backward edge
+ ~e otherwise. */
+ inline bool containsDirectedEdge(int e) const {
+ return contains(edgeIndex, 3, e);
+ }
+ };
+
+
+ /** Oriented, indexed edge */
+ class Edge {
+ public:
+ Edge();
+
+ /** Degenerate edges may include the same vertex times. */
+ int vertexIndex[2];
+
+ inline bool containsVertex(int v) const {
+ return contains(vertexIndex, 2, v);
+ }
+
+ /**
+ The edge is directed <B>forward</B> in face 0
+ <B>backward</B> in face 1. Face index of MeshAlg::Face::NONE
+ indicates a boundary (a.k.a. crack, broken) edge.
+ */
+ int faceIndex[2];
+
+ /** Returns true if f is contained in the faceIndex array in either slot.
+ To see if it is forward in that face, just check edge.faceIndex[0] == f.*/
+ inline bool inFace(int f) const {
+ return contains(faceIndex, 2, f);
+ }
+
+ /**
+ Returns true if either faceIndex is NONE.
+ */
+ inline bool boundary() const {
+ return (faceIndex[0] == Face::NONE) ||
+ (faceIndex[1] == Face::NONE);
+ }
+
+ /**
+ Returns the reversed edge.
+ */
+ inline Edge reverse() const {
+ Edge e;
+ e.vertexIndex[0] = vertexIndex[1];
+ e.vertexIndex[1] = vertexIndex[0];
+ e.faceIndex[0] = faceIndex[1];
+ e.faceIndex[1] = faceIndex[0];
+ return e;
+ }
+ };
+
+
+ /**
+ Convenient for passing around the per-vertex data that changes under
+ animation. The faces and edges are needed to interpret
+ these values.
+ */
+ class Geometry {
+ public:
+ /** Vertex positions */
+ Array<Vector3> vertexArray;
+
+ /** Vertex normals */
+ Array<Vector3> normalArray;
+
+ /**
+ Assignment is optimized using SSE.
+ */
+ Geometry& operator=(const Geometry& src);
+
+ void clear() {
+ vertexArray.clear();
+ normalArray.clear();
+ }
+ };
+
+ /**
+ Given a set of vertices and a set of indices for traversing them
+ to create triangles, computes other mesh properties.
+
+ <B>Colocated vertices are treated as separate.</B> To have
+ colocated vertices collapsed (necessary for many algorithms,
+ like shadowing), weld the mesh before computing adjacency.
+
+ <I>Recent change: In version 6.00, colocated vertices were automatically
+ welded by this routine and degenerate faces and edges were removed. That
+ is no longer the case.</I>
+
+ Where two faces meet, there are two opposite directed edges. These
+ are collapsed into a single bidirectional edge in the edgeArray.
+ If four faces meet exactly at the same edge, that edge will appear
+ twice in the array, and so on. If an edge is a boundary of the mesh
+ (i.e. if the edge has only one adjacent face) it will appear in the
+ array with one face index set to MeshAlg::Face::NONE.
+
+ @param vertexGeometry %Vertex positions to use when deciding colocation.
+ @param indexArray Order to traverse vertices to make triangles
+ @param faceArray <I>Output</I>
+ @param edgeArray <I>Output</I>. Sorted so that boundary edges are at the end of the array.
+ @param vertexArray <I>Output</I>
+ */
+ static void computeAdjacency(
+ const Array<Vector3>& vertexGeometry,
+ const Array<int>& indexArray,
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array<Vertex>& vertexArray);
+
+ /**
+ @deprecated Use the other version of computeAdjacency, which takes Array<Vertex>.
+ @param facesAdjacentToVertex <I>Output</I> adjacentFaceArray[v] is an array of
+ indices for faces touching vertex index v
+ */
+ static void computeAdjacency(
+ const Array<Vector3>& vertexArray,
+ const Array<int>& indexArray,
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array< Array<int> >& facesAdjacentToVertex);
+
+ /**
+ Computes some basic mesh statistics including: min, max mean and median,
+ edge lengths; and min, mean, median, and max face area.
+
+ @param vertexArray %Vertex positions to use when deciding colocation.
+ @param indexArray Order to traverse vertices to make triangles
+ @param minEdgeLength Minimum edge length
+ @param meanEdgeLength Mean edge length
+ @param medianEdgeLength Median edge length
+ @param maxEdgeLength Max edge length
+ @param minFaceArea Minimum face area
+ @param meanFaceArea Mean face area
+ @param medianFaceArea Median face area
+ @param maxFaceArea Max face area
+ */
+ static void computeAreaStatistics(
+ const Array<Vector3>& vertexArray,
+ const Array<int>& indexArray,
+ double& minEdgeLength,
+ double& meanEdgeLength,
+ double& medianEdgeLength,
+ double& maxEdgeLength,
+ double& minFaceArea,
+ double& meanFaceArea,
+ double& medianFaceArea,
+ double& maxFaceArea);
+
+private:
+
+ /** Helper for weldAdjacency */
+ static void weldBoundaryEdges(
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array<Vertex>& vertexArray);
+
+public:
+
+ /**
+ Computes tangent and binormal vectors,
+ which provide a (mostly) consistent
+ parameterization over the surface for
+ effects like bump mapping. In the resulting coordinate frame,
+ T = x (varies with texture s coordinate), B = y (varies with negative texture t coordinate),
+ and N = z for a right-handed coordinate frame. If a billboard is vertical on the screen
+ in view of the camera, the tangent space matches the camera's coordinate frame.
+
+ The vertex, texCoord, tangent, and binormal
+ arrays are parallel arrays.
+
+ The resulting tangent and binormal might not be exactly
+ perpendicular to each other. They are guaranteed to
+ be perpendicular to the normal.
+
+ @cite Max McGuire
+ */
+ static void computeTangentSpaceBasis(
+ const Array<Vector3>& vertexArray,
+ const Array<Vector2>& texCoordArray,
+ const Array<Vector3>& vertexNormalArray,
+ const Array<Face>& faceArray,
+ Array<Vector3>& tangent,
+ Array<Vector3>& binormal);
+
+ /** @deprecated */
+ static void computeNormals(
+ const Array<Vector3>& vertexArray,
+ const Array<Face>& faceArray,
+ const Array< Array<int> >& adjacentFaceArray,
+ Array<Vector3>& vertexNormalArray,
+ Array<Vector3>& faceNormalArray);
+
+ /**
+ Vertex normals are weighted by the area of adjacent faces.
+ Nelson Max showed this is superior to uniform weighting for
+ general meshes in jgt.
+
+ @param vertexNormalArray Output. Unit length
+ @param faceNormalArray Output. Degenerate faces produce zero magnitude normals. Unit length
+ @see weld
+ */
+ static void computeNormals(
+ const Array<Vector3>& vertexGeometry,
+ const Array<Face>& faceArray,
+ const Array<Vertex>& vertexArray,
+ Array<Vector3>& vertexNormalArray,
+ Array<Vector3>& faceNormalArray);
+
+ /** Computes unit length normals in place using the other computeNormals methods.
+ If you already have a face array use another method; it will be faster.
+ @see weld*/
+ static void computeNormals(
+ Geometry& geometry,
+ const Array<int>& indexArray);
+
+ /**
+ Computes face normals only. Significantly faster (especially if
+ normalize is false) than computeNormals.
+ @see weld
+ */
+ static void computeFaceNormals(
+ const Array<Vector3>& vertexArray,
+ const Array<Face>& faceArray,
+ Array<Vector3>& faceNormals,
+ bool normalize = true);
+
+ /**
+ Classifies each face as a backface or a front face relative
+ to the observer point P (which is at infinity when P.w = 0).
+ A face with normal exactly perpendicular to the observer vector
+ may be classified as either a front or a back face arbitrarily.
+ */
+ static void identifyBackfaces(
+ const Array<Vector3>& vertexArray,
+ const Array<Face>& faceArray,
+ const Vector4& P,
+ Array<bool>& backface);
+
+ /** A faster version of identifyBackfaces for the case where
+ face normals have already been computed */
+ static void identifyBackfaces(
+ const Array<Vector3>& vertexArray,
+ const Array<Face>& faceArray,
+ const Vector4& P,
+ Array<bool>& backface,
+ const Array<Vector3>& faceNormals);
+
+ /**
+ Welds nearby and colocated elements of the <I>oldVertexArray</I> together so that
+ <I>newVertexArray</I> contains no vertices within <I>radius</I> of one another.
+ Every vertex in newVertexPositions also appears in oldVertexPositions.
+ This is useful for downsampling meshes and welding cracks created by artist errors
+ or numerical imprecision.
+
+ The two integer arrays map indices back and forth between the arrays according to:
+ <PRE>
+ oldVertexArray[toOld[ni]] == newVertexArray[ni]
+ oldVertexArray[oi] == newVertexArray[toNew[ni]]
+ </PRE>
+
+ Note that newVertexPositions is never longer than oldVertexPositions
+ and is shorter when vertices are welded.
+
+ Welding with a large radius will effectively compute a lower level of detail for
+ the mesh.
+
+ The welding method runs in roughly linear time in the length of oldVertexArray--
+ a uniform spatial grid is used to achieve nearly constant time vertex collapses
+ for uniformly distributed vertices.
+
+ It is sometimes desirable to keep the original vertex ordering but
+ identify the unique vertices. The following code computes
+ array canonical s.t. canonical[v] = first occurance of
+ a vertex near oldVertexPositions[v] in oldVertexPositions.
+
+ <PRE>
+ Array<int> canonical(oldVertexPositions.size()), toNew, toOld;
+ computeWeld(oldVertexPositions, Array<Vector3>(), toNew, toOld, radius);
+ for (int v = 0; v < canonical.size(); ++v) {
+ canonical[v] = toOld[toNew[v]];
+ }
+ </PRE>
+
+ See also G3D::MeshAlg::weldAdjacency.
+
+ @cite The method is that described as the 'Grouper' in Baum, Mann, Smith, and Winget,
+ Making Radiosity Usable: Automatic Preprocessing and Meshing Techniques for
+ the Generation of Accurate Radiosity Solutions, Computer Graphics vol 25, no 4, July 1991.
+
+ @deprecated Use weld.
+ */
+ static void computeWeld(
+ const Array<Vector3>& oldVertexPositions,
+ Array<Vector3>& newVertexPositions,
+ Array<int>& toNew,
+ Array<int>& toOld,
+ double radius = fuzzyEpsilon);
+
+ /**
+ Modifies the face, edge, and vertex arrays in place so that
+ colocated (within radius) vertices are treated as identical.
+ Note that the vertexArray and corresponding geometry will
+ contain elements that are no longer used. In the vertexArray,
+ these elements are initialized to MeshAlg::Vertex() but not
+ removed (because removal would change the indexing).
+
+ This is a good preprocessing step for algorithms that are only
+ concerned with the shape of a mesh (e.g. cartoon rendering, fur, shadows)
+ and not the indexing of the vertices.
+
+ Use this method when you have already computed adjacency information
+ and want to collapse colocated vertices within that data without
+ disturbing the actual mesh vertices or indexing scheme.
+
+ If you have not computed adjacency already, use MeshAlg::computeWeld
+ instead and compute adjacency information after welding.
+
+ @deprecated Use weld.
+
+ @param faceArray Mutated in place. Size is maintained (degenerate
+ faces are <b>not</B> removed).
+ @param edgeArray Mutated in place. May shrink if boundary edges
+ are welded together.
+ @param vertexArray Mutated in place. Size is maintained (duplicate
+ vertices contain no adjacency info).
+ */
+ static void weldAdjacency(
+ const Array<Vector3>& originalGeometry,
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array<Vertex>& vertexArray,
+ double radius = fuzzyEpsilon);
+
+
+ /**
+ Counts the number of edges (in an edge array returned from
+ MeshAlg::computeAdjacency) that have only one adjacent face.
+ */
+ static int countBoundaryEdges(const Array<Edge>& edgeArray);
+
+
+ /**
+ Generates an array of integers from start to start + n - 1 that have run numbers
+ in series then omit the next skip before the next run. Useful for turning
+ a triangle list into an indexed face set.
+
+ Example:
+ <PRE>
+ createIndexArray(10, x);
+ // x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+ createIndexArray(5, x, 2);
+ // x = [2, 3, 4, 5, 6, 7]
+
+ createIndexArray(6, x, 0, 2, 1);
+ // x = [0, 1, 3, 4, 6, 7]
+ </PRE>
+ */
+ static void createIndexArray(
+ int n,
+ Array<int>& array,
+ int start = 0,
+ int run = 1,
+ int skip = 0);
+
+ /**
+ Computes a conservative, near-optimal axis aligned bounding box and sphere.
+
+ @cite The bounding sphere uses the method from J. Ritter. An effcient bounding sphere. In Andrew S. Glassner, editor, Graphics Gems. Academic Press, Boston, MA, 1990.
+
+ */
+ static void computeBounds(const Array<Vector3>& vertex, class AABox& box, class Sphere& sphere);
+
+ /** Computes bounds for a subset of the vertices. It is ok if vertices appear more than once in the index array. */
+ static void computeBounds(const Array<Vector3>& vertex, const Array<int>& index, class AABox& box, class Sphere& sphere);
+
+ /**
+ In debug mode, asserts that the adjacency references between the
+ face, edge, and vertex array are consistent.
+ */
+ static void debugCheckConsistency(
+ const Array<Face>& faceArray,
+ const Array<Edge>& edgeArray,
+ const Array<Vertex>& vertexArray);
+
+ /**
+ Generates a unit square in the X-Z plane composed of a grid of wCells x hCells
+ squares and then transforms it by xform.
+
+ @param vertex Output vertices
+ @param texCoord Output texture coordinates
+ @param index Output triangle list indices
+ @param textureScale Lower-right texture coordinate
+ @param spaceCentered If true, the coordinates generated are centered at the origin before the transformation.
+ @param twoSided If true, matching top and bottom planes are generated.
+ \param elevation If non-NULL, values from this image are used as elevations. Apply an \a xform to adjust the scale
+ */
+ static void generateGrid(
+ Array<Vector3>& vertex,
+ Array<Vector2>& texCoord,
+ Array<int>& index,
+ int wCells = 10,
+ int hCells = 10,
+ const Vector2& textureScale = Vector2(1,1),
+ bool spaceCentered = true,
+ bool twoSided = true,
+ const CoordinateFrame& xform = CoordinateFrame(),
+ const Image1::Ref& elevation = NULL);
+
+ /** Converts quadlist (QUADS),
+ triangle fan (TRIANGLE_FAN),
+ tristrip(TRIANGLE_STRIP), and quadstrip (QUAD_STRIP) indices into
+ triangle list (TRIANGLES) indices and appends them to outIndices. */
+ template<class IndexType>
+ static void toIndexedTriList(
+ const Array<IndexType>& inIndices,
+ MeshAlg::Primitive inType,
+ Array<IndexType>& outIndices) {
+
+ debugAssert(
+ inType == PrimitiveType::TRIANGLE_STRIP ||
+ inType == PrimitiveType::TRIANGLE_FAN ||
+ inType == PrimitiveType::QUADS ||
+ inType == PrimitiveType::QUAD_STRIP);
+
+ const int inSize = inIndices.size();
+
+ switch(inType) {
+ case PrimitiveType::TRIANGLE_FAN:
+ {
+ debugAssert(inSize >= 3);
+
+ int N = outIndices.size();
+ outIndices.resize(N + (inSize - 2) * 3);
+
+ for (IndexType i = 1, outIndex = N; i <= (inSize - 2); ++i, outIndex += 3) {
+ outIndices[outIndex] = inIndices[0];
+ outIndices[outIndex + 1] = inIndices[i];
+ outIndices[outIndex + 2] = inIndices[i + 1];
+ }
+
+ break;
+ }
+
+ case PrimitiveType::TRIANGLE_STRIP:
+ {
+ debugAssert(inSize >= 3);
+
+ int N = outIndices.size();
+ outIndices.resize(N + (inSize - 2) * 3);
+
+ bool atEven = false;
+ for (IndexType i = 0, outIndex = N; i <= (inSize - 2); ++i, outIndex += 3) {
+ if (atEven) {
+ outIndices[outIndex] = inIndices[i + 1];
+ outIndices[outIndex + 1] = inIndices[i];
+ outIndices[outIndex + 2] = inIndices[i + 2];
+ atEven = false;
+ } else {
+ outIndices[outIndex] = inIndices[i];
+ outIndices[outIndex + 1] = inIndices[i + 1];
+ outIndices[outIndex + 2] = inIndices[i + 2];
+ atEven = true;
+ }
+ }
+
+ break;
+ }
+
+ case PrimitiveType::QUADS:
+ {
+ debugAssert(inIndices.size() >= 4);
+
+ int N = outIndices.size();
+ outIndices.resize(N + (inSize / 4) * 3);
+
+ for (IndexType i = 0, outIndex = N; i <= (inSize - 4); i += 4, outIndex += 6) {
+ outIndices[outIndex] = inIndices[i];
+ outIndices[outIndex + 1] = inIndices[i + 1];
+ outIndices[outIndex + 2] = inIndices[i + 3];
+ outIndices[outIndex + 3] = inIndices[i + 1];
+ outIndices[outIndex + 4] = inIndices[i + 2];
+ outIndices[outIndex + 5] = inIndices[i + 3];
+ }
+
+ break;
+ }
+
+ case PrimitiveType::QUAD_STRIP:
+ {
+ debugAssert(inIndices.size() >= 4);
+
+ int N = outIndices.size();
+ outIndices.resize(N + (inSize - 2) * 3);
+
+ for (IndexType i = 0, outIndex = N; i <= (inSize - 2); i += 2, outIndex += 6) {
+ outIndices[outIndex] = inIndices[i];
+ outIndices[outIndex + 1] = inIndices[i + 1];
+ outIndices[outIndex + 2] = inIndices[i + 2];
+ outIndices[outIndex + 3] = inIndices[i + 2];
+ outIndices[outIndex + 4] = inIndices[i + 1];
+ outIndices[outIndex + 5] = inIndices[i + 3];
+ }
+ break;
+ }
+ default:
+ alwaysAssertM(false, "Illegal argument");
+ }
+ }
+
+protected:
+
+ /**
+ Helper for computeAdjacency. If a directed edge with index e already
+ exists from i0 to i1 then e is returned. If a directed edge with index e
+ already exists from i1 to i0, ~e is returned (the complement) and
+ edgeArray[e] is set to f. Otherwise, a new edge is created from i0 to i1
+ with first face index f and its index is returned.
+
+ @param vertexArray Vertex positions to use when deciding colocation.
+
+ @param area Area of face f. When multiple edges of the same direction
+ are found between the same vertices (usually because of degenerate edges)
+ the face with larger area is kept in the edge table.
+ */
+ static int findEdgeIndex(
+ const Array<Vector3>& vertexArray,
+ Array<Edge>& geometricEdgeArray,
+ int i0, int i1, int f, double area);
+};
+}
+#endif
+
diff --git a/dep/include/g3dlite/G3D/MeshBuilder.h b/dep/include/g3dlite/G3D/MeshBuilder.h
new file mode 100644
index 00000000000..9920d59d7d3
--- /dev/null
+++ b/dep/include/g3dlite/G3D/MeshBuilder.h
@@ -0,0 +1,82 @@
+/**
+ @file MeshBuilder.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2002-02-27
+ @edited 2004-10-04
+ */
+#ifndef G3D_MESHBUILDER_H
+#define G3D_MESHBUILDER_H
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Vector3.h"
+#include "G3D/Triangle.h"
+
+namespace G3D {
+
+/**
+ Allows creation of optimized watertight meshes from unoptimized polygon soups.
+ See also G3D::MeshAlg for algorithms that operate on the output.
+ */
+class MeshBuilder {
+public:
+
+ /**
+ Set setWeldRadius to AUTO_WELD to weld vertices closer than 1/2
+ the smallest edge length in a model.
+ */
+ enum {AUTO_WELD = -100};
+
+private:
+ /** Indices of vertices in <B>or near</B> a grid cell. */
+ typedef Array<int> List;
+
+ std::string name;
+
+ /**
+ All of the triangles, as a long triangle list.
+ */
+ Array<Vector3> triList;
+
+ void centerTriList();
+ void computeBounds(Vector3& min, Vector3& max);
+
+ bool _twoSided;
+
+ /** Collapse radius */
+ double close;
+
+public:
+
+ inline MeshBuilder(bool twoSided = false) : _twoSided(twoSided), close(AUTO_WELD) {}
+
+ /** Writes the model to the arrays, which can then be used with
+ G3D::IFSModel::save and G3D::MeshAlg */
+ void commit(std::string& name, Array<int>& indexArray, Array<Vector3>& vertexArray);
+
+ /**
+ Adds a new triangle to the model. (Counter clockwise)
+ */
+ void addTriangle(const Vector3& a, const Vector3& b, const Vector3& c);
+
+ /**
+ Adds two new triangles to the model. (Counter clockwise)
+ */
+ void addQuad(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d);
+
+ void addTriangle(const Triangle& t);
+
+ void setName(const std::string& n);
+
+ /** Vertices within this distance are considered identical.
+ Use AUTO_WELD (the default) to have the distance be a function of the model size.*/
+ void setWeldRadius(double r) {
+ close = r;
+ }
+};
+
+} // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/NetAddress.h b/dep/include/g3dlite/G3D/NetAddress.h
new file mode 100644
index 00000000000..8ed20a06690
--- /dev/null
+++ b/dep/include/g3dlite/G3D/NetAddress.h
@@ -0,0 +1,132 @@
+#ifndef G3D_NETADDRESS_H
+#define G3D_NETADDRESS_H
+
+#include "G3D/platform.h"
+#include "G3D/Table.h"
+
+/** These control the version of Winsock used by G3D.
+ Version 2.0 is standard for G3D 6.09 and later.
+ Version 1.1 is standard for G3D 6.08 and earlier.
+ */
+#define G3D_WINSOCK_MAJOR_VERSION 2
+#define G3D_WINSOCK_MINOR_VERSION 0
+
+#ifdef G3D_WIN32
+# if (G3D_WINSOCK_MAJOR_VERSION == 2)
+# include <winsock2.h>
+# elif (G3D_WINSOCK_MAJOR_VERSION == 1)
+# include <winsock.h>
+# endif
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# ifndef SOCKADDR_IN
+# define SOCKADDR_IN struct sockaddr_in
+# endif
+# ifndef SOCKET
+# define SOCKET int
+# endif
+#endif
+
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+class NetAddress {
+private:
+ friend class NetworkDevice;
+ friend class LightweightConduit;
+ friend class ReliableConduit;
+
+ /** Host byte order */
+ void init(uint32 host, uint16 port);
+ void init(const std::string& hostname, uint16 port);
+ NetAddress(const SOCKADDR_IN& a);
+ NetAddress(const struct in_addr& addr, uint16 port = 0);
+
+ SOCKADDR_IN addr;
+
+public:
+ /**
+ In host byte order
+ */
+ NetAddress(uint32 host, uint16 port = 0);
+
+ /**
+ @param port Specified in host byte order (i.e., don't worry about endian issues)
+ */
+ NetAddress(const std::string& hostname, uint16 port);
+
+ /**
+ @param hostnameAndPort in the form "hostname:port" or "ip:port"
+ */
+ NetAddress(const std::string& hostnameAndPort);
+
+ /**
+ @deprecated Use G3D::NetworkDevice::broadcastAddressArray()
+
+ @brief Creates a UDP broadcast address for use with a
+ G3D::LightweightConduit.
+
+ UDP broadcast allows one machine to send a packet to all machines
+ on the same local network. The IP portion of the address is
+ 0xFFFFFFFF, which indicates "broadcast" to the underlying socket
+ API. This feature is not available with the connection-based TCP
+ protocol abstracted by G3D::ReliableConduit; use multisend
+ instead.
+ */
+ static NetAddress broadcastAddress(uint16 port);
+
+ NetAddress();
+
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ /** @brief Returns true if this is not an illegal address. */
+ bool ok() const;
+
+ /** @brief Returns a value in host format (i.e., don't worry about
+ endian issues) */
+ inline uint32 ip() const {
+ return ntohl(addr.sin_addr.s_addr);
+ //return ntohl(addr.sin_addr.S_un.S_addr);
+ }
+
+ inline uint16 port() const {
+ return ntohs(addr.sin_port);
+ }
+
+ std::string ipString() const;
+ std::string toString() const;
+
+};
+
+std::ostream& operator<<(std::ostream& os, const NetAddress&);
+
+} // namespace G3D
+
+template <> struct HashTrait<G3D::NetAddress> {
+ static size_t hashCode(const G3D::NetAddress& key) {
+ return static_cast<size_t>(key.ip() + (static_cast<G3D::uint32>(key.port()) << 16));
+ }
+};
+
+namespace G3D {
+
+/**
+ Two addresses may point to the same computer but be != because
+ they have different IP's.
+ */
+inline bool operator==(const NetAddress& a, const NetAddress& b) {
+ return (a.ip() == b.ip()) && (a.port() == b.port());
+}
+
+
+inline bool operator!=(const NetAddress& a, const NetAddress& b) {
+ return !(a == b);
+}
+
+} // namespace G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/NetworkDevice.h b/dep/include/g3dlite/G3D/NetworkDevice.h
new file mode 100644
index 00000000000..ea3290cbc09
--- /dev/null
+++ b/dep/include/g3dlite/G3D/NetworkDevice.h
@@ -0,0 +1,738 @@
+/**
+ @file NetworkDevice.h
+
+ These classes abstract networking from the socket level to a
+ serialized messaging style that is more appropriate for games. The
+ performance has been tuned for sending many small messages. The
+ message protocol contains a header that prevents them from being used
+ with raw UDP/TCP (e.g. connecting to an HTTP server).
+
+ LightweightConduit and ReliableConduits have different interfaces
+ because they have different semantics. You would never want to
+ interchange them without rewriting the surrounding code.
+
+ NetworkDevice creates conduits because they need access to a global
+ log pointer and because I don't want non-reference counted conduits
+ being created.
+
+ Be careful with threads and reference counting. The reference
+ counters are not threadsafe, and are also not updated correctly if a
+ thread is explicitly killed. Since the conduits will be passed by
+ const XConduitRef& most of the time this doesn't appear as a major
+ problem. With non-blocking conduits, you should need few threads
+ anyway.
+
+ LightweightConduits preceed each message with a 4-byte host order
+ unsigned integer that is the message type. This does not appear in
+ the message serialization/deserialization.
+
+ ReliableConduits preceed each message with two 4-byte host order
+ unsigned integers. The first is the message type and the second
+ indicates the length of the rest of the data. The size does not
+ include the size of the header itself. The minimum message is 9
+ bytes:a 4-byte type, a 4-byte header equal to "1", and one byte of data.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-11-22
+ @edited 2006-11-25
+ */
+
+#ifndef G3D_NETWORKDEVICE_H
+#define G3D_NETWORKDEVICE_H
+
+#include "G3D/platform.h"
+#include "G3D/NetAddress.h"
+
+#include <string>
+#include <iostream>
+#include "G3D/g3dmath.h"
+
+#include "G3D/ReferenceCount.h"
+#include "G3D/Array.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+class TextOutput;
+
+class Conduit : public ReferenceCountedObject {
+protected:
+ friend class NetworkDevice;
+ friend class NetListener;
+
+ uint64 mSent;
+ uint64 mReceived;
+ uint64 bSent;
+ uint64 bReceived;
+
+ SOCKET sock;
+
+ /**
+ Used for serialization. One per socket
+ to make this threadsafe.
+ */
+ BinaryOutput binaryOutput;
+
+ Conduit();
+
+public:
+
+ virtual ~Conduit();
+ uint64 bytesSent() const;
+ uint64 messagesSent() const;
+ uint64 bytesReceived() const;
+ uint64 messagesReceived() const;
+
+ /**
+ If true, receive will return true.
+ */
+ virtual bool messageWaiting();
+
+ /**
+ Returns the type of the waiting message (i.e. the type supplied
+ with send). The return value is zero when there is no message
+ waiting.
+
+ One way to use this is to have a Table mapping message types to
+ pre-allocated subclasses so receiving looks like:
+
+ <PRE>
+ // My base class for messages.
+ class Message {
+ virtual void serialize(BinaryOutput&) const;
+ virtual void deserialize(BinaryInput&);
+ virtual void process() = 0;
+ };
+
+ Message* m = table[conduit->waitingMessageType()];
+ conduit->receive(m);
+ m->process();
+ </PRE>
+
+ Another is to simply switch on the message type:
+
+ <pre>
+ switch (conduit->waitingMessageType()) {
+ case 0:
+ // No message
+ break;
+
+ case ENTITY_SPAWN_MSG:
+ {
+ EntitySpawnMsg m;
+ condiut->receive(m);
+ spawnEntity(m.id, m.position, m.modelID);
+ }
+ break;
+ ...
+ }
+ </pre>
+ */
+ virtual uint32 waitingMessageType() = 0;
+
+ /** Returns true if the connection is ok. */
+ bool ok() const;
+};
+
+typedef ReferenceCountedPointer<class ReliableConduit> ReliableConduitRef;
+
+#ifdef __GNUC__
+// Workaround for a known bug in gcc 4.x where htonl produces
+// a spurrious warning.
+// http://gcc.gnu.org/ml/gcc-bugs/2005-10/msg03270.html
+uint32 gcchtonl(uint32);
+#endif
+
+// Messaging and stream APIs must be supported on a single class because
+// sometimes an application will switch modes on a single socket. For
+// example, when transferring 3D level geometry during handshaking with
+// a game server.
+/**
+ A conduit that guarantees messages will arrive, intact and in order.
+ Create on the client using NetworkDevice::createReliableConduit and
+ on the server using NetListener::waitForConnection. Set the reference
+ counted pointer to NULL to disconnect.
+
+ To construct a ReliableConduit:
+ <OL>
+ <LI> Create a G3D::NetworkDevice (if you are using G3D::GApp, it creates
+ one for you) on the client and on the server.
+ <LI> On the server, create a G3D::NetListener using
+ G3D::NetworkDevice::createListener
+ <LI> On the server, invoke G3D::NetListener::waitForConnection.
+ <LI> On the client, call G3D::NetworkDevice::createReliableConduit.
+ You will need the server's G3D::NetAddress. Consider using
+ G3D::Discovery::Client to find it via broadcasting.
+ </OL>
+
+ */
+class ReliableConduit : public Conduit {
+private:
+ friend class NetworkDevice;
+ friend class NetListener;
+
+ enum State {RECEIVING, HOLDING, NO_MESSAGE} state;
+
+ NetAddress addr;
+
+ /**
+ Type of the incoming message.
+ */
+ uint32 messageType;
+
+ /**
+ Total size of the incoming message (read from the header).
+ */
+ uint32 messageSize;
+
+ /** Shared buffer for receiving messages. */
+ void* receiveBuffer;
+
+ /** Total size of the receiveBuffer. */
+ size_t receiveBufferTotalSize;
+
+ /** Size occupied by the current message... so far. This will be
+ equal to messageSize when the whole message has arrived.
+ */
+ size_t receiveBufferUsedSize;
+
+ ReliableConduit(const NetAddress& addr);
+
+ ReliableConduit(const SOCKET& sock,
+ const NetAddress& addr);
+
+ template<typename T> static void serializeMessage
+ (uint32 t, const T& m, BinaryOutput& b) {
+
+ b.writeUInt32(t);
+
+ // Reserve space for the 4 byte size header
+ b.writeUInt32(0);
+
+ size_t L = b.length();
+ m.serialize(b);
+ if ((size_t)b.length() == L) {
+ // No data was created by serialization.
+ // We need to send at least one byte because receive assumes that
+ // a zero length message is an error.
+ b.writeUInt8(0xFF);
+ }
+
+ uint32 len = b.size() - 8;
+
+ // We send the length first to tell recv how much data to read.
+ // Here we abuse BinaryOutput a bit and write directly into
+ // its buffer, violating the abstraction.
+ // Note that we write to the second set of 4 bytes, which is
+ // the size field.
+ uint32* lenPtr = ((uint32*)b.getCArray()) + 1;
+ #if defined(__GNUC__)
+ *lenPtr = gcchtonl(len);
+ #else
+ *lenPtr = htonl(len);
+ #endif
+ }
+
+
+ void sendBuffer(const BinaryOutput& b);
+
+ /** Accumulates whatever part of the message (not the header) is
+ still waiting on the socket into the receiveBuffer during
+ state = RECEIVING mode. Closes the socket if anything goes
+ wrong. When receiveBufferUsedSize == messageSize, the entire
+ message has arrived. */
+ void receiveIntoBuffer();
+
+ /** Receives the messageType and messageSize from the socket. */
+ void receiveHeader();
+
+public:
+
+ /**
+ Client invokes this to connect to a server. The call blocks until the
+ conduit is opened. The conduit will not be ok() if it fails.
+ */
+ static ReliableConduitRef create(const NetAddress& address);
+
+ /** Closes the socket. */
+ ~ReliableConduit();
+
+
+ // The message is actually copied from the socket to an internal buffer during
+ // this call. Receive only deserializes.
+ virtual bool messageWaiting();
+
+ /**
+ Serializes the message and schedules it to be sent as soon as possible,
+ and then returns immediately. The message can be any <B>class</B> with
+ a serialize and deserialize method. On the receiving side,
+ use G3D::ReliableConduit::waitingMessageType() to detect the incoming
+ message and then invoke G3D::ReliableConduit::receive(msg) where msg
+ is of the same class as the message that was sent.
+
+ The actual data sent across the network is preceeded by the
+ message type and the size of the serialized message as a 32-bit
+ integer. The size is sent because TCP is a stream protocol and
+ doesn't have a concept of discrete messages.
+ */
+ template<typename T> inline void send(uint32 type, const T& message) {
+ binaryOutput.reset();
+ serializeMessage(type, message, binaryOutput);
+ sendBuffer(binaryOutput);
+ }
+
+ /** Sends an empty message with the given type. Useful for sending
+ commands that have no parameters. */
+ void send(uint32 type);
+
+ /** Send the same message to a number of conduits. Useful for sending
+ data from a server to many clients (only serializes once). */
+ template<typename T>
+ inline static void multisend(
+ const Array<ReliableConduitRef>& array,
+ uint32 type,
+ const T& m) {
+
+ if (array.size() > 0) {
+ array[0]->binaryOutput.reset();
+ serializeMessage(type, m, array[0]->binaryOutput);
+
+ for (int i = 0; i < array.size(); ++i) {
+ array[i]->sendBuffer(array[0]->binaryOutput);
+ }
+ }
+ }
+
+ virtual uint32 waitingMessageType();
+
+ /**
+ If a message is waiting, deserializes the waiting message into
+ message and returns true, otherwise returns false. You can
+ determine the type of the message (and therefore, the class
+ of message) using G3D::ReliableConduit::waitingMessageType().
+ */
+ template<typename T> inline bool receive(T& message) {
+ if (! messageWaiting()) {
+ return false;
+ }
+
+ debugAssert(state == HOLDING);
+ // Deserialize
+ BinaryInput b((uint8*)receiveBuffer, receiveBufferUsedSize, G3D_LITTLE_ENDIAN, BinaryInput::NO_COPY);
+ message.deserialize(b);
+
+ // Don't let anyone read this message again. We leave the buffer
+ // allocated for the next caller, however.
+ receiveBufferUsedSize = 0;
+ state = NO_MESSAGE;
+ messageType = 0;
+ messageSize = 0;
+
+ // Potentially read the next message.
+ messageWaiting();
+
+ return true;
+ }
+
+ /** Removes the current message from the queue. */
+ inline void receive() {
+ if (! messageWaiting()) {
+ return;
+ }
+ receiveBufferUsedSize = 0;
+ state = NO_MESSAGE;
+ messageType = 0;
+ messageSize = 0;
+
+ // Potentially read the next message.
+ messageWaiting();
+ }
+
+ NetAddress address() const;
+};
+
+
+typedef ReferenceCountedPointer<class LightweightConduit> LightweightConduitRef;
+
+/**
+ Provides fast but unreliable transfer of messages. On a LAN,
+ LightweightConduit will probably never drop messages but you
+ <I>might</I> get your messages out of order. On an internet
+ connection it might drop messages altogether. Messages are never
+ corrupted, however. LightweightConduit requires a little less setup
+ and overhead than ReliableConduit. ReliableConduit guarantees
+ message delivery and order but requires a persistent connection.
+
+ To set up a LightweightConduit (assuming you have already made
+ subclasses of G3D::NetMessage based on your application's
+ pcommunication protocol):
+
+[Server Side]
+<OL>
+<LI> Call LightweightConduit::create(port, true, false),
+where port is the port on which you will receive messages.
+
+<LI> Poll LightweightConduit::messageWaiting from your main loop. When
+it is true (or, equivalently, when LightweightConduit::waitingMessageType
+is non-zero) there is an incoming message.
+
+<LI> To read the incoming message, call LightweightConduit::receive with
+the appropriate class type, which mist have a deserialize method.
+LightweightConduit::waitingMessageType tells you what class is
+needed (you make up your own message constants for your program; numbers
+under 1000 are reserved for G3D's internal use).
+
+<LI> When done, simply set the G3D::LightweightConduitRef to NULL or let
+it go out of scope and the conduit cleans itself up automatically.
+</OL>
+
+[Client Side]
+<OL>
+<LI> Call G3D::LightweightConduit::create(). If you will
+broadcast to all servers on a LAN, set the third optional argument to
+true (the default is false for no broadcast). You can also set up the
+receive port as if it was a server to send and receive from a single
+LightweightConduit.
+
+<LI> To send, call G3D::LightweightConduit::send with the target address
+and a pointer to an instance of the message you want to send.
+
+<LI> When done, simply set the G3D::LightweightConduitRef to NULL or let
+it go out of scope and the conduit cleans itself up automatically.
+
+</OL>
+ */
+class LightweightConduit : public Conduit {
+private:
+ friend class NetworkDevice;
+
+ /**
+ True when waitingForMessageType has read the message
+ from the network into messageType/messageStream.
+ */
+ bool alreadyReadMessage;
+
+ /**
+ Origin of the received message.
+ */
+ NetAddress messageSender;
+
+ /**
+ The type of the last message received.
+ */
+ uint32 messageType;
+
+ /**
+ The message received (the type has already been read off).
+ */
+ Array<uint8> messageBuffer;
+
+ LightweightConduit(uint16 receivePort, bool enableReceive, bool enableBroadcast);
+
+ void sendBuffer(const NetAddress& a, BinaryOutput& b);
+
+ /** Maximum transmission unit (packet size in bytes) for this socket.
+ May vary between sockets. */
+ int MTU;
+
+
+ template<typename T>
+ void serializeMessage(
+ uint32 type,
+ const T& m,
+ BinaryOutput& b) const {
+
+ debugAssert(type != 0);
+ b.writeUInt32(type);
+ m.serialize(b);
+ b.writeUInt32(1);
+
+ debugAssertM(b.size() < MTU,
+ format("This LightweightConduit is limited to messages of "
+ "%d bytes (Ethernet hardware limit; this is the "
+ "'UDP MTU')", maxMessageSize()));
+
+ if (b.size() >= MTU) {
+ throw LightweightConduit::PacketSizeException(
+ format("This LightweightConduit is limited to messages of "
+ "%d bytes (Ethernet hardware limit; this is the "
+ "'UDP MTU')", maxMessageSize()),
+ b.size() - 4, // Don't count the type header
+ maxMessageSize());
+ }
+ }
+
+public:
+
+ static LightweightConduitRef create(uint16 receivePort, bool enableReceive, bool enableBroadcast);
+
+ class PacketSizeException {
+ public:
+ std::string message;
+ int serializedPacketSize;
+ int maxMessageSize;
+
+ inline PacketSizeException(const std::string& m, int s, int b) :
+ message(m),
+ serializedPacketSize(s),
+ maxMessageSize(b) {}
+ };
+
+ /** Closes the socket. */
+ ~LightweightConduit();
+
+ /** The maximum length of a message that can be sent
+ (G3D places a small header at the front of each UDP packet;
+ this is already taken into account by the value returned).
+ */
+ inline int maxMessageSize() const {
+ return MTU - 4;
+ }
+
+
+ template<typename T> inline void send(const NetAddress& a, uint32 type, const T& msg) {
+ binaryOutput.reset();
+ serializeMessage(type, msg, binaryOutput);
+ sendBuffer(a, binaryOutput);
+ }
+
+ /** Send the same message to multiple addresses (only serializes once).
+ Useful when server needs to send to a known list of addresses
+ (unlike direct UDP broadcast to all addresses on the subnet) */
+ template<typename T> inline void send(const Array<NetAddress>& a, uint32 type, const T& m) {
+ binaryOutput.reset();
+ serializeMessage(type, m, binaryOutput);
+
+ for (int i = 0; i < a.size(); ++i) {
+ sendBuffer(a[i], binaryOutput);
+ }
+ }
+
+ bool receive(NetAddress& sender);
+
+ template<typename T> inline bool receive(NetAddress& sender, T& message) {
+ bool r = receive(sender);
+ if (r) {
+ BinaryInput b((messageBuffer.getCArray() + 4),
+ messageBuffer.size() - 4,
+ G3D_LITTLE_ENDIAN, BinaryInput::NO_COPY);
+ message.deserialize(b);
+ }
+
+ return r;
+ }
+
+ inline bool receive() {
+ static NetAddress ignore;
+ return receive(ignore);
+ }
+
+ virtual uint32 waitingMessageType();
+
+
+ virtual bool messageWaiting();
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef ReferenceCountedPointer<class NetListener> NetListenerRef;
+
+/**
+ Runs on the server listening for clients trying to make reliable connections.
+ */
+class NetListener : public ReferenceCountedObject {
+private:
+
+ friend class NetworkDevice;
+
+ SOCKET sock;
+
+ /** Port is in host byte order. */
+ NetListener(uint16 port);
+
+public:
+
+ static NetListenerRef create(const uint16 port);
+
+ ~NetListener();
+
+ /** Block until a connection is received. Returns NULL if
+ something went wrong. */
+ ReliableConduitRef waitForConnection();
+
+ /** True if a client is waiting (i.e. waitForConnection will
+ return immediately). */
+ bool clientWaiting() const;
+
+ bool ok() const;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ @brief Abstraction of network (socket) functionality.
+
+ An abstraction over sockets that provides a message-based network
+ infrastructure optimized for sending many small (~500 bytes) messages.
+ All functions always return immediately.
+
+ Create only one NetworkDevice per process (a WinSock restriction).
+
+ NetworkDevice is technically not thread safe. However, as long as
+ you use different conduits on different threads (or lock conduits
+ before sending), you will encounter no problems sharing the single
+ NetworkDevice across multiple threads. That is, do not invoke the same
+ Conduit's send or receive method on two threads at once.
+
+ This assumes that the underlying WinSock/BSD sockets implementation
+ is thread safe. That is not guaranteed, but in practice seems
+ to always be true (see
+ http://tangentsoft.net/wskfaq/intermediate.html#threadsafety)
+
+ <hr>
+
+ IP networks use "network byte order" (big-endian) for
+ communicating integers. "Host byte order" is the endian-ness of
+ the local machine (typically little-endian; see
+ System::endian). The C functions htonl() and ntohl() convert 32-bit
+ values between these formats. G3D only ever exposes host byte order,
+ so programmers rarely need to be aware of the distinction.
+
+ */
+class NetworkDevice {
+public:
+
+ /** @brief Description of an ethernet or wireless ethernet adapter.*/
+ class EthernetAdapter {
+ public:
+ /** Reverse-DNS of the ip address.*/
+ std::string hostname;
+
+ /** Name of the adapter */
+ std::string name;
+
+ /** IP address in host byte order.*/
+ uint32 ip;
+
+ /** Subnet mask in host byte order.*/
+ uint32 subnet;
+
+ /** UDP broadcast address in host byte order.*/
+ uint32 broadcast;
+
+ /** MAC (hardware) address, if known */
+ uint8 mac[6];
+
+ EthernetAdapter();
+
+ /** Produces a text description of this adapter */
+ void describe(TextOutput& t) const;
+ };
+
+private:
+
+ friend class Conduit;
+ friend class LightweightConduit;
+ friend class ReliableConduit;
+ friend class NetListener;
+
+ bool initialized;
+
+ Array<EthernetAdapter> m_adapterArray;
+
+ /** Broadcast addresses available on this machine,
+ extracted from m_adapterArray.*/
+ Array<uint32> m_broadcastAddresses;
+
+ /** Utility method. */
+ void closesocket(SOCKET& sock) const;
+
+ /** Utility method. Returns true on success.*/
+ bool bind(SOCKET sock, const NetAddress& addr) const;
+
+ /** The global instance */
+ static NetworkDevice* s_instance;
+
+ NetworkDevice();
+
+ bool init();
+
+ void _cleanup();
+
+ /** Called from init to update m_adapterArray and
+ m_broadcastAddresses. */
+ void addAdapter(const EthernetAdapter& a);
+
+public:
+
+ /** Prints an IP address to a string.
+ @param ip In host byte order.*/
+ static std::string formatIP(uint32 ip);
+
+ /** Prints a MAC address to a string. */
+ static std::string formatMAC(const uint8 mac[6]);
+
+ ~NetworkDevice();
+
+ /** Returns the available ethernet adapters for the current
+ machine that are online. Does not include the loopback adapter
+ for localhost.*/
+ inline const Array<EthernetAdapter>& adapterArray() const {
+ return m_adapterArray;
+ }
+
+ /** Returns the (unique) IP addresses for UDP broadcasting
+ extracted from adapterArray(). All are in host byte order. */
+ inline const Array<uint32>& broadcastAddressArray() const {
+ return m_broadcastAddresses;
+ }
+
+ /**
+ Returns NULL if there was a problem initializing the network.
+ */
+ static NetworkDevice* instance();
+
+ /**
+ Shuts down the network device (destroying the global instance).
+ */
+ static void cleanup();
+
+ /**
+ Prints a human-readable description of this machine
+ to the text output stream.
+ */
+ void describeSystem(
+ TextOutput& t);
+
+ void describeSystem(
+ std::string& s);
+
+ /** Returns the name (or one of the names) of this computer */
+ std::string localHostName() const;
+
+ /** There is often more than one address for the local host. This
+ returns all of them.
+ @deprecated Use adapterArray()
+ */
+ void localHostAddresses(Array<NetAddress>& array) const;
+};
+
+
+#ifdef __GNUC__
+inline uint32 gcchtonl(uint32 x) {
+ // This pragma fools gcc into surpressing all error messages,
+ // including the bogus one that it creates for htonl
+# pragma GCC system_header
+ return htonl(x);
+}
+#endif
+
+} // G3D namespace
+
+#ifndef _WIN32
+#undef SOCKADDR_IN
+#undef SOCKET
+#endif
+
+#endif
diff --git a/dep/include/g3dlite/G3D/ParseError.h b/dep/include/g3dlite/G3D/ParseError.h
new file mode 100644
index 00000000000..f02948e3d29
--- /dev/null
+++ b/dep/include/g3dlite/G3D/ParseError.h
@@ -0,0 +1,59 @@
+/**
+ @file ParseError.h
+
+ @maintainer Morgan McGuire
+
+ @created 2009-11-15
+ @edited 2009-11-15
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_ParseError_h
+#define G3D_ParseError_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include <string>
+
+namespace G3D {
+
+/** Thrown by TextInput, Any, and other parsers on unexpected input. */
+class ParseError {
+public:
+ enum {UNKNOWN = -1};
+
+ /** Empty means unknown */
+ std::string filename;
+
+ /** For a binary file, the location of the parse error. -1 if unknown.*/
+ int64 byte;
+
+ /** For a text file, the line number is the line number of start of token which caused the exception. 1 is
+ the first line of the file. -1 means unknown. Note that you can use
+ TextInput::Settings::startingLineNumberOffset to shift the effective line
+ number that is reported by that class.
+ */
+ int line;
+
+ /** Character number (in the line) of the start of the token which caused the
+ exception. 1 is the character in the line. May be -1 if unknown.
+ */
+ int character;
+
+ std::string message;
+
+ ParseError() : byte(UNKNOWN), line(UNKNOWN), character(UNKNOWN) {}
+
+ virtual ~ParseError() {}
+
+ ParseError(const std::string& f, int l, int c, const std::string& m) :
+ filename (f), byte(UNKNOWN), line(l), character(c), message(m) {}
+
+ ParseError(const std::string& f, int64 b, const std::string& m) :
+ filename (f), byte(b), line(UNKNOWN), character(UNKNOWN), message(m) {}
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/PhysicsFrame.h b/dep/include/g3dlite/G3D/PhysicsFrame.h
new file mode 100644
index 00000000000..a5a9305b83e
--- /dev/null
+++ b/dep/include/g3dlite/G3D/PhysicsFrame.h
@@ -0,0 +1,74 @@
+/**
+ @file PhysicsFrame.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2002-07-08
+ @edited 2006-01-10
+*/
+
+#ifndef G3D_PHYSICSFRAME_H
+#define G3D_PHYSICSFRAME_H
+
+#include "G3D/platform.h"
+#include "G3D/Vector3.h"
+#include "G3D/Matrix3.h"
+#include "G3D/Quat.h"
+#include "G3D/CoordinateFrame.h"
+#include <math.h>
+#include <string>
+
+
+namespace G3D {
+
+/**
+ An RT transformation using a quaternion; suitable for
+ physics integration.
+
+ This interface is in "Beta" and will change in the next release.
+ */
+class PhysicsFrame {
+public:
+
+ Quat rotation;
+
+ /**
+ Takes object space points to world space.
+ */
+ Vector3 translation;
+
+ /**
+ Initializes to the identity frame.
+ */
+ PhysicsFrame();
+
+ /**
+ Purely translational force
+ */
+ PhysicsFrame(const Vector3& translation) : translation(translation) {}
+
+ PhysicsFrame(const CoordinateFrame& coordinateFrame);
+
+ /** Compose: create the transformation that is <I>other</I> followed by <I>this</I>.*/
+ PhysicsFrame operator*(const PhysicsFrame& other) const;
+
+ virtual ~PhysicsFrame() {}
+
+ CoordinateFrame toCoordinateFrame() const;
+
+ /**
+ Linear interpolation (spherical linear for the rotations).
+ */
+ PhysicsFrame lerp(
+ const PhysicsFrame& other,
+ float alpha) const;
+
+ void deserialize(class BinaryInput& b);
+
+ void serialize(class BinaryOutput& b) const;
+
+};
+
+} // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Plane.h b/dep/include/g3dlite/G3D/Plane.h
index c7043e23c42..360bcd2bc75 100644
--- a/dep/include/g3dlite/G3D/Plane.h
+++ b/dep/include/g3dlite/G3D/Plane.h
@@ -3,7 +3,7 @@
Plane class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
@edited 2004-07-18
@@ -15,6 +15,7 @@
#include "G3D/platform.h"
#include "G3D/Vector3.h"
#include "G3D/Vector4.h"
+#include "G3D/debugAssert.h"
namespace G3D {
@@ -25,8 +26,8 @@ class Plane {
private:
/** normal.Dot(x,y,z) = distance */
- Vector3 _normal;
- float _distance;
+ Vector3 _normal;
+ float _distance;
/**
Assumes the normal has unit length.
@@ -65,10 +66,14 @@ public:
static Plane fromEquation(float a, float b, float c, float d);
+ Plane(class BinaryInput& b);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
virtual ~Plane() {}
/**
- Returns true if point is on the side the normal points to or
+ Returns true if point is on the side the normal points to or
is in the plane.
*/
inline bool halfSpaceContains(Vector3 point) const {
@@ -81,7 +86,7 @@ public:
}
/**
- Returns true if point is on the side the normal points to or
+ Returns true if point is on the side the normal points to or
is in the plane.
*/
inline bool halfSpaceContains(const Vector4& point) const {
@@ -93,7 +98,7 @@ public:
}
/**
- Returns true if point is on the side the normal points to or
+ Returns true if point is on the side the normal points to or
is in the plane. Only call on finite points. Faster than halfSpaceContains.
*/
inline bool halfSpaceContainsFinite(const Vector3& point) const {
@@ -108,9 +113,9 @@ public:
return fuzzyEq(point.dot(_normal), _distance);
}
- inline const Vector3& normal() const {
- return _normal;
- }
+ inline const Vector3& normal() const {
+ return _normal;
+ }
/**
Returns distance from point to plane. Distance is negative if point is behind (not in plane in direction opposite normal) the plane.
@@ -154,4 +159,3 @@ public:
} // namespace
#endif
-
diff --git a/dep/include/g3dlite/G3D/PointHashGrid.h b/dep/include/g3dlite/G3D/PointHashGrid.h
new file mode 100644
index 00000000000..0db9e677321
--- /dev/null
+++ b/dep/include/g3dlite/G3D/PointHashGrid.h
@@ -0,0 +1,917 @@
+/**
+ @file PointHashGrid.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2008-07-01
+ @edited 2009-05-28
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+*/
+#ifndef G3D_PointHashGrid_h
+#define G3D_PointHashGrid_h
+
+#include "G3D/platform.h"
+#include "G3D/EqualsTrait.h"
+#include "G3D/HashTrait.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector3int32.h"
+#include "G3D/Array.h"
+#include "G3D/Table.h"
+#include "G3D/AABox.h"
+#include "G3D/Sphere.h"
+#include "G3D/SmallArray.h"
+
+namespace G3D {
+
+/**
+ Storage of data in a sparse 3D grid of point-based data. The
+ space cost for <I>n</I> elements is O(<I>n</I>). For data with
+ approximately uniform density (with respect to the radius hint),
+ the time cost of searching for neighbors is O(1).
+
+ <i>Value</i> must be supported by a G3D::PositionTrait,
+ G3D::EqualsTrait, and G3D::HashFunc. overrides are provided for
+ common G3D classes like G3D::Vector3.
+*/
+template<class Value,
+ class PosFunc = PositionTrait<Value>,
+ class EqualsFunc = EqualsTrait<Value>,
+ class HashFunc = HashTrait<Vector3int32> >
+class PointHashGrid {
+private:
+
+#define ThisType PointHashGrid<Value, PosFunc, EqualsFunc, HashFunc>
+
+ /** A value annotated with precomputed position and hash code.*/
+ class Entry {
+ public:
+ Vector3 position;
+ Value value;
+ };
+
+ /** One cell of the grid. */
+ typedef Array<Entry> Cell;
+ typedef Table<Vector3int32, Cell, HashFunc> CellTable;
+
+ /** The cube of +/-1 along each dimension. Initialized by initOffsetArray.*/
+ Vector3int32 m_offsetArray[3*3*3];
+
+ /** Incremented every time the data structure is mutated.
+ Used by the iterators to determine if the data structure
+ has changed since iteration began. */
+ int m_epoch;
+
+ /** Extent of a cell along one dimension. */
+ float m_cellWidth;
+
+ /** 1.0 / cell width */
+ float m_invCellWidth;
+
+ /** Conservative bounds; the actual data may be smaller. */
+ AABox m_bounds;
+
+ /** Number of elements. */
+ int m_size;
+
+ /** Non-empty cells indexed by grid position. Actual 3D position is
+ <code>position * m_cellWidth</code>*/
+ CellTable m_data;
+
+ MemoryManager::Ref m_memoryManager;
+
+ /** Intentionally unimplemented: prevent copy construction. */
+ PointHashGrid(const ThisType&);
+
+
+ /** Intentionally unimplemented: prevent assignment. */
+ PointHashGrid& operator=(const ThisType&);
+
+
+ /** Locate the cell and index within that cell containing v. Called by
+ remove() and contains(). */
+ bool find(const Value& v,
+ Vector3int32& foundCellCoord,
+ Cell*& foundCell,
+ int& index) {
+
+ Vector3 pos;
+ PosFunc::getPosition(v, pos);
+
+ Vector3int32 cellCoord;
+ getCellCoord(pos, cellCoord);
+ for (int i = 0; i < 27; ++i) {
+ Vector3int32 c = cellCoord + m_offsetArray[i];
+ Cell* cell = m_data.getPointer(c);
+ if (cell != NULL) {
+ // The cell exists
+ for (int j = 0; j < cell->size(); ++j) {
+ if (EqualsFunc::equals((*cell)[j].value, v)) {
+ foundCell = cell;
+ index = j;
+ foundCellCoord = c;
+ return true;
+ }
+ }
+ }
+ }
+
+ // Not found
+ return false;
+ }
+
+ /** Given a real-space position, returns the cell coord
+ containing it.*/
+ inline void getCellCoord(const Vector3& pos, Vector3int32& cellCoord) const {
+ for (int a = 0; a < 3; ++a) {
+ cellCoord[a] = iFloor(pos[a] * m_invCellWidth);
+ }
+ }
+
+ /** Initializes m_offsetArray. */
+ void initOffsetArray() {
+ int i = 0;
+ Vector3int32 d;
+ for (d.x = -1; d.x <= +1; ++d.x) {
+ for (d.y = -1; d.y <= +1; ++d.y) {
+ for (d.z = -1; d.z <= +1; ++d.z) {
+ m_offsetArray[i] = d;
+ ++i;
+ }
+ }
+ }
+
+ // Put (0, 0, 0) first, so that contains() is most likely to find
+ // the value quickly.
+ i = (1 * 3 + 1) * 3 + 1;
+ debugAssert(m_offsetArray[i] == Vector3int32(0,0,0));
+ Vector3int32 temp = m_offsetArray[0];
+ m_offsetArray[0] = m_offsetArray[i];
+ m_offsetArray[i] = temp;
+ }
+
+public:
+
+ /**
+ @param radiusHint the radius that will typically be used with
+ beginSphereIntersection and beginBoxIntersection. If two <i>Value</i>s are equal,
+ their positions must be within this radius as well.
+ */
+ PointHashGrid(float radiusHint, const MemoryManager::Ref& m = MemoryManager::create()) : m_size(0), m_memoryManager(m) {
+ initOffsetArray();
+ m_data.clearAndSetMemoryManager(m_memoryManager);
+
+ debugAssertM(radiusHint > 0, "Cell radius must be positive");
+ m_cellWidth = radiusHint;
+ m_invCellWidth = 1.0f / m_cellWidth;
+ }
+
+ /**
+ If radiusHint is negative, it is automatically chosen to put
+ about 5 values in each grid cell (which means about 27 * 5
+ values for each beginIntersection call).
+ */
+ PointHashGrid(const Array<Value>& init, float radiusHint = -1.0f, const MemoryManager::Ref& m = MemoryManager::create()) : m_size(0), m_memoryManager(m) {
+ initOffsetArray();
+ m_data.clearAndSetMemoryManager(m_memoryManager);
+
+ Vector3 lo(Vector3::inf());
+ Vector3 hi(-lo);
+
+ // Compute bounds
+ Array<Entry> entry(init.size());
+ for (int i = 0; i < entry.size(); ++i) {
+ const Value& value = init[i];
+ Vector3 pos = m_posFunc(value);
+
+ entry[i].value = value;
+ entry[i].hashCode = m_hashFunc(value);
+ entry[i].position = pos;
+
+ lo = lo.min(pos);
+ hi = hi.max(pos);
+ }
+
+ m_bounds = AABox(lo, hi);
+
+ if (radiusHint <= 0) {
+ // Compute a good cell width based on the bounds.
+ //
+ // N numPerCell
+ // ----- = ---------
+ // volume r^3
+
+ float numPerCell = 5;
+ radiusHint =
+ (float)pow(numPerCell * m_bounds.volume() / init.size(), 1.0 / 3.0);
+
+ if (radiusHint == 0) {
+ // Volume must have been zero because all points were colocated.
+ radiusHint = 0.1f;
+ }
+ }
+
+ insert(init);
+ }
+
+ /** Returns the number of elements. */
+ inline int size() const {
+ return m_size;
+ }
+
+ /** Returns a conservative bounding box around the contents. This is
+ conservative because it is not updated when elements are removed. */
+ const AABox& conservativeBoxBounds() const {
+ return m_bounds;
+ }
+
+ /** Insert @a v at position @a p given by <code>getPosition(v, p)</code>.
+ Multiple elements that are equal may be inserted; all copies will be
+ in the data structure. */
+ void insert(const Value& v) {
+ Vector3 pos;
+ PosFunc::getPosition(v, pos);
+ Vector3int32 cellCoord;
+ getCellCoord(pos, cellCoord);
+
+ // See if the cell already exists
+ Cell& cell = m_data.getCreate(cellCoord);
+
+ if (cell.size() == 0) {
+ // Use the same memory manager as for the whole class
+ cell.clearAndSetMemoryManager(m_memoryManager);
+ }
+
+ Entry& entry = cell.next();
+ entry.value = v;
+ entry.position = pos;
+
+ // Update the bounds
+ if (size() == 0) {
+ m_bounds = AABox(pos);
+ } else {
+ m_bounds.merge(pos);
+ }
+
+ ++m_size;
+ ++m_epoch;
+ }
+
+
+ /** Inserts all elements of the array. */
+ void insert(const Array<Value>& v) {
+ for (int i = 0; i < v.size(); ++i) {
+ insert(v[i]);
+ }
+ }
+
+
+ /** If there are multiple copies of an element, you must
+ delete them multiple times.
+
+ @param shrinkIfNecessary If <b>true</b>, deallocate underlying data
+ structures as they are emptied. False increases performace at
+ the cost of memory overhead for dynamic structures.
+
+ @return true if the element was found.
+ */
+ bool remove(const Value& v, bool shrinkIfNecessary = true) {
+ Cell* cell = NULL;
+ int index = 0;
+ Vector3int32 cellCoord;
+
+ if (find(v, cellCoord, cell, index)) {
+ cell->fastRemove(index, shrinkIfNecessary);
+ --m_size;
+ ++m_epoch;
+
+ if ((cell->size() == 0) && shrinkIfNecessary) {
+ // Remove the cell itself
+
+ // Drop our pointer, which is about to dangle
+ cell = NULL;
+ bool success = m_data.remove(cellCoord);
+ debugAssertM(success, "Data structure corrupt: "
+ "tried to remove a cell that doesn't exist.");
+ }
+
+ return true;
+
+ } else {
+ return false;
+ }
+ }
+
+ /** Removes all elements of @v. */
+ void remove(const Array<Value>& v, bool shrink = true) {
+ for (int i = 0; i < v.size(); ++i) {
+ remove(v[i], shrink);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ class Iterator {
+ private:
+ friend class ThisType;
+
+ bool m_isEnd;
+
+ const ThisType* m_grid;
+
+ typename CellTable::Iterator m_tableIterator;
+
+ /** Index within m_tableIterator->value of the current value. */
+ int m_arrayIndex;
+
+ const int m_epoch;
+
+ /** End iterator. Note that the m_tableIterator is initialized to the end iterator
+ of a temporary value! This is ok because we'll never look at the value of the
+ m_tableIterator, since we're initializing the "end" Iterator.*/
+ Iterator() : m_isEnd(true), m_grid(NULL), m_tableIterator(CellTable().end()),
+ m_arrayIndex(0), m_epoch(0) {}
+
+ Iterator(const ThisType* grid) :
+ m_isEnd(false),
+ m_grid(grid),
+ m_tableIterator( grid->m_data.begin() ),
+ m_arrayIndex(0),
+ m_epoch(grid->m_epoch) { }
+
+ private:
+
+ const Value& value() const {
+ debugAssert(! m_isEnd);
+ debugAssertM(m_tableIterator->value.size() > m_arrayIndex,
+ "No more elements");
+ return m_tableIterator->value[m_arrayIndex].value;
+ }
+
+ public:
+
+ inline bool operator!=(const Iterator& other) const {
+ if (other.m_isEnd && m_isEnd) {
+ return false;
+ } else {
+ return (m_isEnd != other.m_isEnd) ||
+ (m_tableIterator != other.m_tableIterator) ||
+ (m_arrayIndex != other.m_arrayIndex);
+ }
+ }
+
+ bool operator==(const Iterator& other) const {
+ return !(*this != other);
+ }
+
+ /** Preincrement */
+ Iterator& operator++() {
+ debugAssert(! m_isEnd);
+ debugAssertM(m_epoch == m_grid->m_epoch,
+ "It is illegal to mutate the HashGrid "
+ "while iterating through it.");
+
+ ++m_arrayIndex;
+
+ if (m_arrayIndex >= m_tableIterator->value.size()) {
+ // Move on to the next cell
+ ++m_tableIterator;
+ m_arrayIndex = 0;
+
+ // Check to see if we're at the end
+ m_isEnd = (m_tableIterator == m_grid->m_data.end());
+ }
+
+ return *this;
+ }
+
+ /** Post increment (slower) */
+ Iterator operator++(int) {
+ debugAssert(! m_isEnd);
+ Iterator old = *this;
+ ++(*this);
+ return old;
+ }
+
+ const Value& operator*() const { return value(); }
+ const Value* operator->() const { return &value(); }
+ operator Value*() const { return &value(); }
+ }; // Iterator
+
+
+ /** Iterate through all members. It is an error to mutate the HashGrid
+ while iterating through it. Each member can be accessed by "dereferencing"
+ the iterator:
+
+ <pre>
+ for (Grid::Iterator i = grid.begin(); i != grid.end(), ++i) {
+ const Value& = *i;
+ ...
+ }
+ </pre>
+ */
+ Iterator begin() const {
+ return Iterator(this);
+ }
+
+ const Iterator& end() const {
+ static const Iterator it;
+ return it;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Forward declaration required by older gcc versions for friend declaration in BoxIterator
+ class SphereIterator;
+ class BoxIterator {
+ private:
+ friend class ThisType;
+ friend class SphereIterator;
+
+ bool m_isEnd;
+
+ const ThisType* m_grid;
+
+ /** Lower bound on the boxes covered, inclusive. */
+ Vector3int32 m_lo;
+
+ /** Upper bound on the boxes covered, inclusive.*/
+ Vector3int32 m_hi;
+
+ /** If true, test values against m_box before returning them.*/
+ bool m_exact;
+
+ /** The underlying box in 3D space */
+ AABox m_box;
+
+ /** The iterator winds through the 3D grid between m_lo and (m_lo + m_extent) in
+ Z,Y,X-major order. This is the index keeping track of how
+ far it has come */
+ Vector3int32 m_current;
+
+ /** The current cell. */
+ Cell* m_cell;
+
+ /** Index within m_cell of the current value */
+ int m_arrayIndex;
+
+ const int m_epoch;
+
+
+ /** Called from advance() */
+ void advanceCell() {
+ do {
+ ++m_current.x;
+ if (m_current.x > m_hi.x) {
+ m_current.x = m_lo.x;
+ ++m_current.y;
+ if (m_current.y > m_hi.y) {
+ m_current.y = m_lo.y;
+ ++m_current.z;
+ if (m_current.z > m_hi.z) {
+ m_isEnd = true;
+ return;
+ }
+ }
+ }
+
+ // Pick up the new cell
+ m_cell = m_grid->m_data.getPointer(m_current);
+ // Keep advancing if the cell does not exist
+ } while ((m_cell == NULL) || (m_cell->size() == 0));
+ }
+
+ /** Advance to the next value */
+ void advance() {
+ debugAssert(! m_isEnd);
+
+ do {
+ ++m_arrayIndex;
+ bool inConstructor = (m_cell == NULL);
+ if (inConstructor || m_arrayIndex >= m_cell->size()) {
+ advanceCell();
+ m_arrayIndex = 0;
+
+ if (m_isEnd) {
+ // Ran out of values
+ return;
+ }
+ debugAssert(m_cell != NULL);
+ }
+
+ // Advance until we have a value that can be returned, either
+ // because we don't care about exactness or because it is
+ // guaranteed to be within the box.
+ } while (m_exact && ! m_box.contains(position()));
+ }
+
+
+ /** End iterator */
+ BoxIterator() : m_isEnd(true), m_grid(NULL), m_exact(true), m_current(0,0,0), m_cell(NULL), m_arrayIndex(0), m_epoch(0) {}
+
+ /** Begin iterator */
+ BoxIterator(const ThisType* grid, bool exact, const AABox& box) :
+ m_isEnd(false),
+ m_grid(grid),
+ m_exact(exact),
+ m_box(box),
+ m_current(-1, 0 ,0),
+ m_cell(NULL),
+ m_arrayIndex(0),
+ m_epoch(grid->m_epoch) {
+
+ m_grid->getCellCoord(box.low(), m_lo);
+ m_grid->getCellCoord(box.high(), m_hi);
+
+ // Get to the first value
+ m_current = m_lo;
+ // Back up one so that advancing takes us to the first
+ --m_current.x;
+ advance();
+ }
+
+ const Value& value() const {
+ debugAssert(! m_isEnd);
+ return (*m_cell)[m_arrayIndex].value;
+ }
+
+ /** Used by SphereIterator::advance() */
+ const Vector3& position() const {
+ debugAssert(! m_isEnd);
+ return (*m_cell)[m_arrayIndex].position;
+ }
+
+ // Intentionally unimplemented
+ BoxIterator& operator=(const BoxIterator&);
+
+ public:
+
+ inline bool operator!=(const BoxIterator& other) const {
+ if (other.m_isEnd && m_isEnd) {
+ return false;
+ } else {
+ return (m_isEnd != other.m_isEnd) ||
+ (m_cell != other.m_cell) ||
+ (m_arrayIndex != other.m_arrayIndex);
+ }
+ }
+
+ bool operator==(const BoxIterator& other) const {
+ return !(*this != other);
+ }
+
+ /** Preincrement */
+ BoxIterator& operator++() {
+ debugAssert(! m_isEnd);
+ debugAssertM(m_epoch == m_grid->m_epoch,
+ "It is illegal to mutate the HashGrid "
+ "while iterating through it.");
+
+ advance();
+
+ return *this;
+ }
+
+ /** Post increment (slower) */
+ BoxIterator operator++(int) {
+ Iterator old = *this;
+ ++(*this);
+ return old;
+ }
+
+ const Value& operator*() const { return value(); }
+ const Value* operator->() const { return &value(); }
+ operator Value*() const { return &value(); }
+
+ bool hasMore() const {
+ return ! m_isEnd;
+ }
+ }; // BoxIterator
+
+ /**
+ Finds all values whose positions are within @a box. It is an error to
+ mutate the PointHashGrid while iterating through it.
+
+ @param exact If false, the iterator will execute more quickly but will likely return some
+ values that lie outside the box. Set exact = false if you are going to test the
+ results against the yourself box anyway.
+ */
+ BoxIterator beginBoxIntersection(const AABox& box, bool exact = true) const {
+ return BoxIterator(this, exact, box);
+ }
+
+ const BoxIterator& endBoxIntersection() const {
+ static const BoxIterator it;
+ return it;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ class SphereIterator {
+ private:
+
+ friend class ThisType;
+
+ bool m_isEnd;
+ Sphere m_sphere;
+ BoxIterator m_boxIterator;
+
+ SphereIterator() : m_isEnd(true) {}
+
+ void advance() {
+ if (! m_boxIterator.hasMore()) {
+ m_isEnd = true;
+ return;
+ }
+
+ while (! m_sphere.contains(m_boxIterator.position())) {
+ ++m_boxIterator;
+
+ if (! m_boxIterator.hasMore()) {
+ m_isEnd = true;
+ return;
+ }
+ }
+ }
+
+ static AABox getBoundingBox(const Sphere& s) {
+ AABox box;
+ s.getBounds(box);
+ return box;
+ }
+
+ SphereIterator(const ThisType* grid, const Sphere& sphere) :
+ m_isEnd(false),
+ m_sphere(sphere),
+ m_boxIterator(grid, false, getBoundingBox(sphere)) {
+
+ // Find the first element that is actually in the sphere,
+ // not just the box.
+ advance();
+ }
+
+ const Value& value() const {
+ return *m_boxIterator;
+ }
+
+ // TODO: if the sphere is very big compared to radius, check each
+ // cell's box to see if the cell itself is actually inside the sphere
+ // before iterating through it, since there may be many boxes outside the sphere.
+
+ // Intentionally unimplemented
+ SphereIterator& operator=(const SphereIterator&);
+ public:
+
+ inline bool operator!=(const SphereIterator& other) const {
+ if (other.m_isEnd && m_isEnd) {
+ return false;
+ } else {
+ return
+ (m_isEnd != other.m_isEnd) ||
+ (m_sphere != other.m_sphere) ||
+ (m_boxIterator != other.m_boxIterator);
+ }
+ }
+
+ bool operator==(const SphereIterator& other) const {
+ return !(*this != other);
+ }
+
+
+
+ /** Preincrement */
+ SphereIterator& operator++() {
+ debugAssert(! m_isEnd);
+
+ ++m_boxIterator;
+ advance();
+
+ return *this;
+ }
+
+ /** Post increment (slower) */
+ SphereIterator operator++(int) {
+ Iterator old = *this;
+ ++(*this);
+ return old;
+ }
+
+ const Value& operator*() const { return value(); }
+ const Value* operator->() const { return &value(); }
+ operator Value*() const { return &value(); }
+
+ bool hasMore() const {
+ return ! m_isEnd;
+ }
+ }; // SphereIterator
+
+ /**
+ Finds all values whose positions are within @a sphere. It is an error
+ to mutate the HashGrid while iterating through it.
+ */
+ SphereIterator beginSphereIntersection(const Sphere& sphere) const {
+ return SphereIterator(this, sphere);
+ }
+
+ const SphereIterator& endSphereIntersection() const {
+ static const SphereIterator it;
+ return it;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ Dereference to access the bounds() and size() [element count] of the underlying
+ cell objet.
+
+ Example:
+ <pre>
+ for(PointHashGrid<Vector3>::CellIterator iter = grid.beginCells(); iter != grid.endCells(); ++iter) {
+ entriesFound += iter->size();
+ }
+ </pre>
+ */
+ class CellIterator {
+ private:
+ friend class ThisType;
+
+ bool m_isEnd;
+ const ThisType* m_grid;
+ typename CellTable::Iterator m_tableIterator;
+ const int m_epoch;
+
+
+ Cell& cell() {
+ return m_tableIterator->value;
+ }
+
+ public:
+
+ class CellObject {
+ friend class CellIterator;
+ private:
+ const CellIterator* m_parent;
+
+ CellObject() : m_parent(NULL) {}
+
+ public:
+
+ /** Returns the bounds on this cell */
+ AABox bounds() const {
+ const Vector3int32& k = m_parent->m_tableIterator->key;
+ return AABox(Vector3(k) * m_parent->m_cellWidth,
+ Vector3(k + Vector3int32(1, 1, 1)) * m_parent->m_cellWidth);
+ }
+
+ /** Number of elements inside this cell */
+ int size() const {
+ debugAssert(! m_parent->m_isEnd);
+ return m_parent->m_tableIterator->value.size();
+ }
+ };
+
+ private:
+ /** Used to make the indirection work.*/
+ CellObject m_indirection;
+
+ /** End iterator. Note that the m_tableIterator is initialized to the end iterator
+ of a temporary value! This is ok because we'll never look at the value of the
+ m_tableIterator, since we're initializing the "end" Iterator.*/
+ CellIterator() :
+ m_isEnd(true),
+ m_grid(NULL),
+ m_tableIterator( CellTable().end() ),
+ m_epoch(0) {}
+
+ CellIterator(const ThisType* grid) :
+ m_isEnd(false),
+ m_grid(grid),
+ m_tableIterator( grid->m_data.begin()),
+ m_epoch(grid->m_epoch) {
+ m_indirection.m_parent = this;
+ m_isEnd = ! m_tableIterator.hasMore();
+ }
+
+ // Intentionally unimplemented
+ CellIterator& operator=(const CellIterator&);
+
+ public:
+
+ const CellObject& operator*() const { return m_indirection; }
+ const CellObject* operator->() const { return &m_indirection; }
+ operator CellObject*() const { return &m_indirection; }
+
+ inline bool operator!=(const CellIterator& other) const {
+ // != is called more often than == during iteration
+ return !(
+ (m_isEnd && other.m_isEnd) ||
+ ((m_isEnd == other.m_isEnd) &&
+ (m_tableIterator != other.m_tableIterator)));
+ }
+
+ bool operator==(const CellIterator& other) const {
+ return !(*this != other);
+ }
+
+ /** Preincrement */
+ CellIterator& operator++() {
+ debugAssertM(m_epoch == m_grid->m_epoch,
+ "It is illegal to mutate the HashGrid while "
+ "iterating through it.");
+ ++m_tableIterator;
+ m_isEnd = ! m_tableIterator.hasMore();
+ return *this;
+ }
+
+ /** Post increment (slower) */
+ CellIterator operator++(int) {
+ Iterator old = *this;
+ ++(*this);
+ return old;
+ }
+
+ bool hasMore() const {
+ return ! m_isEnd;
+ }
+ }; // CellIterator
+
+ /** Iterates through the non-empty cells. This is intended primarily for
+ debugging and visualizing the data structure.*/
+ CellIterator beginCells() const {
+ return CellIterator(this);
+ }
+
+ const CellIterator& endCells() const {
+ static const CellIterator it;
+ return it;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** Returns true if there is a value that is exactly equal to @a v. This will
+ check all neighboring cells to avoid roundoff error at cell boundaries.
+ */
+ bool contains(const Value& v) const {
+ Cell* cell = NULL;
+ int index = 0;
+ Vector3int32 cellCoord;
+ return const_cast<ThisType*>(this)->find(v, cellCoord, cell, index);
+ }
+
+ /** Calls delete on all of the values, which are assumed to be pointers.
+ This is a helper to avoid requiring you to iterate through the data
+ structure, removing and deleting each one. Clears the PointHashGrid at the
+ end.
+
+ Using objects (instead of pointers) or reference counted pointers is
+ recommended over using pointers and this deleteAll method.*/
+ void deleteAll() {
+ for (Iterator it = begin(); it.hasMore(); ++it) {
+ delete *it;
+ }
+ clear();
+ }
+
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ ++m_epoch;
+ m_size = 0;
+ m_bounds = AABox();
+
+ m_data.clearAndSetMemoryManager(m);
+ m_memoryManager = m;
+ }
+
+ /** Removes all data.
+ @param shrink If true, underlying structures are deallocated as
+ they are freed.*/
+ void clear(bool shrink = true) {
+ m_size = 0;
+ m_bounds = AABox();
+ if (! shrink) {
+ // Remove all data
+ for (CellIterator it = beginCells(); it.hasMore(); ++it) {
+ it.cell().clear(true);
+ }
+ } else {
+ m_data.clear();
+ }
+ ++m_epoch;
+ }
+
+ int debugGetDeepestBucketSize() const {
+ return m_data.debugGetDeepestBucketSize();
+ }
+
+ float debugGetAverageBucketSize() const {
+ return m_data.debugGetAverageBucketSize();
+ }
+#undef ThisType
+};
+
+} // G3D
+#endif
diff --git a/dep/include/g3dlite/G3D/PointKDTree.h b/dep/include/g3dlite/G3D/PointKDTree.h
new file mode 100644
index 00000000000..151cbd5f2f3
--- /dev/null
+++ b/dep/include/g3dlite/G3D/PointKDTree.h
@@ -0,0 +1,1185 @@
+/**
+ @file PointKDTree.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2004-01-11
+ @edited 2008-11-02
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+
+ */
+
+#ifndef X_PointKDTree_H
+#define X_PointKDTree_H
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Table.h"
+#include "G3D/Vector2.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector4.h"
+#include "G3D/AABox.h"
+#include "G3D/Sphere.h"
+#include "G3D/Box.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/CollisionDetection.h"
+#include "G3D/GCamera.h"
+#include "G3D/PositionTrait.h"
+#include <algorithm>
+
+namespace G3D {
+
+/**
+ A set data structure that supports spatial queries using an axis-aligned
+ BSP tree for speed.
+
+ PointKDTree allows you to quickly find points in 3D that lie within
+ a box or sphere. For large sets of objects it is much faster
+ than testing each object for a collision. See also G3D::KDTree; this class
+ is optimized for point sets, e.g.,for use in photon mapping and mesh processing.
+
+ <B>Template Parameters</B>
+
+ <br>
+
+ <br>The template parameter <I>T</I> must be one for which
+ the following functions are overloaded:
+
+ <pre>
+ T::T(); <I>(public constructor of no arguments)</I>
+
+ template<> struct PositionTrait<class T> {
+ static void getPosition(const T& v, G3D::Vector3& p);};
+
+ template <> struct HashTrait<class T> {
+ static size_t hashCode(const T& key);};
+
+ template<> struct EqualsTrait<class T> {
+ static bool equals(const T& a, const T& b); };
+ </pre>
+
+ <p>
+
+ G3D provides these for the Vector2, Vector3, and Vector4 classes.
+ If you use a custom class, or a pointer to a custom class, you will need
+ to define those functions.
+
+ <B>Moving %Set Members</B>
+ <DT>It is important that objects do not move without updating the
+ PointKDTree. If the position of an object is about
+ to change, PointKDTree::remove it before they change and
+ PointKDTree::insert it again afterward. For objects
+ where the hashCode and == operator are invariant with respect
+ to the 3D position,
+ you can use the PointKDTree::update method as a shortcut to
+ insert/remove an object in one step after it has moved.
+
+
+ Note: Do not mutate any value once it has been inserted into PointKDTree. Values
+ are copied interally. All PointKDTree iterators convert to pointers to constant
+ values to reinforce this.
+
+ If you want to mutate the objects you intend to store in a PointKDTree
+ simply insert <I>pointers</I> to your objects instead of the objects
+ themselves, and ensure that the above operations are defined. (And
+ actually, because values are copied, if your values are large you may
+ want to insert pointers anyway, to save space and make the balance
+ operation faster.)
+
+ <B>Dimensions</B>
+ Although designed as a 3D-data structure, you can use the PointKDTree
+ for data distributed along 2 or 1 axes by simply returning bounds
+ that are always zero along one or more dimensions.
+
+*/
+template<class T,
+ class PositionFunc = PositionTrait<T>,
+ class HashFunc = HashTrait<T>,
+ class EqualsFunc = EqualsTrait<T> >
+class PointKDTree {
+protected:
+#define TreeType PointKDTree<T, PositionFunc, HashFunc, EqualsFunc>
+
+ // Unlike the KDTree, the PointKDTree assumes that T elements are
+ // small and keeps the handle and cached position together instead of
+ // placing them in separate bounds arrays. Also note that a copy of T
+ // is kept in the member table and that there is no indirection.
+ class Handle {
+ private:
+ Vector3 m_position;
+
+ public:
+ T value;
+
+ inline Handle() {}
+ inline Handle(const T& v) : value(v) {
+ PositionFunc::getPosition(v, m_position);
+ }
+
+ /** Used by makeNode to create fake handles for partitioning. */
+ void setPosition(const Vector3& v) {
+ m_position = v;
+ }
+
+ inline const Vector3& position() const {
+ return m_position;
+ }
+ };
+
+ /** Returns the bounds of the sub array. Used by makeNode. */
+ static AABox computeBounds(
+ const Array<Handle>& point) {
+
+ if (point.size() == 0) {
+ return AABox(Vector3::inf(), Vector3::inf());
+ }
+
+ AABox bounds(point[0].position());
+
+ for (int p = 0; p < point.size(); ++p) {
+ bounds.merge(point[p].position());
+ }
+
+ return bounds;
+ }
+
+ class Node {
+ public:
+
+ /** Spatial bounds on all values at this node and its children, based purely on
+ the parent's splitting planes. May be infinite */
+ AABox splitBounds;
+
+ Vector3::Axis splitAxis;
+
+ /** Location along the specified axis */
+ float splitLocation;
+
+ /** child[0] contains all values strictly
+ smaller than splitLocation along splitAxis.
+
+ child[1] contains all values strictly
+ larger.
+
+ Both may be NULL if there are not enough
+ values to bother recursing.
+ */
+ Node* child[2];
+
+ /** Values if this is a leaf node). */
+ Array<Handle> valueArray;
+
+ /** Creates node with NULL children */
+ Node() {
+ splitAxis = Vector3::X_AXIS;
+ splitLocation = 0;
+ splitBounds = AABox(-Vector3::inf(), Vector3::inf());
+ for (int i = 0; i < 2; ++i) {
+ child[i] = NULL;
+ }
+ }
+
+ /**
+ Doesn't clone children.
+ */
+ Node(const Node& other) : valueArray(other.valueArray) {
+ splitAxis = other.splitAxis;
+ splitLocation = other.splitLocation;
+ splitBounds = other.splitBounds;
+ for (int i = 0; i < 2; ++i) {
+ child[i] = NULL;
+ }
+ }
+
+ /** Copies the specified subarray of pt into point, NULLs the children.
+ Assumes a second pass will set splitBounds. */
+ Node(const Array<Handle>& pt) {
+ splitAxis = Vector3::X_AXIS;
+ splitLocation = 0;
+ for (int i = 0; i < 2; ++i) {
+ child[i] = NULL;
+ }
+ valueArray = pt;
+ }
+
+
+ /** Deletes the children (but not the values) */
+ ~Node() {
+ for (int i = 0; i < 2; ++i) {
+ delete child[i];
+ }
+ }
+
+
+ /** Returns true if this node is a leaf (no children) */
+ inline bool isLeaf() const {
+ return (child[0] == NULL) && (child[1] == NULL);
+ }
+
+
+ /**
+ Recursively appends all handles and children's handles
+ to the array.
+ */
+ void getHandles(Array<Handle>& handleArray) const {
+ handleArray.append(valueArray);
+ for (int i = 0; i < 2; ++i) {
+ if (child[i] != NULL) {
+ child[i]->getHandles(handleArray);
+ }
+ }
+ }
+
+
+ void verifyNode(const Vector3& lo, const Vector3& hi) {
+ // debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
+ // splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
+
+ debugAssert(lo == splitBounds.low());
+ debugAssert(hi == splitBounds.high());
+
+ for (int i = 0; i < valueArray.length(); ++i) {
+ const Vector3& b = valueArray[i].position();
+ debugAssert(splitBounds.contains(b));
+ }
+
+ if (child[0] || child[1]) {
+ debugAssert(lo[splitAxis] < splitLocation);
+ debugAssert(hi[splitAxis] > splitLocation);
+ }
+
+ Vector3 newLo = lo;
+ newLo[splitAxis] = splitLocation;
+ Vector3 newHi = hi;
+ newHi[splitAxis] = splitLocation;
+
+ if (child[0] != NULL) {
+ child[0]->verifyNode(lo, newHi);
+ }
+
+ if (child[1] != NULL) {
+ child[1]->verifyNode(newLo, hi);
+ }
+ }
+
+
+ /**
+ Stores the locations of the splitting planes (the structure but not the content)
+ so that the tree can be quickly rebuilt from a previous configuration without
+ calling balance.
+ */
+ static void serializeStructure(const Node* n, BinaryOutput& bo) {
+ if (n == NULL) {
+ bo.writeUInt8(0);
+ } else {
+ bo.writeUInt8(1);
+ n->splitBounds.serialize(bo);
+ serialize(n->splitAxis, bo);
+ bo.writeFloat32(n->splitLocation);
+ for (int c = 0; c < 2; ++c) {
+ serializeStructure(n->child[c], bo);
+ }
+ }
+ }
+
+ /** Clears the member table */
+ static Node* deserializeStructure(BinaryInput& bi) {
+ if (bi.readUInt8() == 0) {
+ return NULL;
+ } else {
+ Node* n = new Node();
+ n->splitBounds.deserialize(bi);
+ deserialize(n->splitAxis, bi);
+ n->splitLocation = bi.readFloat32();
+ for (int c = 0; c < 2; ++c) {
+ n->child[c] = deserializeStructure(bi);
+ }
+ }
+ }
+
+ /** Returns the deepest node that completely contains bounds. */
+ Node* findDeepestContainingNode(const Vector3& point) {
+
+ // See which side of the splitting plane the bounds are on
+ if (point[splitAxis] < splitLocation) {
+ // Point is on the low side. Recurse into the child
+ // if it exists.
+ if (child[0] != NULL) {
+ return child[0]->findDeepestContainingNode(point);
+ }
+ } else if (point[splitAxis] > splitLocation) {
+ // Point is on the high side, recurse into the child
+ // if it exists.
+ if (child[1] != NULL) {
+ return child[1]->findDeepestContainingNode(point);
+ }
+ }
+
+ // There was no containing child, so this node is the
+ // deepest containing node.
+ return this;
+ }
+
+ /** Appends all members that intersect the box.
+ If useSphere is true, members are tested against the sphere instead. */
+ void getIntersectingMembers(
+ const AABox& sphereBounds,
+ const Sphere& sphere,
+ Array<T>& members) const {
+
+ // Test all values at this node. Extract the
+ // underlying C array for speed
+ const int N = valueArray.size();
+ const Handle* handleArray = valueArray.getCArray();
+
+ const float r2 = square(sphere.radius);
+
+ // Copy the sphere center so that it is on the stack near the radius
+ const Vector3 center = sphere.center;
+ for (int v = 0; v < N; ++v) {
+ if ((center - handleArray[v].position()).squaredLength() <= r2) {
+ members.append(handleArray[v].value);
+ }
+ }
+
+ // If the left child overlaps the box, recurse into it
+ if (child[0] && (sphereBounds.low()[splitAxis] < splitLocation)) {
+ child[0]->getIntersectingMembers(sphereBounds, sphere, members);
+ }
+
+ // If the right child overlaps the box, recurse into it
+ if (child[1] && (sphereBounds.high()[splitAxis] > splitLocation)) {
+ child[1]->getIntersectingMembers(sphereBounds, sphere, members);
+ }
+ }
+
+ /** Appends all members that intersect the box.
+ If useSphere is true, members are tested against the sphere instead.
+
+ Implemented using both box and sphere tests to simplify the implementation
+ of a future beginSphereInteresection iterator using the same underlying
+ BoxIterator class.
+ */
+ void getIntersectingMembers(
+ const AABox& box,
+ const Sphere& sphere,
+ Array<T>& members,
+ bool useSphere) const {
+
+ // Test all values at this node
+ for (int v = 0; v < valueArray.size(); ++v) {
+ if ((useSphere && sphere.contains(valueArray[v].position())) ||
+ (! useSphere && box.contains(valueArray[v].position()))) {
+ members.append(valueArray[v].value);
+ }
+ }
+
+ // If the left child overlaps the box, recurse into it
+ if ((child[0] != NULL) && (box.low()[splitAxis] < splitLocation)) {
+ child[0]->getIntersectingMembers(box, sphere, members, useSphere);
+ }
+
+ // If the right child overlaps the box, recurse into it
+ if ((child[1] != NULL) && (box.high()[splitAxis] > splitLocation)) {
+ child[1]->getIntersectingMembers(box, sphere, members, useSphere);
+ }
+ }
+
+ /**
+ Recurse through the tree, assigning splitBounds fields.
+ */
+ void assignSplitBounds(const AABox& myBounds) {
+ splitBounds = myBounds;
+
+# ifdef G3D_DEBUG
+ if (child[0] || child[1]) {
+ debugAssert(splitBounds.high()[splitAxis] > splitLocation);
+ debugAssert(splitBounds.low()[splitAxis] < splitLocation);
+ }
+# endif
+
+ AABox childBounds[2];
+ myBounds.split(splitAxis, splitLocation, childBounds[0], childBounds[1]);
+
+ for (int c = 0; c < 2; ++c) {
+ if (child[c]) {
+ child[c]->assignSplitBounds(childBounds[c]);
+ }
+ }
+ }
+ };
+
+ class AxisComparator {
+ private:
+ Vector3::Axis sortAxis;
+
+ public:
+
+ AxisComparator(Vector3::Axis s) : sortAxis(s) {}
+
+ inline int operator()(const Handle& A, const Handle& B) const {
+ if (A.position()[sortAxis] > B.position()[sortAxis]) {
+ return -1;
+ } else if (A.position()[sortAxis] < B.position()[sortAxis]) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
+ /**
+ Recursively subdivides the subarray.
+
+ The source array will be cleared after it is used
+
+ Call assignSplitBounds() on the root node after making a tree.
+ */
+ Node* makeNode(
+ Array<Handle>& source,
+ Array<Handle>& temp,
+ int valuesPerNode,
+ int numMeanSplits) {
+
+ Node* node = NULL;
+
+ if (source.size() <= valuesPerNode) {
+ // Make a new leaf node
+ node = new Node(source);
+
+ // Set the pointers in the memberTable
+ for (int i = 0; i < source.size(); ++i) {
+ memberTable.set(source[i].value, node);
+ }
+
+ } else {
+ // Make a new internal node
+ node = new Node();
+
+ const AABox bounds = computeBounds(source);
+ const Vector3 extent = bounds.high() - bounds.low();
+
+ Vector3::Axis splitAxis = extent.primaryAxis();
+
+ float splitLocation;
+
+ Array<Handle> lt, gt;
+
+ if (numMeanSplits <= 0) {
+ source.medianPartition(lt, node->valueArray, gt, temp, AxisComparator(splitAxis));
+ splitLocation = node->valueArray[0].position()[splitAxis];
+
+ if ((node->valueArray.size() > source.size() / 2) &&
+ (source.size() > 10)) {
+ // Our median split put an awful lot of points on the splitting plane. Try a mean
+ // split instead
+ numMeanSplits = 1;
+ }
+ }
+
+ if (numMeanSplits > 0) {
+ // Compute the mean along the axis
+
+ splitLocation = (bounds.high()[splitAxis] +
+ bounds.low()[splitAxis]) / 2.0;
+
+ Handle splitHandle;
+ Vector3 v;
+ v[splitAxis] = splitLocation;
+ splitHandle.setPosition(v);
+
+ source.partition(splitHandle, lt, node->valueArray, gt, AxisComparator(splitAxis));
+ }
+
+# if defined(G3D_DEBUG) && defined(VERIFY_TREE)
+ for (int i = 0; i < lt.size(); ++i) {
+ const Vector3& v = lt[i].position();
+ debugAssert(v[splitAxis] < splitLocation);
+ }
+ for (int i = 0; i < gt.size(); ++i) {
+ debugAssert(gt[i].position()[splitAxis] > splitLocation);
+ }
+ for (int i = 0; i < node->valueArray.size(); ++i) {
+ debugAssert(node->valueArray[i].position()[splitAxis] == splitLocation);
+ }
+# endif
+
+ node->splitAxis = splitAxis;
+ node->splitLocation = splitLocation;
+
+ // Throw away the source array to save memory
+ source.fastClear();
+
+ if (lt.size() > 0) {
+ node->child[0] = makeNode(lt, temp, valuesPerNode, numMeanSplits - 1);
+ }
+
+ if (gt.size() > 0) {
+ node->child[1] = makeNode(gt, temp, valuesPerNode, numMeanSplits - 1);
+ }
+
+ // Add the values stored at this interior node to the member table
+ for(int i = 0; i < node->valueArray.size(); ++i) {
+ memberTable.set(node->valueArray[i].value, node);
+ }
+
+ }
+
+ return node;
+ }
+
+ /**
+ Recursively clone the passed in node tree, setting
+ pointers for members in the memberTable as appropriate.
+ called by the assignment operator.
+ */
+ Node* cloneTree(Node* src) {
+ Node* dst = new Node(*src);
+
+ // Make back pointers
+ for (int i = 0; i < dst->valueArray.size(); ++i) {
+ memberTable.set(dst->valueArray[i].value, dst);
+ }
+
+ // Clone children
+ for (int i = 0; i < 2; ++i) {
+ if (src->child[i] != NULL) {
+ dst->child[i] = cloneTree(src->child[i]);
+ }
+ }
+
+ return dst;
+ }
+
+ /** Maps members to the node containing them */
+ typedef Table<T, Node*, HashFunc, EqualsFunc> MemberTable;
+ MemberTable memberTable;
+
+ Node* root;
+
+public:
+
+ /** To construct a balanced tree, insert the elements and then call
+ PointKDTree::balance(). */
+ PointKDTree() : root(NULL) {}
+
+
+ PointKDTree(const PointKDTree& src) : root(NULL) {
+ *this = src;
+ }
+
+
+ PointKDTree& operator=(const PointKDTree& src) {
+ delete root;
+ // Clone tree takes care of filling out the memberTable.
+ root = cloneTree(src.root);
+ return *this;
+ }
+
+
+ ~PointKDTree() {
+ clear();
+ }
+
+ /**
+ Throws out all elements of the set and erases the structure of the tree.
+ */
+ void clear() {
+ memberTable.clear();
+ delete root;
+ root = NULL;
+ }
+
+ /** Removes all elements of the set while maintaining the structure of the tree */
+ void clearData() {
+ memberTable.clear();
+ Array<Node*> stack;
+ stack.push(root);
+ while (stack.size() > 0) {
+ Node* node = stack.pop();
+ node->valueArray.fastClear();
+
+ for (int i = 0; i < 2; ++i) {
+ if (node->child[i] != NULL) {
+ stack.push(node->child[i]);
+ }
+ }
+ }
+ }
+
+
+ int size() const {
+ return memberTable.size();
+ }
+
+ /**
+ Inserts an object into the set if it is not
+ already present. O(log n) time. Does not
+ cause the tree to be balanced.
+ */
+ void insert(const T& value) {
+ if (contains(value)) {
+ // Already in the set
+ return;
+ }
+
+ Handle h(value);
+
+ if (root == NULL) {
+ // This is the first node; create a root node
+ root = new Node();
+ }
+
+ Node* node = root->findDeepestContainingNode(h.position());
+
+ // Insert into the node
+ node->valueArray.append(h);
+
+ // Insert into the node table
+ memberTable.set(value, node);
+ }
+
+ /** Inserts each elements in the array in turn. If the tree
+ begins empty (no structure and no elements), this is faster
+ than inserting each element in turn. You still need to balance
+ the tree at the end.*/
+ void insert(const Array<T>& valueArray) {
+ // Pre-size the member table to avoid multiple allocations
+ memberTable.setSizeHint(valueArray.size() + size());
+
+ if (root == NULL) {
+ // Optimized case for an empty tree; don't bother
+ // searching or reallocating the root node's valueArray
+ // as we incrementally insert.
+ root = new Node();
+ root->valueArray.resize(valueArray.size());
+ for (int i = 0; i < valueArray.size(); ++i) {
+ // Insert in opposite order so that we have the exact same
+ // data structure as if we inserted each (i.e., order is reversed
+ // from array).
+ root->valueArray[valueArray.size() - i - 1] = Handle(valueArray[i]);
+ memberTable.set(valueArray[i], root);
+ }
+ } else {
+ // Insert at appropriate tree depth.
+ for (int i = 0; i < valueArray.size(); ++i) {
+ insert(valueArray[i]);
+ }
+ }
+ }
+
+
+ /**
+ Returns true if this object is in the set, otherwise
+ returns false. O(1) time.
+ */
+ bool contains(const T& value) {
+ return memberTable.containsKey(value);
+ }
+
+
+ /**
+ Removes an object from the set in O(1) time.
+ It is an error to remove members that are not already
+ present. May unbalance the tree.
+
+ Removing an element never causes a node (split plane) to be removed...
+ nodes are only changed when the tree is rebalanced. This behavior
+ is desirable because it allows the split planes to be serialized,
+ and then deserialized into an empty tree which can be repopulated.
+ */
+ void remove(const T& value) {
+ debugAssertM(contains(value),
+ "Tried to remove an element from a "
+ "PointKDTree that was not present");
+
+ Array<Handle>& list = memberTable[value]->valueArray;
+
+ // Find the element and remove it
+ for (int i = list.length() - 1; i >= 0; --i) {
+ if (list[i].value == value) {
+ list.fastRemove(i);
+ break;
+ }
+ }
+ memberTable.remove(value);
+ }
+
+
+ /**
+ If the element is in the set, it is removed.
+ The element is then inserted.
+
+ This is useful when the == and hashCode methods
+ on <I>T</I> are independent of the bounds. In
+ that case, you may call update(v) to insert an
+ element for the first time and call update(v)
+ again every time it moves to keep the tree
+ up to date.
+ */
+ void update(const T& value) {
+ if (contains(value)) {
+ remove(value);
+ }
+ insert(value);
+ }
+
+
+ /**
+ Rebalances the tree (slow). Call when objects
+ have moved substantially from their original positions
+ (which unbalances the tree and causes the spatial
+ queries to be slow).
+
+ @param valuesPerNode Maximum number of elements to put at
+ a node.
+
+ @param numMeanSplits numMeanSplits = 0 gives a
+ fully axis aligned BSP-tree, where the balance operation attempts to balance
+ the tree so that every splitting plane has an equal number of left
+ and right children (i.e. it is a <B>median</B> split along that axis).
+ This tends to maximize average performance; all querries will return in the same amount of time.
+
+ You can override this behavior by
+ setting a number of <B>mean</B> (average) splits. numMeanSplits = MAX_INT
+ creates a full oct-tree, which tends to optimize peak performance (some areas of the scene will terminate after few recursive splits) at the expense of
+ peak performance.
+ */
+ void balance(int valuesPerNode = 40, int numMeanSplits = 3) {
+ if (root == NULL) {
+ // Tree is empty
+ return;
+ }
+
+ Array<Handle> handleArray;
+ root->getHandles(handleArray);
+
+ // Delete the old tree
+ clear();
+
+ Array<Handle> temp;
+ root = makeNode(handleArray, temp, valuesPerNode, numMeanSplits);
+ temp.fastClear();
+
+ // Walk the tree, assigning splitBounds. We start with unbounded
+ // space.
+ root->assignSplitBounds(AABox::maxFinite());
+
+# ifdef _DEBUG
+ root->verifyNode(Vector3::minFinite(), Vector3::maxFinite());
+# endif
+ }
+
+private:
+
+ /**
+ Returns the elements
+
+ @param parentMask The mask that this node returned from culledBy.
+ */
+ static void getIntersectingMembers(
+ const Array<Plane>& plane,
+ Array<T>& members,
+ Node* node,
+ uint32 parentMask) {
+
+ int dummy;
+
+ if (parentMask == 0) {
+ // None of these planes can cull anything
+ for (int v = node->valueArray.size() - 1; v >= 0; --v) {
+ members.append(node->valueArray[v].value);
+ }
+
+ // Iterate through child nodes
+ for (int c = 0; c < 2; ++c) {
+ if (node->child[c]) {
+ getIntersectingMembers(plane, members, node->child[c], 0);
+ }
+ }
+ } else {
+
+ if (node->valueArray.size() > 0) {
+ // This is a leaf; check the points
+ debugAssertM(node->child[0] == NULL, "Malformed Point tree");
+ debugAssertM(node->child[1] == NULL, "Malformed Point tree");
+
+ // Test values at this node against remaining planes
+ for (int p = 0; p < plane.size(); ++p) {
+ if ((parentMask >> p) & 1 != 0) {
+ // Test against this plane
+ const Plane& curPlane = plane[p];
+ for (int v = node->valueArray.size() - 1; v >= 0; --v) {
+ if (curPlane.halfSpaceContains(node->valueArray[v].position())) {
+ members.append(node->valueArray[v].value);
+ }
+ }
+ }
+ }
+ } else {
+
+ uint32 childMask = 0xFFFFFF;
+
+ // Iterate through child nodes
+ for (int c = 0; c < 2; ++c) {
+ if (node->child[c] &&
+ ! node->child[c]->splitBounds.culledBy(plane, dummy, parentMask, childMask)) {
+ // This node was not culled
+ getIntersectingMembers(plane, members, node->child[c], childMask);
+ }
+ }
+ }
+ }
+ }
+
+public:
+
+ /**
+ Returns all members inside the set of planes.
+ @param members The results are appended to this array.
+ */
+ void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
+ if (root == NULL) {
+ return;
+ }
+
+ getIntersectingMembers(plane, members, root, 0xFFFFFF);
+ }
+
+ /**
+ Typically used to find all visible
+ objects inside the view frustum (see also GCamera::getClipPlanes)... i.e. all objects
+ <B>not</B> culled by frustum.
+
+ Example:
+ <PRE>
+ Array<Object*> visible;
+ tree.getIntersectingMembers(camera.frustum(), visible);
+ // ... Draw all objects in the visible array.
+ </PRE>
+ @param members The results are appended to this array.
+ */
+ void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
+ Array<Plane> plane;
+
+ for (int i = 0; i < frustum.faceArray.size(); ++i) {
+ plane.append(frustum.faceArray[i].plane);
+ }
+
+ getIntersectingMembers(plane, members);
+ }
+
+ /**
+ C++ STL style iterator variable. See beginBoxIntersection().
+ The iterator overloads the -> (dereference) operator, so this
+ acts like a pointer to the current member.
+ */
+ // This iterator turns Node::getIntersectingMembers into a
+ // coroutine. It first translates that method from recursive to
+ // stack based, then captures the system state (analogous to a Scheme
+ // continuation) after each element is appended to the member array,
+ // and allowing the computation to be restarted.
+ class BoxIntersectionIterator {
+ private:
+ friend class TreeType;
+
+ /** True if this is the "end" iterator instance */
+ bool isEnd;
+
+ /** The box that we're testing against. */
+ AABox box;
+
+ /** Node that we're currently looking at. Undefined if isEnd
+ is true. */
+ Node* node;
+
+ /** Nodes waiting to be processed */
+ // We could use backpointers within the tree and careful
+ // state management to avoid ever storing the stack-- but
+ // it is much easier this way and only inefficient if the
+ // caller uses post increment (which they shouldn't!).
+ Array<Node*> stack;
+
+ /** The next index of current->valueArray to return.
+ Undefined when isEnd is true.*/
+ int nextValueArrayIndex;
+
+ BoxIntersectionIterator() : isEnd(true) {}
+
+ BoxIntersectionIterator(const AABox& b, const Node* root) :
+ isEnd(root == NULL), box(b),
+ node(const_cast<Node*>(root)), nextValueArrayIndex(-1) {
+
+ // We intentionally start at the "-1" index of the current
+ // node so we can use the preincrement operator to move
+ // ourselves to element 0 instead of repeating all of the
+ // code from the preincrement method. Note that this might
+ // cause us to become the "end" instance.
+ ++(*this);
+ }
+
+ public:
+
+ inline bool operator!=(const BoxIntersectionIterator& other) const {
+ return ! (*this == other);
+ }
+
+ bool operator==(const BoxIntersectionIterator& other) const {
+ if (isEnd) {
+ return other.isEnd;
+ } else if (other.isEnd) {
+ return false;
+ } else {
+ // Two non-end iterators; see if they match. This is kind of
+ // silly; users shouldn't call == on iterators in general unless
+ // one of them is the end iterator.
+ if ((box != other.box) || (node != other.node) ||
+ (nextValueArrayIndex != other.nextValueArrayIndex) ||
+ (stack.length() != other.stack.length())) {
+ return false;
+ }
+
+ // See if the stacks are the same
+ for (int i = 0; i < stack.length(); ++i) {
+ if (stack[i] != other.stack[i]) {
+ return false;
+ }
+ }
+
+ // We failed to find a difference; they must be the same
+ return true;
+ }
+ }
+
+ /**
+ Pre increment.
+ */
+ BoxIntersectionIterator& operator++() {
+ ++nextValueArrayIndex;
+
+ bool foundIntersection = false;
+ while (! isEnd && ! foundIntersection) {
+
+ // Search for the next node if we've exhausted this one
+ while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) {
+ // If we entered this loop, then the iterator has exhausted the elements at
+ // node (possibly because it just switched to a child node with no members).
+ // This loop continues until it finds a node with members or reaches
+ // the end of the whole intersection search.
+
+ // If the right child overlaps the box, push it onto the stack for
+ // processing.
+ if ((node->child[1] != NULL) &&
+ (box.high()[node->splitAxis] > node->splitLocation)) {
+ stack.push(node->child[1]);
+ }
+
+ // If the left child overlaps the box, push it onto the stack for
+ // processing.
+ if ((node->child[0] != NULL) &&
+ (box.low()[node->splitAxis] < node->splitLocation)) {
+ stack.push(node->child[0]);
+ }
+
+ if (stack.length() > 0) {
+ // Go on to the next node (which may be either one of the ones we
+ // just pushed, or one from farther back the tree).
+ node = stack.pop();
+ nextValueArrayIndex = 0;
+ } else {
+ // That was the last node; we're done iterating
+ isEnd = true;
+ }
+ }
+
+ // Search for the next intersection at this node until we run out of children
+ while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
+ if (box.intersects(node->valueArray[nextValueArrayIndex].bounds)) {
+ foundIntersection = true;
+ } else {
+ ++nextValueArrayIndex;
+ // If we exhaust this node, we'll loop around the master loop
+ // to find a new node.
+ }
+ }
+ }
+
+ return *this;
+ }
+
+ /**
+ Post increment (much slower than preincrement!).
+ */
+ BoxIntersectionIterator operator++(int) {
+ BoxIntersectionIterator old = *this;
+ ++this;
+ return old;
+ }
+
+ /** Overloaded dereference operator so the iterator can masquerade as a pointer
+ to a member */
+ const T& operator*() const {
+ alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
+ return node->valueArray[nextValueArrayIndex].value;
+ }
+
+ /** Overloaded dereference operator so the iterator can masquerade as a pointer
+ to a member */
+ T const * operator->() const {
+ alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
+ return &(stack.last()->valueArray[nextValueArrayIndex].value);
+ }
+
+ /** Overloaded cast operator so the iterator can masquerade as a pointer
+ to a member */
+ operator T*() const {
+ alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
+ return &(stack.last()->valueArray[nextValueArrayIndex].value);
+ }
+ };
+
+
+ /**
+ Iterates through the members that intersect the box
+ */
+ BoxIntersectionIterator beginBoxIntersection(const AABox& box) const {
+ return BoxIntersectionIterator(box, root);
+ }
+
+ BoxIntersectionIterator endBoxIntersection() const {
+ // The "end" iterator instance
+ return BoxIntersectionIterator();
+ }
+
+ /**
+ Appends all members whose bounds intersect the box.
+ See also PointKDTree::beginBoxIntersection.
+ */
+ void getIntersectingMembers(const AABox& box, Array<T>& members) const {
+ if (root == NULL) {
+ return;
+ }
+ root->getIntersectingMembers(box, Sphere(Vector3::zero(), 0), members, false);
+ }
+
+
+ /**
+ @param members The results are appended to this array.
+ */
+ void getIntersectingMembers(const Sphere& sphere, Array<T>& members) const {
+ if (root == NULL) {
+ return;
+ }
+
+ AABox box;
+ sphere.getBounds(box);
+ root->getIntersectingMembers(box, sphere, members);
+
+ }
+
+
+ /**
+ Stores the locations of the splitting planes (the structure but not the content)
+ so that the tree can be quickly rebuilt from a previous configuration without
+ calling balance.
+ */
+ void serializeStructure(BinaryOutput& bo) const {
+ Node::serializeStructure(root, bo);
+ }
+
+ /** Clears the member table */
+ void deserializeStructure(BinaryInput& bi) {
+ clear();
+ root = Node::deserializeStructure(bi);
+ }
+
+ /**
+ Returns an array of all members of the set. See also PointKDTree::begin.
+ */
+ void getMembers(Array<T>& members) const {
+ memberTable.getKeys(members);
+ }
+
+
+ /**
+ C++ STL style iterator variable. See begin().
+ Overloads the -> (dereference) operator, so this acts like a pointer
+ to the current member.
+ */
+ class Iterator {
+ private:
+ friend class TreeType;
+
+ // Note: this is a Table iterator, we are currently defining
+ // Set iterator
+ typename MemberTable::Iterator it;
+
+ Iterator(const typename MemberTable::Iterator& it) : it(it) {}
+
+ public:
+ inline bool operator!=(const Iterator& other) const {
+ return !(*this == other);
+ }
+
+ bool operator==(const Iterator& other) const {
+ return it == other.it;
+ }
+
+ /**
+ Pre increment.
+ */
+ Iterator& operator++() {
+ ++it;
+ return *this;
+ }
+
+ /**
+ Post increment (slower than preincrement).
+ */
+ Iterator operator++(int) {
+ Iterator old = *this;
+ ++(*this);
+ return old;
+ }
+
+ const T& operator*() const {
+ return it->key;
+ }
+
+ T* operator->() const {
+ return &(it->key);
+ }
+
+ operator T*() const {
+ return &(it->key);
+ }
+ };
+
+
+ /**
+ C++ STL style iterator method. Returns the first member.
+ Use preincrement (++entry) to get to the next element (iteration
+ order is arbitrary).
+ Do not modify the set while iterating.
+ */
+ Iterator begin() const {
+ return Iterator(memberTable.begin());
+ }
+
+
+ /**
+ C++ STL style iterator method. Returns one after the last iterator
+ element.
+ */
+ Iterator end() const {
+ return Iterator(memberTable.end());
+ }
+#undef TreeType
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Pointer.h b/dep/include/g3dlite/G3D/Pointer.h
new file mode 100644
index 00000000000..6e35062a746
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Pointer.h
@@ -0,0 +1,292 @@
+/**
+ @file Pointer.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-05-16
+ @edited 2009-03-26
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_Pointer_h
+#define G3D_Pointer_h
+
+#include "G3D/debugAssert.h"
+#include "G3D/ReferenceCount.h"
+
+namespace G3D {
+
+/**
+ Acts like a pointer to a value of type ValueType (i.e.,
+ ValueType*), but can operate through accessor methods as well as on
+ a value in memory. This is useful for implementing scripting
+ languages and other applications that need to connect existing APIs
+ by reference.
+
+ Because the accessors require values to be passed by value (instead of by reference)
+ this is primarily useful for objects whose memory size is small.
+
+ <pre>
+ class Foo {
+ public:
+ void setEnabled(bool b);
+ bool getEnabled() const;
+ };
+
+ Foo f;
+ bool b;
+
+ Pointer<bool> p1(&b);
+ Pointer<bool> p2(&f, &Foo::getEnabled, &Foo::setEnabled);
+
+ *p1 = true;
+ *p2 = false;
+ *p2 = *p1; \/\/ Value assignment
+ p2 = p1; \/\/ Pointer aliasing
+
+ \/\/ Or, equivalently:
+ p1.setValue(true);
+ p2.setValue(false);
+
+ p2.setValue(p1.getValue());
+ p2 = p1;
+ </pre>
+
+ <i>Note:</i> Because of the way that dereference is implemented, you cannot pass <code>*p</code> through a function
+ that takes varargs (...), e.g., <code>printf("%d", *p)</code> will produce a compile-time error. Instead use
+ <code>printf("%d",(bool)*p)</code> or <code>printf("%d", p.getValue())</code>.
+
+ */
+template<class ValueType>
+class Pointer {
+private:
+
+ class Interface {
+ public:
+ virtual ~Interface() {};
+ virtual void set(ValueType b) = 0;
+ virtual ValueType get() const = 0;
+ virtual Interface* clone() const = 0;
+ virtual bool isNull() const = 0;
+ };
+
+ class Memory : public Interface {
+ private:
+
+ ValueType* value;
+
+ public:
+
+ Memory(ValueType* value) : value(value) {
+ //debugAssert(value != NULL);
+ }
+
+ virtual void set(ValueType v) {
+ *value = v;
+ }
+
+ virtual ValueType get() const {
+ return *value;
+ }
+
+ virtual Interface* clone() const {
+ return new Memory(value);
+ }
+
+ virtual bool isNull() const {
+ return value == NULL;
+ }
+ };
+
+ template<class T, typename GetMethod, typename SetMethod>
+ class Accessor : public Interface {
+ private:
+
+ T* object;
+ GetMethod getMethod;
+ SetMethod setMethod;
+
+ public:
+
+ Accessor(T* object,
+ GetMethod getMethod,
+ SetMethod setMethod) : object(object), getMethod(getMethod), setMethod(setMethod) {
+ debugAssert(object != NULL);
+ }
+
+ virtual void set(ValueType v) {
+ (object->*setMethod)(v);
+ }
+
+ virtual ValueType get() const {
+ return (object->*getMethod)();
+ }
+
+ virtual Interface* clone() const {
+ return new Accessor(object, getMethod, setMethod);
+ }
+
+ virtual bool isNull() const {
+ return object == NULL;
+ }
+ };
+
+
+ template<class T, typename GetMethod, typename SetMethod>
+ class RefAccessor : public Interface {
+ private:
+
+ ReferenceCountedPointer<T> object;
+ GetMethod getMethod;
+ SetMethod setMethod;
+
+ public:
+
+ RefAccessor(
+ const ReferenceCountedPointer<T>& object,
+ GetMethod getMethod,
+ SetMethod setMethod) : object(object), getMethod(getMethod), setMethod(setMethod) {
+
+ debugAssert(object != NULL);
+ }
+
+ virtual void set(ValueType v) {
+ (object.pointer()->*setMethod)(v);
+ }
+
+ virtual ValueType get() const {
+ return (object.pointer()->*getMethod)();
+ }
+
+ virtual Interface* clone() const {
+ return new RefAccessor(object, getMethod, setMethod);
+ }
+
+ virtual bool isNull() const {
+ return object.isNull();
+ }
+ };
+
+
+ Interface* m_interface;
+
+public:
+
+ Pointer() : m_interface(NULL) {};
+
+ /** Allows implicit cast from real pointer */
+ Pointer(ValueType* v) : m_interface(new Memory(v)) {}
+
+ inline bool isNull() const {
+ return (m_interface == NULL) || m_interface->isNull();
+ }
+
+ // Assignment
+ inline Pointer& operator=(const Pointer& r) {
+ delete m_interface;
+ if (r.m_interface != NULL) {
+ m_interface = r.m_interface->clone();
+ } else {
+ m_interface = NULL;
+ }
+ return this[0];
+ }
+
+ Pointer(const Pointer& p) : m_interface(NULL) {
+ this[0] = p;
+ }
+
+ template<class Class>
+ Pointer(const ReferenceCountedPointer<Class>& object,
+ ValueType (Class::*getMethod)() const,
+ void (Class::*setMethod)(ValueType)) :
+ m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+
+ template<class Class>
+ Pointer(const ReferenceCountedPointer<Class>& object,
+ const ValueType& (Class::*getMethod)() const,
+ void (Class::*setMethod)(ValueType)) :
+ m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+
+ template<class Class>
+ Pointer(const ReferenceCountedPointer<Class>& object,
+ ValueType (Class::*getMethod)() const,
+ void (Class::*setMethod)(const ValueType&)) :
+ m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+
+ template<class Class>
+ Pointer(const ReferenceCountedPointer<Class>& object,
+ const ValueType& (Class::*getMethod)() const,
+ void (Class::*setMethod)(const ValueType&)) :
+ m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+
+ template<class Class>
+ Pointer(Class* object,
+ const ValueType& (Class::*getMethod)() const,
+ void (Class::*setMethod)(const ValueType&)) :
+ m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+
+ template<class Class>
+ Pointer(Class* object,
+ ValueType (Class::*getMethod)() const,
+ void (Class::*setMethod)(const ValueType&)) :
+ m_interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+
+ template<class Class>
+ Pointer(Class* object,
+ const ValueType& (Class::*getMethod)() const,
+ void (Class::*setMethod)(ValueType)) :
+ m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+
+ template<class Class>
+ Pointer(Class* object,
+ ValueType (Class::*getMethod)() const,
+ void (Class::*setMethod)(ValueType)) :
+ m_interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+
+ ~Pointer() {
+ delete m_interface;
+ }
+
+ inline const ValueType getValue() const {
+ debugAssert(m_interface != NULL);
+ return m_interface->get();
+ }
+
+ inline void setValue(const ValueType& v) {
+ debugAssert(m_interface != NULL);
+ m_interface->set(v);
+ }
+
+ class IndirectValue {
+ private:
+
+ friend class Pointer;
+ Pointer* pointer;
+ IndirectValue(Pointer* p) : pointer(p) {}
+
+ public:
+
+ void operator=(const ValueType& v) {
+ pointer->setValue(v);
+ }
+
+ operator ValueType() const {
+ return pointer->getValue();
+ }
+
+ };
+
+ inline IndirectValue operator*() {
+ return IndirectValue(this);
+ }
+
+ inline const ValueType operator*() const {
+ return getValue();
+ }
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/PositionTrait.h b/dep/include/g3dlite/G3D/PositionTrait.h
new file mode 100644
index 00000000000..67a4f64138a
--- /dev/null
+++ b/dep/include/g3dlite/G3D/PositionTrait.h
@@ -0,0 +1,7 @@
+#ifndef G3D_POSITIONTRAIT_H
+#define G3D_POSITIONTRAIT_H
+
+template<typename Value>
+struct PositionTrait{};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/PrecomputedRandom.h b/dep/include/g3dlite/G3D/PrecomputedRandom.h
new file mode 100644
index 00000000000..411d128c582
--- /dev/null
+++ b/dep/include/g3dlite/G3D/PrecomputedRandom.h
@@ -0,0 +1,110 @@
+/**
+ @file PrecomputedRandom.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-03-31
+ @edited 2009-03-31
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_PrecomputedRandom_h
+#define G3D_PrecomputedRandom_h
+
+#include "G3D/platform.h"
+#include "G3D/Random.h"
+
+namespace G3D {
+
+/** Fast random numbers using a precomputed data table.
+
+ e.g., generates cosHemi about 13x faster than Random.
+ This is useful for quickly generating seeded random
+ numbers for reproducibility. G3D::Random takes a long
+ time to seed; this is instantaneous (providing the
+ precomputed data is already available.)
+
+ Not threadsafe.*/
+class PrecomputedRandom : public Random {
+public:
+ /** Put the cosHemi and the uniform together so that when
+ alternating between them we stay in cache. This is also packed
+ into a good size for SIMD and GPU operations.*/
+ class HemiUniformData {
+ public:
+ float cosHemiX;
+ float cosHemiY;
+ float cosHemiZ;
+ float uniform;
+ };
+
+ class SphereBitsData {
+ public:
+ float sphereX;
+ float sphereY;
+ float sphereZ;
+ uint32 bits;
+ };
+
+protected:
+
+ /** Array of 2^n elements. */
+ const HemiUniformData* m_hemiUniform;
+ const SphereBitsData* m_sphereBits;
+
+ /** 2^n - 1; the AND mask for computing a fast modulo */
+ int m_modMask;
+
+ int m_index;
+
+ /** If true, free m_hemiUniform and m_sphereBits in destructor */
+ bool m_freeData;
+
+public:
+
+ /*
+ \param dataSize Must be a power of 2
+ \param data Will NOT be deleted by the destructor.
+ */
+ PrecomputedRandom(const HemiUniformData* data1, const SphereBitsData* data2, int dataSize, uint32 seed = 0xF018A4D2);
+
+ /**
+ \param dataSize Number of random numbers that can be requested before periodicity. Must be a power of 2.
+ */
+ PrecomputedRandom(int dataSize, uint32 seed = 0xF018A4D2);
+
+ ~PrecomputedRandom();
+
+ /** Each bit is random. Subclasses can choose to override just
+ this method and the other methods will all work automatically. */
+ virtual uint32 bits();
+
+ // integer is inherited
+
+ /** Uniform random float on the range [min, max] */
+ virtual float uniform(float low, float high);
+
+ /** Uniform random float on the range [0, 1] */
+ virtual float uniform();
+
+ // gaussian is inherited
+
+ /** Returns 3D unit vectors distributed according to
+ a cosine distribution about the z axis. */
+ virtual void cosHemi(float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors distributed according to a cosine
+ power distribution (\f$ \mbox{cos}^k \theta \f$) about
+ the z-axis. */
+ virtual void cosPowHemi(const float k, float& x, float& y, float& z);
+
+ // hemi is inherited
+
+ /** Returns 3D unit vectors uniformly distributed on the sphere */
+ virtual void sphere(float& x, float& y, float& z);
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Quat.h b/dep/include/g3dlite/G3D/Quat.h
index 5fc30e8ec49..9ef3d57b301 100644
--- a/dep/include/g3dlite/G3D/Quat.h
+++ b/dep/include/g3dlite/G3D/Quat.h
@@ -1,16 +1,16 @@
/**
@file Quat.h
-
+
Quaternion
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2002-01-23
- @edited 2006-05-10
+ @edited 2009-05-10
*/
-#ifndef G3D_QUAT_H
-#define G3D_QUAT_H
+#ifndef G3D_Quat_h
+#define G3D_Quat_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
@@ -27,11 +27,11 @@ namespace G3D {
A quaternion represents the sum of a real scalar and
an imaginary vector: ix + jy + kz + w. A unit quaternion
- representing a rotation by A about axis v has the form
+ representing a rotation by A about axis v has the form
[sin(A/2)*v, cos(A/2)]. For a unit quaternion, q.conj() == q.inverse()
is a rotation by -A about v. -q is the same rotation as q
- (negate both the axis and angle).
-
+ (negate both the axis and angle).
+
A non-unit quaterion q represents the same rotation as
q.unitize() (Dam98 pg 28).
@@ -56,9 +56,9 @@ public:
/**
q = [sin(angle / 2) * axis, cos(angle / 2)]
-
+
In Watt & Watt's notation, s = w, v = (x, y, z)
- In the Real-Time Rendering notation, u = (x, y, z), w = w
+ In the Real-Time Rendering notation, u = (x, y, z), w = w
*/
float x, y, z, w;
@@ -90,19 +90,19 @@ public:
/** Note: two quats can represent the Quat::sameRotation and not be equal. */
bool fuzzyEq(const Quat& q) {
- return G3D::fuzzyEq(x, q.x) && G3D::fuzzyEq(y, q.y) && G3D::fuzzyEq(z, q.z) && G3D::fuzzyEq(w, q.w);
+ return G3D::fuzzyEq(x, q.x) && G3D::fuzzyEq(y, q.y) && G3D::fuzzyEq(z, q.z) && G3D::fuzzyEq(w, q.w);
}
-
- /** True if these quaternions represent the same rotation (note that every rotation is
+
+ /** True if these quaternions represent the same rotation (note that every rotation is
represented by two values; q and -q).
*/
bool sameRotation(const Quat& q) {
return fuzzyEq(q) || fuzzyEq(-q);
}
- inline Quat operator-() const {
- return Quat(-x, -y, -z, -w);
- }
+ inline Quat operator-() const {
+ return Quat(-x, -y, -z, -w);
+ }
/**
Returns the imaginary part (x, y, z)
@@ -129,34 +129,34 @@ public:
void toAxisAngleRotation(
Vector3& axis,
float& angle) const {
- double d;
- toAxisAngleRotation(axis, d);
- angle = (float)d;
- }
+ double d;
+ toAxisAngleRotation(axis, d);
+ angle = (float)d;
+ }
Matrix3 toRotationMatrix() const;
void toRotationMatrix(
Matrix3& rot) const;
-
+
/**
- Spherical linear interpolation: linear interpolation along the
+ Spherical linear interpolation: linear interpolation along the
shortest (3D) great-circle route between two quaternions.
Note: Correct rotations are expected between 0 and PI in the right order.
@cite Based on Game Physics -- David Eberly pg 538-540
@param threshold Critical angle between between rotations at which
- the algorithm switches to normalized lerp, which is more
- numerically stable in those situations. 0.0 will always slerp.
+ the algorithm switches to normalized lerp, which is more
+ numerically stable in those situations. 0.0 will always slerp.
*/
Quat slerp(
const Quat& other,
float alpha,
float threshold = 0.05f) const;
- /** Normalized linear interpolation of quaternion components. */
- Quat nlerp(const Quat& other, float alpha) const;
+ /** Normalized linear interpolation of quaternion components. */
+ Quat nlerp(const Quat& other, float alpha) const;
/**
Negates the imaginary part.
@@ -177,7 +177,15 @@ public:
return Quat(x * s, y * s, z * s, w * s);
}
- /** @cite Based on Watt & Watt, page 360 */
+ inline Quat& operator*=(float s) {
+ x *= s;
+ y *= s;
+ z *= s;
+ w *= s;
+ return *this;
+ }
+
+ /** @cite Based on Watt & Watt, page 360 */
friend Quat operator* (float s, const Quat& q);
inline Quat operator/(float s) const {
@@ -188,7 +196,7 @@ public:
return (x * other.x) + (y * other.y) + (z * other.z) + (w * other.w);
}
- /** Note that q<SUP>-1</SUP> = q.conj() for a unit quaternion.
+ /** Note that q<SUP>-1</SUP> = q.conj() for a unit quaternion.
@cite Dam99 page 13 */
inline Quat inverse() const {
return conj() / dot(*this);
@@ -209,10 +217,12 @@ public:
return (*this) * other.inverse();
}
+
/** Is the magnitude nearly 1.0? */
inline bool isUnit(float tolerance = 1e-5) const {
return abs(dot(*this) - 1.0f) < tolerance;
}
+
inline float magnitude() const {
return sqrtf(dot(*this));
@@ -225,7 +235,7 @@ public:
} else if (w < 0) {
// Log of a negative number. Multivalued, any number of the form
// (PI * v, ln(-q.w))
- return Quat((float)G3D_PI, 0, 0, ::logf(-w));
+ return Quat((float)pi(), 0, 0, ::logf(-w));
} else {
// log of zero!
return Quat((float)nan(), (float)nan(), (float)nan(), (float)nan());
@@ -240,18 +250,18 @@ public:
}
}
/** log q = [Av, 0] where q = [sin(A) * v, cos(A)].
- Only for unit quaternions
+ Only for unit quaternions
debugAssertM(isUnit(), "Log only defined for unit quaternions");
// Solve for A in q = [sin(A)*v, cos(A)]
Vector3 u(x, y, z);
double len = u.magnitude();
if (len == 0.0) {
- return
+ return
}
double A = atan2((double)w, len);
Vector3 v = u / len;
-
+
return Quat(v * A, 0);
}
*/
@@ -266,6 +276,7 @@ public:
return Quat(sinf(A) * v, cosf(A));
}
+
/**
Raise this quaternion to a power. For a rotation, this is
the effect of rotating x times as much as the original
@@ -278,16 +289,10 @@ public:
return (log() * x).exp();
}
- /**
- @deprecated
- Use toUnit()
- */
- inline Quat unitize() const {
+ inline void unitize() {
float mag2 = dot(*this);
- if (G3D::fuzzyEq(mag2, 1.0f)) {
- return *this;
- } else {
- return *this / sqrtf(mag2);
+ if (! G3D::fuzzyEq(mag2, 1.0f)) {
+ *this *= rsq(mag2);
}
}
@@ -296,7 +301,9 @@ public:
the magnitude.
*/
inline Quat toUnit() const {
- return unitize();
+ Quat x = *this;
+ x.unitize();
+ return x;
}
/**
@@ -317,11 +324,14 @@ public:
const float& operator[] (int i) const;
float& operator[] (int i);
- /** Generate uniform random unit quaternion (i.e. random "direction")
- @cite From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III.
+ /** Generate uniform random unit quaternion (i.e. random "direction")
+ @cite From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III.
*/
static Quat unitRandom();
+ void deserialize(class BinaryInput& b);
+ void serialize(class BinaryOutput& b) const;
+
// 2-char swizzles
Vector2 xx() const;
@@ -684,6 +694,26 @@ inline G3D::Quat operator*(float s, const G3D::Quat& q) {
return q * s;
}
+inline float& Quat::operator[] (int i) {
+ debugAssert(i >= 0);
+ debugAssert(i < 4);
+ return ((float*)this)[i];
+}
+
+inline const float& Quat::operator[] (int i) const {
+ debugAssert(i >= 0);
+ debugAssert(i < 4);
+ return ((float*)this)[i];
+}
+
+inline Quat Quat::operator-(const Quat& other) const {
+ return Quat(x - other.x, y - other.y, z - other.z, w - other.w);
+}
+
+inline Quat Quat::operator+(const Quat& other) const {
+ return Quat(x + other.x, y + other.y, z + other.z, w + other.w);
+}
+
} // Namespace G3D
// Outside the namespace to avoid overloading confusion for C++
@@ -691,7 +721,5 @@ inline G3D::Quat pow(const G3D::Quat& q, double x) {
return q.pow((float)x);
}
-#include "Quat.inl"
#endif
-
diff --git a/dep/include/g3dlite/G3D/Queue.h b/dep/include/g3dlite/G3D/Queue.h
new file mode 100644
index 00000000000..36573265d1a
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Queue.h
@@ -0,0 +1,364 @@
+/**
+ @file Queue.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2002-07-09
+ @edited 2008-12-20
+ */
+
+#ifndef G3D_QUEUE_H
+#define G3D_QUEUE_H
+
+#include "G3D/platform.h"
+#include "G3D/System.h"
+#include "G3D/debug.h"
+
+namespace G3D {
+
+/**
+ Locate the indices of the break between of the two
+ sections of the circular queue. These are used to
+ construct two for loops that iterate over the whole
+ sequence without using the modulo operator.
+
+ [0 ... secondEnd) [head .... firstEnd)
+ */
+#define FIND_ENDS \
+ int firstEnd = head + num;\
+ int secondEnd = 0;\
+ if (firstEnd > numAllocated) {\
+ secondEnd = firstEnd - numAllocated;\
+ firstEnd = numAllocated;\
+ }
+
+
+/**
+ Dynamic queue that uses a circular buffer for performance.
+
+ Faster than std::deque for objects with constructors.
+ */
+template <class T>
+class Queue {
+private:
+ //
+ // |<---- num ---->|
+ // [ | | | | | | | | | | | | | ]
+ // ^
+ // |
+ // head
+ //
+ //
+
+ /**
+ Only num elements are initialized.
+ */
+ T* data;
+
+ /**
+ Index of the next element to be dequeue-d in data.
+ */
+ int head;
+
+ /**
+ Number of elements (including head) that are visible and initialized.
+ */
+ int num;
+
+ /**
+ Size of data array in elements.
+ */
+ int numAllocated;
+
+ /** If a clear was needed, assumes it already occured */
+ void _copy(const Queue& other) {
+ debugAssert(data == NULL);
+ data = (T*)System::malloc(sizeof(T) * other.numAllocated);
+ debugAssert(data);
+ head = other.head;
+ num = other.num;
+ numAllocated = other.numAllocated;
+
+ FIND_ENDS;
+
+ for (int i = head; i < firstEnd; ++i) {
+ new (data + i)T(other.data[i]);
+ }
+
+ for (int i = 0; i < secondEnd; ++i) {
+ new (data + i)T(other.data[i]);
+ }
+ }
+
+
+ /**
+ Computes a data array index from a queue position. The queue position
+ may be negative.
+ */
+ inline int index(int i) const {
+ return (head + i + numAllocated) % numAllocated;
+ }
+
+ /**
+ Allocates newSize elements and repacks the array.
+ */
+ void repackAndRealloc(int newSize) {
+ // TODO: shrink queue
+ T* old = data;
+ data = (T*)System::malloc(newSize * sizeof(T));
+ debugAssert(data != NULL);
+
+ FIND_ENDS;
+
+ int j = 0;
+ for (int i = head; i < firstEnd; ++i, ++j) {
+ new (data + j)T(old[i]);
+ (old + i)->~T();
+ }
+
+ for (int i = 0; i < secondEnd; ++i, ++j) {
+ new (data + j)T(old[i]);
+ (old + i)->~T();
+ }
+
+ head = 0;
+ System::free(old);
+ numAllocated = newSize;
+ }
+
+ /**
+ Ensure that there is at least one element between
+ the tail and head, wrapping around in the circular
+ buffer.
+ */
+ inline void reserveSpace() {
+ if (num == numAllocated) {
+ repackAndRealloc(numAllocated * 3 + 20);
+ }
+ }
+
+public:
+
+ Queue() :
+ data(NULL),
+ head(0),
+ num(0),
+ numAllocated(0) {
+ }
+
+
+ /**
+ Copy constructor
+ */
+ Queue(const Queue& other) : data(NULL) {
+ _copy(other);
+ }
+
+
+ /**
+ Destructor does not delete() the objects if T is a pointer type
+ (e.g. T = int*) instead, it deletes the pointers themselves and
+ leaves the objects. Call deleteAll if you want to dealocate
+ the objects referenced.
+ */
+ virtual ~Queue() {
+ clear();
+ }
+
+ /**
+ Insert a new element into the front of the queue
+ (a traditional queue only uses pushBack).
+ */
+ inline void pushFront(const T& e) {
+ reserveSpace();
+
+ // Get the index of head-1
+ int i = index(-1);
+
+ // Call the constructor on the newly exposed element.
+ new (data + i)T(e);
+
+ // Reassign the head to point to this index
+ head = i;
+ ++num;
+ }
+
+ /**
+ Insert a new element at the end of the queue.
+ */
+ inline void pushBack(const T& e) {
+ reserveSpace();
+
+ // Get the index of 1+tail
+ int i = index(num);
+
+ // Initialize that element
+ new (data + i)T(e);
+ ++num;
+ }
+
+ /**
+ pushBack
+ */
+ inline void enqueue(const T& e) {
+ pushBack(e);
+ }
+
+
+ /**
+ Remove the last element from the queue. The queue will never
+ shrink in size. (A typical queue only uses popFront).
+ */
+ inline T popBack() {
+ int tail = index(num - 1);
+ T result(data[tail]);
+
+ // Call the destructor
+ (data + tail)->~T();
+ --num;
+
+ return result;
+ }
+
+ /**
+ Remove the next element from the head of the queue. The queue will never
+ shrink in size. */
+ inline T popFront() {
+ T result(data[head]);
+ // Call the destructor
+ (data + head)->~T();
+ head = (head + 1) % numAllocated;
+ --num;
+ return result;
+ }
+
+
+ /**
+ popFront
+ */
+ inline T dequeue() {
+ return popFront();
+ }
+
+ /**
+ Removes all elements (invoking their destructors).
+
+ @param freeStorage If false, the underlying array is not deallocated
+ (allowing fast push in the future), however, the size of the Queue
+ is reported as zero.
+
+ */
+ void clear(bool freeStorage = true) {
+
+ FIND_ENDS;
+
+ // Invoke the destructors on the elements
+ int i;
+ for (i = head; i < firstEnd; ++i) {
+ (data + i)->~T();
+ }
+
+ for (i = 0; i < secondEnd; ++i) {
+ (data + i)->~T();
+ }
+
+ num = 0;
+ head = 0;
+ if (freeStorage) {
+ numAllocated = 0;
+ System::free(data);
+ data = NULL;
+ }
+ }
+
+ /** Clear without freeing the underlying array. */
+ void fastClear() {
+ clear(false);
+ }
+
+ /**
+ Assignment operator.
+ */
+ Queue& operator=(const Queue& other) {
+ clear();
+ _copy(other);
+ return *this;
+ }
+
+ /**
+ Number of elements in the queue.
+ */
+ inline int size() const {
+ return num;
+ }
+
+ /**
+ Number of elements in the queue.
+ */
+ inline int length() const {
+ return size();
+ }
+
+ /**
+ Performs bounds checks in debug mode
+ */
+ inline T& operator[](int n) {
+ debugAssert((n >= 0) && (n < num));
+ return data[index(n)];
+ }
+
+ /**
+ Performs bounds checks in debug mode
+ */
+ inline const T& operator[](int n) const {
+ debugAssert((n >= 0) && (n < num));
+ return data[index(n)];
+ }
+
+
+ /** Returns the back element */
+ inline const T& last() const {
+ return (*this)[size() - 1];
+ }
+
+ inline T& last() {
+ return (*this)[size() - 1];
+ }
+
+ /**
+ Returns true if the given element is in the queue.
+ */
+ bool contains(const T& e) const {
+ for (int i = 0; i < size(); ++i) {
+ if ((*this)[i] == e) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ Calls delete on all objects[0...size-1]
+ and sets the queue size to zero.
+ */
+ void deleteAll() {
+ FIND_ENDS;
+
+ int i;
+ for (i = 0; i < secondEnd; ++i) {
+ delete data[i];
+ }
+
+ for (i = head; i < firstEnd; ++i) {
+ delete data[i];
+ }
+ clear();
+ }
+};
+
+#undef FIND_ENDS
+
+}; // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Random.h b/dep/include/g3dlite/G3D/Random.h
new file mode 100644
index 00000000000..54491d06f1b
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Random.h
@@ -0,0 +1,139 @@
+/**
+ @file Random.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-01-02
+ @edited 2009-03-20
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_Random_h
+#define G3D_Random_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/GMutex.h"
+
+namespace G3D {
+
+/** Random number generator.
+
+ Threadsafe.
+
+ Useful for generating consistent random numbers across platforms
+ and when multiple threads are involved.
+
+ Uses the Fast Mersenne Twister (FMT-19937) algorithm.
+
+ On average, uniform() runs about 2x-3x faster than rand().
+
+ @cite http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html
+
+ On OS X, Random is about 10x faster than drand48() (which is
+ threadsafe) and 4x faster than rand() (which is not threadsafe).
+ */
+class Random {
+protected:
+
+ /** Constants (important for the algorithm; do not modify) */
+ enum {
+ N = 624,
+ M = 397,
+ R = 31,
+ U = 11,
+ S = 7,
+ T = 15,
+ L = 18,
+ A = 0x9908B0DF,
+ B = 0x9D2C5680,
+ C = 0xEFC60000};
+
+ /**
+ Prevents multiple overlapping calls to generate().
+ */
+ Spinlock lock;
+
+ /** State vector (these are the next N values that will be returned) */
+ uint32* state;
+
+ /** Index into state */
+ int index;
+
+ bool m_threadsafe;
+
+ /** Generate the next N ints, and store them for readback later.
+ Called from bits() */
+ virtual void generate();
+
+ /** For subclasses. The void* parameter is just to distinguish this from the
+ public constructor.*/
+ Random(void*);
+
+public:
+
+ /** \param threadsafe Set to false if you know that this random
+ will only be used on a single thread. This eliminates the
+ lock and improves performance on some platforms.
+ */
+ Random(uint32 seed = 0xF018A4D2, bool threadsafe = true);
+
+ virtual ~Random();
+
+ /** Each bit is random. Subclasses can choose to override just
+ this method and the other methods will all work automatically. */
+ virtual uint32 bits();
+
+ /** Uniform random integer on the range [min, max] */
+ virtual int integer(int min, int max);
+
+ /** Uniform random float on the range [min, max] */
+ virtual inline float uniform(float low, float high) {
+ // We could compute the ratio in double precision here for
+ // about 1.5x slower performance and slightly better
+ // precision.
+ return low + (high - low) * ((float)bits() / (float)0xFFFFFFFFUL);
+ }
+
+ /** Uniform random float on the range [0, 1] */
+ virtual inline float uniform() {
+ // We could compute the ratio in double precision here for
+ // about 1.5x slower performance and slightly better
+ // precision.
+ const float norm = 1.0f / (float)0xFFFFFFFFUL;
+ return (float)bits() * norm;
+ }
+
+ /** Normally distributed reals. */
+ virtual float gaussian(float mean, float stdev);
+
+ /** Returns 3D unit vectors distributed according to
+ a cosine distribution about the z-axis. */
+ virtual void cosHemi(float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors distributed according to a cosine
+ power distribution (\f$ \cos^k \theta \f$) about
+ the z-axis. */
+ virtual void cosPowHemi(const float k, float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors uniformly distributed on the
+ hemisphere about the z-axis. */
+ virtual void hemi(float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors uniformly distributed on the sphere */
+ virtual void sphere(float& x, float& y, float& z);
+
+ /**
+ A shared instance for when the performance and features but not
+ consistency of the class are desired. It is slightly (10%)
+ faster to use a distinct instance than to use the common one.
+
+ Threadsafe.
+ */
+ static Random& common();
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Ray.h b/dep/include/g3dlite/G3D/Ray.h
index 740f307d88c..80df5828aff 100644
--- a/dep/include/g3dlite/G3D/Ray.h
+++ b/dep/include/g3dlite/G3D/Ray.h
@@ -1,16 +1,16 @@
/**
@file Ray.h
-
+
Ray class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2002-07-12
- @edited 2006-02-21
+ @edited 2009-06-29
*/
-#ifndef G3D_RAY_H
-#define G3D_RAY_H
+#ifndef G3D_Ray_h
+#define G3D_Ray_h
#include "G3D/platform.h"
#include "G3D/Vector3.h"
@@ -23,43 +23,85 @@ namespace G3D {
*/
class Ray {
private:
- Ray(const Vector3& origin, const Vector3& direction) {
- this->origin = origin;
- this->direction = direction;
- }
+ friend class Intersect;
+
+ Vector3 m_origin;
+
+ /** Unit length */
+ Vector3 m_direction;
+
+ /** 1.0 / direction */
+ Vector3 m_invDirection;
+
+
+ // The following are for the "ray slope" optimization from
+ // "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
+ // by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
+ // Computer Graphics Lab, TU Braunschweig, Germany and
+ // University of Koblenz-Landau, Germany*/
+ enum Classification {MMM, MMP, MPM, MPP, PMM, PMP, PPM, PPP, POO, MOO, OPO, OMO, OOP, OOM, OMM, OMP, OPM, OPP, MOM, MOP, POM, POP, MMO, MPO, PMO, PPO}; Classification classification;
+ // ray slope
+ float ibyj, jbyi, kbyj, jbyk, ibyk, kbyi;
+ // Precomputed components
+ float c_xy, c_xz, c_yx, c_yz, c_zx, c_zy;
public:
- Vector3 origin;
- /**
- Not unit length
- */
- Vector3 direction;
+ void set(const Vector3& origin, const Vector3& direction);
+
+ inline const Vector3& origin() const {
+ return m_origin;
+ }
+
+ /** Unit direction vector. */
+ inline const Vector3& direction() const {
+ return m_direction;
+ }
+
+ /** Component-wise inverse of direction vector. May have inf() components */
+ inline const Vector3& invDirection() const {
+ return m_invDirection;
+ }
+
+ inline Ray() {
+ set(Vector3::zero(), Vector3::unitX());
+ }
- Ray() : origin(Vector3::zero()), direction(Vector3::zero()) {}
+ inline Ray(const Vector3& origin, const Vector3& direction) {
+ set(origin, direction);
+ }
- virtual ~Ray() {}
+ Ray(class BinaryInput& b);
+
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
/**
- Creates a Ray from a origin and a (nonzero) direction.
+ Creates a Ray from a origin and a (nonzero) unit direction.
*/
static Ray fromOriginAndDirection(const Vector3& point, const Vector3& direction) {
return Ray(point, direction);
}
- Ray unit() const {
- return Ray(origin, direction.unit());
- }
+ /** Advances the origin along the direction by @a distance */
+ inline Ray bump(float distance) const {
+ return Ray(m_origin + m_direction * distance, m_direction);
+ }
+
+ /** Advances the origin along the @a bumpDirection by @a distance and returns the new ray*/
+ inline Ray bump(float distance, const Vector3& bumpDirection) const {
+ return Ray(m_origin + bumpDirection * distance, m_direction);
+ }
/**
Returns the closest point on the Ray to point.
*/
Vector3 closestPoint(const Vector3& point) const {
- float t = direction.dot(point - this->origin);
+ float t = m_direction.dot(point - m_origin);
if (t < 0) {
- return this->origin;
+ return m_origin;
} else {
- return this->origin + direction * t;
+ return m_origin + m_direction * t;
}
}
@@ -80,7 +122,7 @@ public:
Vector3 intersection(const class Plane& plane) const;
/**
- Returns the distance until intersection with the (solid) sphere.
+ Returns the distance until intersection with the sphere or the (solid) ball bounded by the sphere.
Will be 0 if inside the sphere, inf if there is no intersection.
The ray direction is <B>not</B> normalized. If the ray direction
@@ -90,8 +132,10 @@ public:
See also the G3D::CollisionDetection "movingPoint" methods,
which give more information about the intersection.
+
+ \param solid If true, rays inside the sphere immediately intersect (good for collision detection). If false, they hit the opposite side of the sphere (good for ray tracing).
*/
- float intersectionTime(const class Sphere& sphere) const;
+ float intersectionTime(const class Sphere& sphere, bool solid = false) const;
float intersectionTime(const class Plane& plane) const;
@@ -121,6 +165,7 @@ public:
const Vector3& edge01,
const Vector3& edge02) const;
+
inline float intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
@@ -129,6 +174,7 @@ public:
return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0);
}
+
inline float intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
@@ -140,12 +186,12 @@ public:
return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0, w0, w1, w2);
}
- /* One-sided triangle
+ /* One-sided triangle
*/
inline float intersectionTime(const Triangle& triangle) const {
return intersectionTime(
triangle.vertex(0), triangle.vertex(1), triangle.vertex(2),
- triangle.edge01, triangle.edge02);
+ triangle.edge01(), triangle.edge02());
}
inline float intersectionTime(
@@ -154,7 +200,7 @@ public:
double& w1,
double& w2) const {
return intersectionTime(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2),
- triangle.edge01, triangle.edge02, w0, w1, w2);
+ triangle.edge01(), triangle.edge02(), w0, w1, w2);
}
/** Refracts about the normal
@@ -175,6 +221,7 @@ public:
const Vector3& normal) const;
};
+
#define EPSILON 0.000001
#define CROSS(dest,v1,v2) \
dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
@@ -186,7 +233,7 @@ public:
#define SUB(dest,v1,v2) \
dest[0]=v1[0]-v2[0]; \
dest[1]=v1[1]-v2[1]; \
- dest[2]=v1[2]-v2[2];
+ dest[2]=v1[2]-v2[2];
inline float Ray::intersectionTime(
const Vector3& vert0,
@@ -202,49 +249,51 @@ inline float Ray::intersectionTime(
float u, v;
float tvec[3], pvec[3], qvec[3];
-
+
// begin calculating determinant - also used to calculate U parameter
- CROSS(pvec, direction, edge2);
-
+ CROSS(pvec, m_direction, edge2);
+
// if determinant is near zero, ray lies in plane of triangle
const float det = DOT(edge1, pvec);
-
+
if (det < EPSILON) {
- return (float)inf();
+ return finf();
}
-
+
// calculate distance from vert0 to ray origin
- SUB(tvec, origin, vert0);
-
+ SUB(tvec, m_origin, vert0);
+
// calculate U parameter and test bounds
u = DOT(tvec, pvec);
if ((u < 0.0f) || (u > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
-
+
// prepare to test V parameter
CROSS(qvec, tvec, edge1);
-
+
// calculate V parameter and test bounds
- v = DOT(direction, qvec);
+ v = DOT(m_direction, qvec);
if ((v < 0.0f) || (u + v > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
+
// Case where we don't need correct (u, v):
const float t = DOT(edge2, qvec);
-
+
if (t >= 0.0f) {
// Note that det must be positive
return t / det;
} else {
// We had to travel backwards in time to intersect
- return (float)inf();
+ return finf();
}
}
+
inline float Ray::intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
@@ -264,37 +313,37 @@ inline float Ray::intersectionTime(
float tvec[3], pvec[3], qvec[3];
// begin calculating determinant - also used to calculate U parameter
- CROSS(pvec, direction, edge2);
-
+ CROSS(pvec, m_direction, edge2);
+
// if determinant is near zero, ray lies in plane of triangle
const float det = DOT(edge1, pvec);
-
+
if (det < EPSILON) {
- return (float)inf();
+ return finf();
}
-
+
// calculate distance from vert0 to ray origin
- SUB(tvec, origin, vert0);
-
+ SUB(tvec, m_origin, vert0);
+
// calculate U parameter and test bounds
u = DOT(tvec, pvec);
if ((u < 0.0f) || (u > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
-
+
// prepare to test V parameter
CROSS(qvec, tvec, edge1);
-
+
// calculate V parameter and test bounds
- v = DOT(direction, qvec);
+ v = DOT(m_direction, qvec);
if ((v < 0.0f) || (u + v > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
-
+
float t = DOT(edge2, qvec);
-
+
if (t >= 0) {
const float inv_det = 1.0f / det;
t *= inv_det;
@@ -308,7 +357,7 @@ inline float Ray::intersectionTime(
return t;
} else {
// We had to travel backwards in time to intersect
- return (float)inf();
+ return finf();
}
}
@@ -320,4 +369,3 @@ inline float Ray::intersectionTime(
}// namespace
#endif
-
diff --git a/dep/include/g3dlite/G3D/Rect2D.h b/dep/include/g3dlite/G3D/Rect2D.h
new file mode 100644
index 00000000000..2fb58c50465
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Rect2D.h
@@ -0,0 +1,417 @@
+/**
+ @file Rect2D.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-11-13
+ @created 2009-11-16
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Rect2D_h
+#define G3D_Rect2D_h
+
+// Linux defines this as a macro
+#ifdef border
+#undef border
+#endif
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Vector2.h"
+
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
+
+namespace G3D {
+
+class Any;
+
+/**
+ If you are using this class for pixel rectangles, keep in mind that the last
+ pixel you can draw to is at x0() + width() - 1.
+ */
+class Rect2D {
+private:
+ Vector2 min, max;
+
+ /**
+ Returns true if the whole polygon is clipped.
+ @param p Value of the point
+ @param axis Index [0 or 1] of the axis to clip along?
+ @param clipGreater Are we clipping greater than or less than the line?
+ @param inPoly Polygon being clipped
+ @param outPoly The clipped polygon
+ */
+ template<class T>
+ static bool clipSide2D(
+ const float p, bool clipGreater, int axis,
+ const Array<T>& inPoly, Array<T>& outPoly) {
+
+ outPoly.clear();
+ int i0 = -1;
+
+ Vector2 pt1;
+ bool c1 = true;
+
+ float negate = clipGreater ? -1 : 1;
+
+ // Find a point that is not clipped
+ for (i0 = 0; (i0 < inPoly.length()) && c1; ++i0) {
+ pt1 = inPoly[i0];
+ c1 = (negate * pt1[axis]) < (negate * p);
+ }
+
+ // We incremented i0 one time to many
+ --i0;
+
+ if (c1) {
+ // We could not find an unclipped point
+ return true;
+ }
+
+ outPoly.append(pt1);
+
+ // for each point in inPoly,
+ // if the point is outside the side and the previous one was also outside, continue
+ // if the point is outside the side and the previous one was inside, cut the line
+ // if the point is inside the side and the previous one was also inside, append the points
+ // if the point is inside the side and the previous one was outside, cut the line
+ for (int i = 1; i <= inPoly.length(); ++i) {
+ T pt2 = inPoly[(i + i0) % inPoly.length()];
+ bool c2 = (negate * pt2[axis]) < (negate * p);
+
+ if (c1 ^ c2) {
+
+ if (!c1 && c2 && (i > 1)) {
+ // Unclipped to clipped trasition and not the first iteration
+ outPoly.append(pt1);
+ }
+
+ // only one point is clipped, find where the line crosses the clipping plane
+
+
+ float alpha;
+ if (pt2[axis] == pt1[axis]) {
+ alpha = 0;
+ } else {
+ alpha = (p - pt1[axis]) / (pt2[axis] - pt1[axis]);
+ }
+ outPoly.append(pt1.lerp(pt2, alpha));
+ } else if (! (c1 || c2) && (i != 1)) {
+ // neither point is clipped (don't do this the first time
+ // because we appended the first pt before the loop)
+ outPoly.append(pt1);
+ }
+
+ pt1 = pt2;
+ c1 = c2;
+ }
+
+ return false;
+ }
+
+public:
+
+ /** \param any Must either Rect2D::xywh(#, #, #, #) or Rect2D::xyxy(#, #, #, #)*/
+ Rect2D(const Any& any);
+
+ /** Converts the Rect2D to an Any. */
+ operator Any() const;
+
+ Rect2D() : min(0, 0), max(0, 0) {}
+
+ /** Creates a rectangle at 0,0 with the given width and height*/
+ Rect2D(const Vector2& wh) : min(0, 0), max(wh.x, wh.y) {}
+
+ /** Computes a rectangle that contains both @a a and @a b.
+ Note that even if @a or @b has zero area, its origin will be included.*/
+ Rect2D(const Rect2D& a, const Rect2D& b) {
+ min = a.min.min(b.min);
+ max = a.max.max(b.max);
+ }
+
+ /** @brief Uniformly random point on the interior */
+ Vector2 randomPoint() const {
+ return Vector2(uniformRandom(0, max.x - min.x) + min.x,
+ uniformRandom(0, max.y - min.y) + min.y);
+ }
+
+ float width() const {
+ return max.x - min.x;
+ }
+
+ float height() const {
+ return max.y - min.y;
+ }
+
+ float x0() const {
+ return min.x;
+ }
+
+ float x1() const {
+ return max.x;
+ }
+
+ float y0() const {
+ return min.y;
+ }
+
+ float y1() const {
+ return max.y;
+ }
+
+ /** Min, min corner */
+ Vector2 x0y0() const {
+ return min;
+ }
+
+ Vector2 x1y0() const {
+ return Vector2(max.x, min.y);
+ }
+
+ Vector2 x0y1() const {
+ return Vector2(min.x, max.y);
+ }
+
+ /** Max,max corner */
+ Vector2 x1y1() const {
+ return max;
+ }
+
+ /** Width and height */
+ Vector2 wh() const {
+ return max - min;
+ }
+
+ Vector2 center() const {
+ return (max + min) * 0.5;
+ }
+
+ float area() const {
+ return width() * height();
+ }
+
+ bool isFinite() const {
+ return (min.isFinite() && max.isFinite());
+ }
+
+ Rect2D lerp(const Rect2D& other, float alpha) const {
+ Rect2D out;
+
+ out.min = min.lerp(other.min, alpha);
+ out.max = max.lerp(other.max, alpha);
+
+ return out;
+ }
+
+ static Rect2D xyxy(float x0, float y0, float x1, float y1) {
+ Rect2D r;
+
+ r.min.x = G3D::min(x0, x1);
+ r.min.y = G3D::min(y0, y1);
+ r.max.x = G3D::max(x0, x1);
+ r.max.y = G3D::max(y0, y1);
+
+ return r;
+ }
+
+ static Rect2D xyxy(const Vector2& v0, const Vector2& v1) {
+ Rect2D r;
+
+ r.min = v0.min(v1);
+ r.max = v0.max(v1);
+
+ return r;
+ }
+
+ static Rect2D xywh(float x, float y, float w, float h) {
+ return xyxy(x, y, x + w, y + h);
+ }
+
+ static Rect2D xywh(const Vector2& v, const Vector2& w) {
+ return xyxy(v.x, v.y, v.x + w.x, v.y + w.y);
+ }
+
+ /** Constructs a Rect2D with infinite boundaries.
+ Use isFinite() to test either min or max.
+ */
+ static Rect2D inf() {
+ return xyxy(Vector2::inf(), Vector2::inf());
+ }
+
+ bool contains(const Vector2& v) const {
+ return (v.x >= min.x) && (v.y >= min.y) && (v.x <= max.x) && (v.y <= max.y);
+ }
+
+ bool contains(const Rect2D& r) const {
+ return (min.x <= r.min.x) && (min.y <= r.min.y) &&
+ (max.x >= r.max.x) && (max.y >= r.max.y);
+ }
+
+ /** True if there is non-zero area to the intersection between @a this and @a r.
+ Note that two rectangles that are adjacent do not intersect because there is
+ zero area to the overlap, even though one of them "contains" the corners of the other.*/
+ bool intersects(const Rect2D& r) const {
+ return (min.x < r.max.x) && (min.y < r.max.y) &&
+ (max.x > r.min.x) && (max.y > r.min.y);
+ }
+
+ /** Like intersection, but counts the adjacent case as touching. */
+ bool intersectsOrTouches(const Rect2D& r) const {
+ return (min.x <= r.max.x) && (min.y <= r.max.y) &&
+ (max.x >= r.min.x) && (max.y >= r.min.y);
+ }
+
+ Rect2D operator*(float s) const {
+ return xyxy(min.x * s, min.y * s, max.x * s, max.y * s);
+ }
+
+ Rect2D operator/(float s) const {
+ return xyxy(min / s, max / s);
+ }
+
+ Rect2D operator/(const Vector2& s) const {
+ return xyxy(min / s, max / s);
+ }
+
+ Rect2D operator+(const Vector2& v) const {
+ return xyxy(min + v, max + v);
+ }
+
+ Rect2D operator-(const Vector2& v) const {
+ return xyxy(min - v, max - v);
+ }
+
+ bool operator==(const Rect2D& other) const {
+ return (min == other.min) && (max == other.max);
+ }
+
+ bool operator!=(const Rect2D& other) const {
+ return (min != other.min) || (max != other.max);
+ }
+
+ /** Returns the corners in the order: (min,min), (max,min), (max,max), (min,max). */
+ Vector2 corner(int i) const {
+ debugAssert(i >= 0 && i < 4);
+ switch (i & 3) {
+ case 0:
+ return Vector2(min.x, min.y);
+ case 1:
+ return Vector2(max.x, min.y);
+ case 2:
+ return Vector2(max.x, max.y);
+ case 3:
+ return Vector2(min.x, max.y);
+ default:
+ // Should never get here
+ return Vector2(0, 0);
+ }
+ }
+
+
+ /** @deprecated
+ @sa expand() */
+ Rect2D border(float delta) const {
+ return Rect2D::xywh(x0() + delta,
+ y0() + delta,
+ width() - 2.0f * delta,
+ height() - 2.0f * delta);
+ }
+
+ /** Returns a new Rect2D that is bigger/smaller by the specified amount
+ (negative is shrink.) */
+ Rect2D expand(float delta) const {
+ float newX = x0() - delta;
+ float newY = y0() - delta;
+ float newW = width() + 2.0f * delta;
+ float newH = height() + 2.0f * delta;
+
+ if (newW < 0.0f) {
+ newX = (x0() + width()) / 2.0f;
+ newW = 0.0f;
+ }
+
+ if (newH < 0.0f) {
+ newY = (y0() + height()) / 2.0f;
+ newH = 0.0f;
+ }
+ return Rect2D::xywh(newX, newY, newW, newH);
+ }
+
+ /**
+ Clips so that the rightmost point of the outPoly is at rect.x1 (e.g. a 800x600 window produces
+ rightmost point 799, not 800). The results are suitable for pixel rendering if iRounded.
+ Templated so that it will work for Vector2,3,4 (the z and w components are interpolated linearly).
+ The template parameter must define T.lerp and contain x and y components.
+
+ If the entire polygon is clipped by a single side, the result will be empty.
+ The result might also have zero area but not be empty.
+ */
+ template<class T>
+ void clip(const Array<T>& inPoly, Array<T>& outPoly) const {
+
+ const bool greaterThan = true;
+ const bool lessThan = false;
+ const int X = 0;
+ const int Y = 1;
+
+ Array<T> temp;
+
+ bool entirelyClipped =
+ clipSide2D(x0(), lessThan, X, inPoly, temp) ||
+ clipSide2D(x1(), greaterThan, X, temp, outPoly) ||
+ clipSide2D(y0(), lessThan, Y, outPoly, temp) ||
+ clipSide2D(y1(), greaterThan, Y, temp, outPoly);
+
+ if (entirelyClipped) {
+ outPoly.clear();
+ }
+ }
+
+
+ /** Returns the largest, centered Rect2D that can fit inside this
+ while maintaining the aspect ratio of x:y. Convenient for
+ displaying images in odd-shaped windows.
+ */
+ Rect2D largestCenteredSubRect(float ww, float hh) const {
+ float textureAspect = hh / ww;
+ float viewAspect = height() / width();
+
+ if (viewAspect > textureAspect) {
+ // The view is too tall
+ float h = width() * textureAspect;
+ float y = (height() - h) / 2;
+ return Rect2D::xywh(0, y, width(), h) + corner(0);
+ } else {
+ // The view is too wide
+ float w = height() / textureAspect;
+ float x = (width() - w) / 2;
+ return Rect2D::xywh(x, 0, w, height()) + corner(0);
+ }
+ }
+
+ /**
+ Returns the overlap region between the two rectangles. This may have zero area
+ if they do not intersect. See the two-Rect2D constructor for a way to compute
+ a union-like rectangle.
+ */
+ Rect2D intersect(const Rect2D& other) const {
+ if (intersects(other)) {
+ return Rect2D::xyxy(min.max(other.min), max.min(other.max));
+ }else{
+ return Rect2D::xywh(0, 0, 0, 0);
+ }
+ }
+};
+
+typedef Rect2D AABox2D;
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/ReferenceCount.h b/dep/include/g3dlite/G3D/ReferenceCount.h
new file mode 100644
index 00000000000..84591c6d8e5
--- /dev/null
+++ b/dep/include/g3dlite/G3D/ReferenceCount.h
@@ -0,0 +1,570 @@
+/**
+ @file ReferenceCount.h
+
+ Reference Counting Garbage Collector for C++
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Adapted and extended from Justin Miller's "RGC" class that appeared in BYTE magazine.
+ @cite See also http://www.jelovic.com/articles/cpp_without_memory_errors_slides.htm
+
+ @created 2001-10-23
+ @edited 2009-04-25
+*/
+#ifndef G3D_ReferenceCount_h
+#define G3D_ReferenceCount_h
+
+#include "G3D/platform.h"
+#include "G3D/debug.h"
+#include "G3D/AtomicInt32.h"
+
+namespace G3D {
+
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
+/** Base class for WeakReferenceCountedPointer */
+class _WeakPtr {
+public:
+ inline virtual ~_WeakPtr() {}
+
+protected:
+ friend class ReferenceCountedObject;
+
+ /** Called by ReferenceCountedObject to tell a weak pointer that its underlying object was collected. */
+ virtual void objectCollected() = 0;
+};
+
+/** Used internally by ReferenceCountedObject */
+class _WeakPtrLinkedList {
+public:
+ _WeakPtr* weakPtr;
+ _WeakPtrLinkedList* next;
+
+ inline _WeakPtrLinkedList() : weakPtr(NULL), next(NULL) {}
+
+ /** Inserts this node into the head of the list that previously had n as its head. */
+ inline _WeakPtrLinkedList(_WeakPtr* p, _WeakPtrLinkedList* n) : weakPtr(p), next(n) {}
+};
+
+/**
+ Objects that are reference counted inherit from this. Subclasses
+ <B>must</B> have a public destructor (the default destructor is fine)
+ and <B>publicly</B> inherit ReferenceCountedObject.
+
+ Multiple inheritance from a reference counted object is dangerous-- use
+ at your own risk.
+
+ ReferenceCountedPointer and ReferenceCountedObject are threadsafe.
+ You can create and drop references on multiple threads without
+ violating integrity. WeakReferenceCountedPointer is <i>not</i>
+ threadsafe. Introducing a weak pointer destroys all thread safety,
+ even for strong pointers to the same object (this is inherent in the
+ design of the class; we cannot fix it without slowing down the
+ performance of reference counted objects.)
+
+ <B>Usage Example</B>
+
+ <PRE>
+
+class Foo : public G3D::ReferenceCountedObject {
+public:
+ int x;
+};
+
+class Bar : public Foo {};
+
+typedef G3D::ReferenceCountedPointer<Foo> FooRef;
+typedef G3D::WeakReferenceCountedPointer<Foo> WeakFooRef;
+typedef G3D::ReferenceCountedPointer<Bar> BarRef;
+
+
+int main(int argc, char *argv[]) {
+
+ WeakFooRef x;
+
+ {
+ FooRef a = new Foo();
+
+ // Reference count == 1
+
+ x = a;
+ // Weak references do not increase count
+
+ {
+ FooRef b = a;
+ // Reference count == 2
+ }
+
+ // Reference count == 1
+ }
+ // No more strong references; object automatically deleted.
+ // x is set to NULL automatically.
+
+ // Example of using dynamic cast on reference counted objects
+ BarRef b = new Bar();
+
+ // No cast needed to go down the heirarchy.
+ FooRef f = b;
+
+ // We can't cast the reference object because it is a class.
+ // Instead we must extract the pointer and cast that:
+ b = dynamic_cast<Bar*>(&*f);
+
+ return 0;
+}
+</PRE>
+ */
+class ReferenceCountedObject {
+public:
+
+ /**
+ The long name is to keep this from accidentally conflicting with
+ a subclass's variable name. Do not use or explicitly manipulate
+ this value--its type may change in the future and is not part
+ of the supported API.
+ */
+ AtomicInt32 ReferenceCountedObject_refCount;
+
+ /**
+ Linked list of all weak pointers that reference this (some may be
+ on the stack!). Do not use or explicitly manipulate this value.
+ */
+ _WeakPtrLinkedList* ReferenceCountedObject_weakPointer;
+
+protected:
+
+ ReferenceCountedObject();
+
+public:
+
+ /** Automatically called immediately before the object is deleted.
+ This is not called from the destructor because it needs to be invoked
+ before the subclass destructor.
+ */
+ void ReferenceCountedObject_zeroWeakPointers();
+
+ virtual ~ReferenceCountedObject();
+
+
+ /**
+ Note: copies will initially start out with 0
+ references and 0 weak references like any other object.
+ */
+ ReferenceCountedObject(const ReferenceCountedObject& notUsed);
+
+ ReferenceCountedObject& operator=(const ReferenceCountedObject& other);
+};
+
+
+
+/**
+ Use ReferenceCountedPointer<T> in place of T* in your program.
+ T must subclass ReferenceCountedObject.
+@deprecated To be replaced by boost::shared_ptr in 7.0
+ */
+template <class T>
+class ReferenceCountedPointer {
+private:
+
+ T* m_pointer;
+
+public:
+ typedef T element_type;
+
+ inline T* pointer() const {
+ return m_pointer;
+ }
+
+private:
+
+ /** Nulls out the pointer and drops a reference. If the reference
+ count hits zero. */
+ void zeroPointer() {
+ if (m_pointer != NULL) {
+
+ ReferenceCountedObject* pointer = ((ReferenceCountedObject*)m_pointer);
+ debugAssert(G3D::isValidHeapPointer(m_pointer));
+ debugAssertM(pointer->ReferenceCountedObject_refCount.value() > 0,
+ "Dangling reference detected.");
+
+ // Only delete if this instance caused the count to hit
+ // exactly zero. If there is a race condition, the value
+ // may be zero after decrement returns, but only one of
+ // the instances will get a zero return value.
+ if (pointer->ReferenceCountedObject_refCount.decrement() == 0) {
+ // We held the last reference, so delete the object.
+ // This test is threadsafe because there is no way for
+ // the reference count to increase after the last
+ // reference was dropped (assuming the application does
+ // not voilate the class abstraction).
+ //debugPrintf(" delete 0x%x\n", m_pointer);
+
+ // We must zero the weak pointers *before* deletion in case there
+ // are cycles of weak references.
+ // Note that since there are no strong references at this point,
+ // it is perfectly fair to zero the weak pointers anyway.
+ pointer->ReferenceCountedObject_zeroWeakPointers();
+ delete pointer;
+ }
+
+ m_pointer = NULL;
+ }
+ }
+
+ /** Non-atomic (except for the referencec increment). Can only be
+ called in contexts like the copy constructor or initial
+ constructor where it is known that the reference count will
+ not hit zero on some other thread. */
+ void setPointer(T* x) {
+ if (x != m_pointer) {
+ zeroPointer();
+
+ if (x != NULL) {
+ debugAssert(G3D::isValidHeapPointer(x));
+
+ m_pointer = x;
+
+ // Note that the ref count can be zero if this is the
+ // first pointer to it
+ ReferenceCountedObject* pointer = (ReferenceCountedObject*)m_pointer;
+ debugAssertM(pointer->ReferenceCountedObject_refCount.value() >= 0,
+ "Negative reference count detected.");
+ pointer->ReferenceCountedObject_refCount.increment();
+ }
+ }
+ }
+
+public:
+
+ inline ReferenceCountedPointer() : m_pointer(NULL) {}
+
+ /**
+ Allow silent cast <i>to</i> the base class.
+
+ <pre>
+ SubRef s = new Sub();
+ BaseRef b = s;
+ </pre>
+
+ i.e., compile-time subtyping rule
+ RCP&lt;<I>T</I>&gt; &lt;: RCP&lt;<I>S</I>&gt; if <I>T</I> &lt;: <I>S</I>
+ */
+ template <class S>
+ inline ReferenceCountedPointer(const ReferenceCountedPointer<S>& p) :
+ m_pointer(NULL) {
+ setPointer(p.pointer());
+ }
+
+# if (! defined(MSC_VER) || (MSC_VER >= 1300))
+ /**
+ Explicit cast to a subclass. Acts like dynamic cast; the result will be NULL if
+ the cast cannot succeed. Not supported on VC6.
+ <pre>
+ SubRef s = new Sub();
+ BaseRef b = s;
+ s = b.downcast<Sub>(); // Note that the template argument is the object type, not the pointer type.
+ </pre>
+ */
+ template <class S>
+ ReferenceCountedPointer<S> downcast() {
+ return ReferenceCountedPointer<S>(dynamic_cast<S*>(m_pointer));
+ }
+
+ template <class S>
+ const ReferenceCountedPointer<S> downcast() const {
+ return ReferenceCountedPointer<S>(dynamic_cast<const S*>(m_pointer));
+ }
+# endif
+
+ // We need an explicit version of the copy constructor as well or
+ // the default copy constructor will be used.
+ inline ReferenceCountedPointer(const ReferenceCountedPointer<T>& p) : m_pointer(NULL) {
+ setPointer(p.m_pointer);
+ }
+
+ /** Allows construction from a raw pointer. That object will thereafter be
+ reference counted -- do not call delete on it.
+
+ Use of const allows downcast on const references */
+ inline ReferenceCountedPointer(const T* p) : m_pointer(NULL) {
+ // only const constructor is defined to remove ambiguity using NULL
+ setPointer(const_cast<T*>(p));
+ }
+
+
+ inline ~ReferenceCountedPointer() {
+ zeroPointer();
+ }
+
+ inline size_t hashCode() const {
+ return reinterpret_cast<size_t>(m_pointer);;
+ }
+
+ inline const ReferenceCountedPointer<T>& operator=(const ReferenceCountedPointer<T>& p) {
+ setPointer(p.m_pointer);
+ return *this;
+ }
+
+ inline ReferenceCountedPointer<T>& operator=(T* p) {
+ setPointer(p);
+ return *this;
+ }
+
+ inline bool operator==(const ReferenceCountedPointer<T>& y) const {
+ return (m_pointer == y.m_pointer);
+ }
+
+ inline bool operator!=(const ReferenceCountedPointer<T>& y) const {
+ return (m_pointer != y.m_pointer);
+ }
+
+ bool operator < (const ReferenceCountedPointer<T>& y) const {
+ return (m_pointer < y.m_pointer);
+ }
+
+ bool operator > (const ReferenceCountedPointer<T>& y) const {
+ return (m_pointer > y.m_pointer);
+ }
+
+ bool operator <= (const ReferenceCountedPointer<T>& y) const {
+ return (m_pointer <= y.m_pointer);
+ }
+
+ bool operator >= (const ReferenceCountedPointer<T>& y) const {
+ return (m_pointer >= y.m_pointer);
+ }
+
+ inline T& operator*() const {
+ debugAssertM(m_pointer != NULL, "Dereferenced a NULL ReferenceCountedPointer");
+ return (*m_pointer);
+ }
+
+ inline T* operator->() const {
+ debugAssertM(m_pointer != NULL, "Dereferenced a NULL ReferenceCountedPointer");
+ return m_pointer;
+ }
+
+ inline bool isNull() const {
+ return (m_pointer == NULL);
+ }
+
+ inline bool notNull() const {
+ return (m_pointer != NULL);
+ }
+
+ // TODO: distinguish between last strong and last any pointer
+ /**
+ Returns true if this is the last reference to an object.
+ Useful for flushing memoization caches-- a cache that holds the last
+ reference is unnecessarily keeping an object alive.
+
+ <b>Not threadsafe.</b>
+
+ @deprecated Use WeakReferenceCountedPointer for caches
+ */
+ inline int isLastReference() const {
+ return (m_pointer->ReferenceCountedObject_refCount.value() == 1);
+ }
+};
+
+
+/**
+ A weak pointer allows the object it references to be garbage collected.
+ Weak pointers are commonly used in caches, where it is important to hold
+ a pointer to an object without keeping that object alive solely for the
+ cache's benefit (i.e., the object can be collected as soon as all
+ pointers to it <B>outside</B> the cache are gone). They are also convenient
+ for adding back-pointers in tree and list structures.
+
+ Weak pointers may become NULL at any point (when their target is collected).
+ Therefore the only way to reference the target is to convert to a strong
+ pointer and then check that it is not NULL.
+
+@deprecated To be replaced by boost::weak_ptr in 7.0
+ */
+template <class T>
+class WeakReferenceCountedPointer : public _WeakPtr {
+private:
+
+ /** NULL if the object has been collected. */
+ T* pointer;
+
+public:
+ /**
+ Creates a strong pointer, which prevents the object from being
+ garbage collected. The strong pointer may be NULL, which means
+ that the underlying.
+ */
+ // There is intentionally no way to check if the
+ // WeakReferenceCountedPointer has a null reference without
+ // creating a strong pointer since there is no safe way to use
+ // that information-- the pointer could be collected by a
+ // subsequent statement.
+ ReferenceCountedPointer<T> createStrongPtr() const {
+ // TODO: What if the object's destructor is called while we
+ // are in this method?
+ return ReferenceCountedPointer<T>(pointer);
+ }
+
+private:
+
+ /** Thread issues: safe because this is only called when another
+ object is guaranteed to keep p alive for the duration of this
+ call. */
+ void setPointer(T* p) {
+ // TODO: must prevent the object from being collected while in
+ // this method
+
+ zeroPointer();
+ pointer = p;
+
+ if (pointer != NULL) {
+ // TODO: threadsafe: must update the list atomically
+
+ // Add myself to the head of my target's list of weak pointers
+ _WeakPtrLinkedList* head =
+ new _WeakPtrLinkedList
+ (this,
+ pointer->ReferenceCountedObject_weakPointer);
+
+ pointer->ReferenceCountedObject_weakPointer = head;
+ } else {
+
+ }
+ }
+
+
+ /**
+ Removes this from its target's list of weak pointers. Called
+ when the weak pointer goes out of scope.
+
+ Thread issues: depends on the thread safety of createStrongPtr.
+ */
+ void zeroPointer() {
+ // Grab a strong reference to prevent the object from being collected while we
+ // are traversing its list.
+ ReferenceCountedPointer<T> strong = createStrongPtr();
+
+ // If the following test fails then the object was collected before we
+ // reached it.
+ if (strong.notNull()) {
+ debugAssertM(((ReferenceCountedObject*)pointer)->ReferenceCountedObject_weakPointer != NULL,
+ "Weak pointer exists without a backpointer from the object.");
+
+ // Remove myself from my target's list of weak pointers
+ _WeakPtrLinkedList** node = &((ReferenceCountedObject*)pointer)->ReferenceCountedObject_weakPointer;
+ while ((*node)->weakPtr != this) {
+ node = &((*node)->next);
+ debugAssertM(*node != NULL,
+ "Weak pointer exists without a backpointer from the object (2).");
+ }
+
+ // Node must now point at the node for me. Remove node and
+ // close the linked list behind it.
+ _WeakPtrLinkedList* temp = *node;
+ *node = temp->next;
+
+ // Now delete the node corresponding to me
+ delete temp;
+ }
+
+ pointer = NULL;
+ }
+
+public:
+
+ WeakReferenceCountedPointer() : pointer(0) {}
+
+ /**
+ Allow compile time subtyping rule
+ RCP&lt;<I>T</I>&gt; &lt;: RCP&lt;<I>S</I>&gt; if <I>T</I> &lt;: <I>S</I>
+ */
+ template <class S>
+ inline WeakReferenceCountedPointer(const WeakReferenceCountedPointer<S>& p) : pointer(0) {
+ // Threadsafe: the object cannot be collected while the other pointer exists.
+ setPointer(p.pointer);
+ }
+
+ template <class S>
+ inline WeakReferenceCountedPointer(const ReferenceCountedPointer<S>& p) : pointer(0) {
+ // Threadsafe: the object cannot be collected while the other
+ // pointer exists.
+ setPointer(p.pointer());
+ }
+
+ // Gets called a *lot* when weak pointers are on the stack
+ WeakReferenceCountedPointer(
+ const WeakReferenceCountedPointer<T>& weakPtr) : pointer(0) {
+ setPointer(weakPtr.pointer);
+ }
+
+ WeakReferenceCountedPointer(
+ const ReferenceCountedPointer<T>& strongPtr) : pointer(0) {
+ setPointer(strongPtr.pointer());
+ }
+
+ ~WeakReferenceCountedPointer() {
+ zeroPointer();
+ }
+
+ WeakReferenceCountedPointer<T>& operator=(const WeakReferenceCountedPointer<T>& other) {
+ // Threadsafe: the object cannot be collected while the other pointer exists.
+
+ // I now point at other's target
+ setPointer(other.pointer);
+
+ return *this;
+ }
+
+ WeakReferenceCountedPointer<T>& operator=(const ReferenceCountedPointer<T>& other) {
+
+ // Threadsafe: the object cannot be collected while the other pointer exists.
+
+ // I now point at other's target
+ setPointer(other.pointer());
+
+ return *this;
+ }
+
+ bool operator==(const WeakReferenceCountedPointer<T>& other) const {
+ return pointer == other.pointer;
+ }
+
+ bool operator!=(const WeakReferenceCountedPointer<T>& other) const {
+ return pointer != other.pointer;
+ }
+
+ bool operator < (const WeakReferenceCountedPointer<T>& y) const {
+ return (pointer < y.pointer);
+ }
+
+ bool operator > (const WeakReferenceCountedPointer<T>& y) const {
+ return (pointer > y.pointer);
+ }
+
+ bool operator <= (const WeakReferenceCountedPointer<T>& y) const {
+ return (pointer <= y.pointer);
+ }
+
+ bool operator >= (const ReferenceCountedPointer<T>& y) const {
+ return (pointer >= y.pointer);
+ }
+
+protected:
+
+ /** Invoked by the destructor on ReferenceCountedPointer. */
+ void objectCollected() {
+ debugAssertM(pointer != NULL,
+ "Removed a weak pointer twice.");
+ pointer = NULL;
+ }
+
+};
+
+} // namespace
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/RegistryUtil.h b/dep/include/g3dlite/G3D/RegistryUtil.h
index 85b5d0ab1be..4b47be5f4bd 100644
--- a/dep/include/g3dlite/G3D/RegistryUtil.h
+++ b/dep/include/g3dlite/G3D/RegistryUtil.h
@@ -21,11 +21,14 @@
namespace G3D {
-/**
+/**
Provides generalized Windows registry querying.
All key names are one string in the format:
- "[base key]\[sub-keys]\value"
+ "[base key]\[sub-keys]"
+
+ A value must now be provided for every query.
+ An empty value string will use the (Default) value.
[base key] can be any of the following:
HKEY_CLASSES_ROOT
@@ -37,45 +40,53 @@ namespace G3D {
HKEY_PERFORMANCE_TEXT
HKEY_USERS
- keyExists() should be used to validate a key before reading or writing
- to ensure that a debug assert or false return is for a different error.
+ valueExists() should be used to validate a key+value before reading or writing
+ to ensure that a debug assert or false return is for a different error during
+ reads and writes.
+
+ All read and write calls will assert when a key will not open for reasons other
+ that it does not exist. All read and write calls will assert when the value cannot
+ be read or written for any reason.
*/
class RegistryUtil {
public:
- /** returns true if the key exists */
+ /** returns true if the key exists and the current user has permission to read */
static bool keyExists(const std::string& key);
+ /** returns true if the key exists and the current user has permission to read */
+ static bool valueExists(const std::string& key, const std::string& value);
+
/** returns false if the key could not be read for any reason. */
- static bool readInt32(const std::string& key, int32& valueData);
+ static bool readInt32(const std::string& key, const std::string& value, int32& data);
- /**
+ /**
Reads an arbitrary amount of data from a binary registry key.
returns false if the key could not be read for any reason.
-
+
@beta
- @param valueData pointer to the output buffer of sufficient size. Pass NULL as valueData in order to have available data size returned in dataSize.
- @param dataSize size of the output buffer. When NULL is passed for valueData, contains the size of available data on successful return.
+ @param data pointer to the output buffer of sufficient size. Pass NULL as data in order to have available data size returned in dataSize.
+ @param dataSize size of the output buffer. When NULL is passed for data, contains the size of available data on successful return.
*/
- static bool readBytes(const std::string& key, uint8* valueData, uint32& dataSize);
+ static bool readBytes(const std::string& key, const std::string& value, uint8* data, uint32& dataSize);
/** returns false if the key could not be read for any reason. */
- static bool readString(const std::string& key, std::string& valueData);
+ static bool readString(const std::string& key, const std::string& value, std::string& data);
/** returns false if the key could not be written for any reason. */
- static bool writeInt32(const std::string& key, int32 valueData);
+ static bool writeInt32(const std::string& key, const std::string& value, int32 data);
- /**
+ /**
Writes an arbitrary amount of data to a binary registry key.
returns false if the key could not be written for any reason.
-
- @param valueData pointer to the input buffer
+
+ @param data pointer to the input buffer
@param dataSize size of the input buffer that should be written
*/
- static bool writeBytes(const std::string& key, const uint8* valueData, uint32 dataSize);
+ static bool writeBytes(const std::string& key, const std::string& value, const uint8* data, uint32 dataSize);
/** returns false if the key could not be written for any reason. */
- static bool writeString(const std::string& key, const std::string& valueData);
+ static bool writeString(const std::string& key, const std::string& value, const std::string& data);
};
@@ -84,4 +95,3 @@ public:
#endif // G3D_WIN32
#endif // G3D_REGISTRYTUIL_H
-
diff --git a/dep/include/g3dlite/G3D/Set.h b/dep/include/g3dlite/G3D/Set.h
new file mode 100644
index 00000000000..9a8e1b619bb
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Set.h
@@ -0,0 +1,186 @@
+/**
+ @file Set.h
+
+ Hash set
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-12-09
+ @edited 2009-06-10
+ */
+
+#ifndef G3D_Set_h
+#define G3D_Set_h
+
+#include "G3D/platform.h"
+#include "G3D/Table.h"
+#include "G3D/MemoryManager.h"
+#include <assert.h>
+#include <string>
+
+namespace G3D {
+
+/**
+ An unordered data structure that has at most one of each element.
+ Provides O(1) time insert, remove, and member test (contains).
+
+ Set uses G3D::Table internally, which means that the template type T
+ must define a hashCode and operator== function. See G3D::Table for
+ a discussion of these functions.
+ */
+// There is not copy constructor or assignment operator defined because
+// the default ones are correct for Set.
+template<class T, class HashFunc = HashTrait<T>, class EqualsFunc = EqualsTrait<T> >
+class Set {
+
+ /**
+ If an object is a member, it is contained in
+ this table.
+ */
+ Table<T, bool, HashFunc, EqualsFunc> memberTable;
+
+public:
+
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ memberTable.clearAndSetMemoryManager(m);
+ }
+
+ virtual ~Set() {}
+
+ int size() const {
+ return (int)memberTable.size();
+ }
+
+ bool contains(const T& member) const {
+ return memberTable.containsKey(member);
+ }
+
+ /**
+ Inserts into the table if not already present.
+ */
+ void insert(const T& member) {
+ memberTable.set(member, true);
+ }
+
+ /**
+ Returns true if the element was present and removed. Returns false
+ if the element was not present.
+ */
+ bool remove(const T& member) {
+ return memberTable.remove(member);
+ }
+
+ /** If @a member is present, sets @a removed to the element
+ being removed and returns true. Otherwise returns false
+ and does not write to @a removed. This is useful when building
+ efficient hashed data structures that wrap Set.
+ */
+ bool getRemove(const T& member, T& removed) {
+ bool ignore;
+ return memberTable.getRemove(member, removed, ignore);
+ }
+
+ /** If a value that is EqualsFunc to @a member is present, returns a pointer to the
+ version stored in the data structure, otherwise returns NULL.
+ */
+ const T* getPointer(const T& member) const {
+ return memberTable.getKeyPointer(member);
+ }
+
+ Array<T> getMembers() const {
+ return memberTable.getKeys();
+ }
+
+ void getMembers(Array<T>& keyArray) const {
+ memberTable.getKeys(keyArray);
+ }
+
+ void clear() {
+ memberTable.clear();
+ }
+
+ void deleteAll() {
+ getMembers().deleteAll();
+ clear();
+ }
+
+ /**
+ C++ STL style iterator variable. See begin().
+ */
+ class Iterator {
+ private:
+ friend class Set<T>;
+
+ // Note: this is a Table iterator, we are currently defining
+ // Set iterator
+ typename Table<T, bool>::Iterator it;
+
+ Iterator(const typename Table<T, bool>::Iterator& it) : it(it) {}
+
+ public:
+ inline bool operator!=(const Iterator& other) const {
+ return !(*this == other);
+ }
+
+ bool hasMore() const {
+ return it.hasMore();
+ }
+
+ bool operator==(const Iterator& other) const {
+ return it == other.it;
+ }
+
+ /**
+ Pre increment.
+ */
+ Iterator& operator++() {
+ ++it;
+ return *this;
+ }
+
+ /**
+ Post increment (slower than preincrement).
+ */
+ Iterator operator++(int) {
+ Iterator old = *this;
+ ++(*this);
+ return old;
+ }
+
+ const T& operator*() const {
+ return it->key;
+ }
+
+ T* operator->() const {
+ return &(it->key);
+ }
+
+ operator T*() const {
+ return &(it->key);
+ }
+ };
+
+
+ /**
+ C++ STL style iterator method. Returns the first member.
+ Use preincrement (++entry) to get to the next element.
+ Do not modify the set while iterating.
+ */
+ Iterator begin() const {
+ return Iterator(memberTable.begin());
+ }
+
+
+ /**
+ C++ STL style iterator method. Returns one after the last iterator
+ element.
+ */
+ const Iterator end() const {
+ return Iterator(memberTable.end());
+ }
+};
+
+}
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/SmallArray.h b/dep/include/g3dlite/G3D/SmallArray.h
new file mode 100644
index 00000000000..41f9959e264
--- /dev/null
+++ b/dep/include/g3dlite/G3D/SmallArray.h
@@ -0,0 +1,155 @@
+/**
+ @file SmallArray.h
+
+ @created 2009-04-26
+ @edited 2009-04-26
+
+ Copyright 2000-2009, Morgan McGuire, http://graphics.cs.williams.edu
+ All rights reserved.
+ */
+#ifndef G3D_SmallArray_h
+#define G3D_SmallArray_h
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+
+namespace G3D {
+
+/** Embeds \a N elements to reduce allocation time and increase
+ memory coherence when working with arrays of arrays.
+ Offers a limited subset of the functionality of G3D::Array.*/
+template<class T, int N>
+class SmallArray {
+private:
+ int m_size;
+
+ /** First N elements */
+ T m_embedded[N];
+
+ /** Remaining elements */
+ Array<T> m_rest;
+
+public:
+
+ SmallArray() : m_size(0) {}
+
+ inline int size() const {
+ return m_size;
+ }
+
+ void resize(int n, bool shrinkIfNecessary = true) {
+ m_rest.resize(std::max(0, n - N), shrinkIfNecessary);
+ m_size = n;
+ }
+
+ void clear(bool shrinkIfNecessary = true) {
+ resize(0, shrinkIfNecessary);
+ }
+
+ inline T& operator[](int i) {
+ debugAssert(i < m_size && i >= 0);
+ if (i < N) {
+ return m_embedded[i];
+ } else {
+ return m_rest[i - N];
+ }
+ }
+
+ inline const T& operator[](int i) const {
+ debugAssert(i < m_size && i >= 0);
+ if (i < N) {
+ return m_embedded[i];
+ } else {
+ return m_rest[i - N];
+ }
+ }
+
+ inline void push(const T& v) {
+ ++m_size;
+ if (m_size <= N) {
+ m_embedded[m_size - 1] = v;
+ } else {
+ m_rest.append(v);
+ }
+ }
+
+ inline void append(const T& v) {
+ push(v);
+ }
+
+ void fastRemove(int i) {
+ debugAssert(i < m_size && i >= 0);
+ if (i < N) {
+ if (m_size <= N) {
+ // Exclusively embedded
+ m_embedded[i] = m_embedded[m_size - 1];
+ } else {
+ // Move one down from the rest array
+ m_embedded[i] = m_rest.pop();
+ }
+ } else {
+ // Removing from the rest array
+ m_rest.fastRemove(i - N);
+ }
+ --m_size;
+ }
+
+ T pop() {
+ debugAssert(m_size > 0);
+ if (m_size <= N) {
+ // Popping from embedded, don't need a temporary
+ --m_size;
+ return m_embedded[m_size];
+ } else {
+ // Popping from rest
+ --m_size;
+ return m_rest.pop();
+ }
+ }
+
+ inline void popDiscard() {
+ debugAssert(m_size > 0);
+ if (m_size > N) {
+ m_rest.popDiscard();
+ }
+ --m_size;
+ }
+
+ inline T& next() {
+ ++m_size;
+ if (m_size <= N) {
+ return m_embedded[m_size - 1];
+ } else {
+ return m_rest.next();
+ }
+ }
+
+ bool contains(const T& value) const {
+ for (int i = std::min(m_size, N) - 1; i >= 0; --i) {
+ if (m_embedded[i] == value) {
+ return true;
+ }
+ }
+ return m_rest.contains(value);
+ }
+
+ template<int MIN_ELEMENTS, int MIN_BYTES>
+ SmallArray<T, N>& operator=(const Array<T, MIN_ELEMENTS, MIN_BYTES>& src) {
+ resize(src.size());
+ for (int i = 0; i < src.size(); ++i) {
+ (*this)[i] = src[i];
+ }
+ return *this;
+ }
+
+ inline const T& last() const {
+ return (*this)[size() - 1];
+ }
+
+ inline T& last() {
+ return (*this)[size() - 1];
+ }
+};
+
+}
+#endif
diff --git a/dep/include/g3dlite/G3D/Sphere.h b/dep/include/g3dlite/G3D/Sphere.h
index 122e4d41f65..595b61c4bf1 100644
--- a/dep/include/g3dlite/G3D/Sphere.h
+++ b/dep/include/g3dlite/G3D/Sphere.h
@@ -1,12 +1,12 @@
/**
@file Sphere.h
-
+
Sphere class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2001-06-02
- @edited 2004-07-05
+ @edited 2008-10-07
*/
#ifndef G3D_SPHERE_H
@@ -36,6 +36,10 @@ public:
radius = 0;
}
+ Sphere(class BinaryInput& b);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
Sphere(
const Vector3& center,
float radius) {
@@ -60,51 +64,49 @@ public:
*/
bool contains(const Vector3& point) const;
-/**
- @deprecated Use culledBy(Array<Plane>&)
- */
- bool culledBy(
- const class Plane* plane,
- int numPlanes,
- int32& cullingPlaneIndex,
- const uint32 testMask,
- uint32& childMask) const;
+ bool contains(const Sphere& other) const;
/**
- @deprecated Use culledBy(Array<Plane>&)
+ @deprecated Use culledBy(Array<Plane>&)
*/
bool culledBy(
- const class Plane* plane,
- int numPlanes,
- int32& cullingPlaneIndex = dummy,
- const uint32 testMask = -1) const;
-
+ const class Plane* plane,
+ int numPlanes,
+ int32& cullingPlaneIndex,
+ const uint32 testMask,
+ uint32& childMask) const;
+
/**
- See AABox::culledBy
+ @deprecated Use culledBy(Array<Plane>&)
*/
bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex,
- const uint32 testMask,
- uint32& childMask) const;
+ const class Plane* plane,
+ int numPlanes,
+ int32& cullingPlaneIndex = dummy,
+ const uint32 testMask = 0xFFFFFFFF) const;
/**
+ See AABox::culledBy
+ */
+ bool culledBy(
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex,
+ const uint32 testMask,
+ uint32& childMask) const;
+
+ /**
Conservative culling test that does not produce a mask for children.
*/
bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex = dummy,
- const uint32 testMask = -1) const;
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex = dummy,
+ const uint32 testMask = 0xFFFFFFFF) const;
+
virtual std::string toString() const;
float volume() const;
- /** @deprecated */
- float surfaceArea() const;
-
- inline float area() const {
- return surfaceArea();
- }
+ float area() const;
/**
Uniformly distributed on the surface.
@@ -117,13 +119,30 @@ public:
Vector3 randomInteriorPoint() const;
void getBounds(class AABox& out) const;
-};
-} // namespace
+ bool intersects(const Sphere& other) const;
+
+ /** Translates the sphere */
+ Sphere operator+(const Vector3& v) const {
+ return Sphere(center + v, radius);
+ }
+
+ /** Translates the sphere */
+ Sphere operator-(const Vector3& v) const {
+ return Sphere(center - v, radius);
+ }
+
+ /** Sets this to the smallest sphere that encapsulates both */
+ void merge(const Sphere& s);
+};
-inline unsigned int hashCode(const G3D::Sphere& sphere) {
- return (unsigned int)(hashCode(sphere.center) + (sphere.radius * 13));
}
-#endif
+template <> struct HashTrait<G3D::Sphere> {
+ static size_t hashCode(const G3D::Sphere& key) {
+ return static_cast<size_t>(key.center.hashCode() + (key.radius * 13));
+ }
+};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Spline.h b/dep/include/g3dlite/G3D/Spline.h
new file mode 100644
index 00000000000..fdd29e69ce9
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Spline.h
@@ -0,0 +1,367 @@
+/**
+ @file Spline.h
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ */
+
+#ifndef G3D_SPLINE_H
+#define G3D_SPLINE_H
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Matrix4.h"
+#include "G3D/Vector4.h"
+
+namespace G3D {
+
+/** Common implementation code for all G3D::Spline template parameters */
+class SplineBase {
+public:
+
+ /** Times at which control points occur. Must have the same
+ number of elements as Spline::control. */
+ Array<float> time;
+
+ /** If cyclic, then the control points will be assumed to wrap around.
+ If not cyclic, then the tangents at the ends of the spline
+ point to the final control points.*/
+ bool cyclic;
+
+ /** For a cyclic spline, this is the time elapsed between the last
+ control point and the first. If less than or equal to zero this is
+ assumed to be:
+
+ (time[0] - time[1] + .
+ time[time.size() - 1] - time[time.size() - 2]) / 2.
+ */
+ float finalInterval;
+
+ SplineBase() : cyclic(true), finalInterval(-1) {}
+
+ virtual ~SplineBase() {}
+
+ /** See specification for Spline::finalInterval; this handles the
+ non-positive case. Returns 0 if not cyclic. */
+ float getFinalInterval() const;
+
+ /** Returns the amount of time covered by this spline in one
+ period. For a cyclic spline, this contains the final
+ interval.*/
+ float duration() const;
+
+ /** Computes the derivative spline basis from the control point version. */
+ static Matrix4 computeBasis();
+
+protected:
+
+ /** Assumes that t0 <= s < tn. called by computeIndex. */
+ void computeIndexInBounds(float s, int& i, float& u) const;
+
+public:
+
+ /**
+ Given a time @a s, finds @a i and 0 <= @a u < 1 such that
+ @a s = time[@a i] * @a u + time[@a i + 1] * (1 - @a u). Note that
+ @a i may be outside the bounds of the time and control arrays;
+ use getControl to handle wraparound and extrapolation issues.
+
+ This function takes expected O(1) time for control points with
+ uniform time sampled control points or for uniformly
+ distributed random time samples, but may take O( log time.size() ) time
+ in the worst case.
+
+ Called from evaluate().
+ */
+ void computeIndex(float s, int& i, float& u) const;
+};
+
+
+/**
+ Smooth parameteric curve implemented using a piecewise 3rd-order
+ Catmull-Rom spline curve. The spline is considered infinite and may
+ either continue linearly from the specified control points or cycle
+ through them. Control points are spaced uniformly in time at unit
+ intervals by default, but irregular spacing may be explicitly
+ specified.
+
+ The dimension of the spline can be set by varying the Control
+ template parameter. For a 1D function, use Spline<float>. For a
+ curve in the plane, Spline<Vector2>. Note that <i>any</i> template
+ parameter that supports operator+(Control) and operator*(float) can
+ be used; you can make splines out of G3D::Vector4, G3D::Matrix3, or
+ your own classes.
+
+ To provide shortest-path interpolation, subclass G3D::Spline and
+ override ensureShortestPath(). To provide normalization of
+ interpolated points (e.g., projecting Quats onto the unit
+ hypersphere) override correct().
+
+ See Real Time Rendering, 2nd edition, ch 12 for a general discussion
+ of splines and their properties.
+
+ @sa G3D::UprightSpline, G3D::QuatSpline
+ */
+template<typename Control>
+class Spline : public SplineBase {
+protected:
+ /** The additive identity control point. */
+ Control zero;
+
+public:
+
+ /** Control points. Must have the same number of elements as
+ Spline::time.*/
+ Array<Control> control;
+
+ Spline() {
+ static Control x;
+ // Hide the fact from C++ that we are using an
+ // uninitialized variable here by pointer arithmetic.
+ // This is ok because any type that is a legal control
+ // point also supports multiplication by float.
+ zero = *(&x) * 0.0f;
+ }
+
+ /** Appends a control point at a specific time that must be
+ greater than that of the previous point. */
+ void append(float t, const Control& c) {
+ debugAssertM((time.size() == 0) || (t > time.last()),
+ "Control points must have monotonically increasing times.");
+ time.append(t);
+ control.append(c);
+ debugAssert(control.size() == time.size());
+ }
+
+
+ /** Appends control point spaced in time based on the previous
+ control point, or spaced at unit intervals if this is the
+ first control point. */
+ void append(const Control& c) {
+ switch (time.size()) {
+ case 0:
+ append(0, c);
+ break;
+
+ case 1:
+ if (time[0] == 0) {
+ append(1, c);
+ } else {
+ append(time[0], c);
+ }
+ break;
+
+ default:
+ append(2 * time[time.size() - 1] - time[time.size() - 2], c);
+ }
+ debugAssert(control.size() == time.size());
+ }
+
+ /** Erases all control points and times, but retains the state of
+ cyclic and finalInterval.
+ */
+ void clear() {
+ control.clear();
+ time.clear();
+ }
+
+
+ /** Number of control points */
+ int size() const {
+ debugAssert(time.size() == control.size());
+ return control.size();
+ }
+
+
+ /** Returns the requested control point and time sample based on
+ array index. If the array index is out of bounds, wraps (for
+ a cyclic spline) or linearly extrapolates (for a non-cyclic
+ spline), assuming time intervals follow the first or last
+ sample recorded.
+
+ Calls correct() on the control point if it was extrapolated.
+
+ Returns 0 if there are no control points.
+
+ @sa Spline::control and Spline::time for the underlying
+ control point array; Spline::computeIndex to find the index
+ given a time.
+ */
+ void getControl(int i, float& t, Control& c) const {
+ int N = control.size();
+ if (N == 0) {
+ c = zero;
+ t = 0;
+ } else if (cyclic) {
+ c = control[iWrap(i, N)];
+
+ if (i < 0) {
+ // Wrapped around bottom
+
+ // Number of times we wrapped around the cyclic array
+ int wraps = (N + 1 - i) / N;
+ int j = (i + wraps * N) % N;
+ t = time[j] - wraps * duration();
+
+ } else if (i < N) {
+
+ t = time[i];
+
+ } else {
+ // Wrapped around top
+
+ // Number of times we wrapped around the cyclic array
+ int wraps = i / N;
+ int j = i % N;
+ t = time[j] + wraps * duration();
+ }
+
+ } else if (i < 0) {
+ // Are there enough points to extrapolate?
+ if (N >= 2) {
+ // Step away from control point 0
+ float dt = time[1] - time[0];
+
+ // Extrapolate (note; i is negative)
+ c = control[1] * float(i) + control[0] * float(1 - i);
+ correct(c);
+ t = dt * i + time[0];
+
+ } else {
+ // Just clamp
+ c = control[0];
+
+ // Only 1 time; assume 1s intervals
+ t = time[0] + i;
+ }
+
+ } else if (i >= N) {
+ if (N >= 2) {
+ float dt = time[N - 1] - time[N - 2];
+
+ // Extrapolate
+ c = control[N - 1] * float(i - N + 2) + control[N - 2] * -float(i - N + 1);
+ correct(c);
+ t = time[N - 1] + dt * (i - N + 1);
+
+ } else {
+ // Return the last, clamping
+ c = control.last();
+ // Only 1 time; assume 1s intervals
+ t = time[0] + i;
+ }
+ } else {
+ // In bounds
+ c = control[i];
+ t = time[i];
+ }
+ }
+
+protected:
+
+ /** Returns a series of N control points and times, fixing
+ boundary issues. The indices may be assumed to be treated
+ cyclically. */
+ void getControls(int i, float* T, Control* A, int N) const {
+ for (int j = 0; j < N; ++j) {
+ getControl(i + j, T[j], A[j]);
+ }
+ ensureShortestPath(A, N);
+ }
+
+ /**
+ Mutates the array of N control points. It is useful to override this
+ method by one that wraps the values if they are angles or quaternions
+ for which "shortest path" interpolation is significant.
+ */
+ virtual void ensureShortestPath(Control* A, int N) const { (void)A; (void) N;}
+
+ /** Normalize or otherwise adjust this interpolated Control. */
+ virtual void correct(Control& A) const { (void)A; }
+
+public:
+
+
+ /**
+ Return the position at time s. The spline is defined outside
+ of the time samples by extrapolation or cycling.
+ */
+ Control evaluate(float s) const {
+ debugAssertM(control.size() == time.size(), "Corrupt spline: wrong number of control points.");
+
+ /*
+ @cite http://www.gamedev.net/reference/articles/article1497.asp
+ Derivation of basis matrix follows.
+
+ Given control points with positions p[i] at times t[i], 0 <= i <= 3, find the position
+ at time t[1] <= s <= t[2].
+
+ Let u = s - t[0]
+ Let U = [u^0 u^1 u^2 u^3] = [1 u u^2 u^3]
+ Let dt0 = t[0] - t[-1]
+ Let dt1 = t[1] - t[0]
+ Let dt2 = t[2] - t[1]
+ */
+
+ // Index of the first control point (i.e., the u = 0 point)
+ int i = 0;
+ // Fractional part of the time
+ float u = 0;
+
+ computeIndex(s, i, u);
+
+ Control p[4];
+ float t[4];
+ getControls(i - 1, t, p, 4);
+ float dt0 = t[1] - t[0];
+ float dt1 = t[2] - t[1];
+ float dt2 = t[3] - t[2];
+
+ static const Matrix4 basis = computeBasis();
+
+ // Powers of u
+ Vector4 uvec((float)(u*u*u), (float)(u*u), (float)u, 1.0f);
+
+ // Compute the weights on each of the control points.
+ const Vector4& weights = uvec * basis;
+
+ // Compute the weighted sum of the neighboring control points.
+ Control sum;
+
+ const Control& p0 = p[0];
+ const Control& p1 = p[1];
+ const Control& p2 = p[2];
+ const Control& p3 = p[3];
+
+ const Control& dp0 = p1 + (p0*-1.0f);
+ const Control& dp1 = p2 + (p1*-1.0f);
+ const Control& dp2 = p3 + (p2*-1.0f);
+
+ // The factor of 1/2 from averaging two time intervals is
+ // already factored into the basis
+
+ // tan1 = (dp0 / dt0 + dp1 / dt1) * ((dt0 + dt1) * 0.5);
+ // The last term normalizes for unequal time intervals
+ float x = (dt0 + dt1) * 0.5f;
+ float n0 = x / dt0;
+ float n1 = x / dt1;
+ float n2 = x / dt2;
+ const Control& dp1n1 = dp1 * n1;
+ const Control& tan1 = dp0 * n0 + dp1n1;
+ const Control& tan2 = dp1n1 + dp2 * n2;
+
+ sum =
+ tan1 * weights[0]+
+ p1 * weights[1] +
+ p2 * weights[2] +
+ tan2 * weights[3];
+
+
+ correct(sum);
+ return sum;
+ }
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Stopwatch.h b/dep/include/g3dlite/G3D/Stopwatch.h
new file mode 100644
index 00000000000..3f2aa9c8d86
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Stopwatch.h
@@ -0,0 +1,144 @@
+/**
+ @file Stopwatch.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2005-10-05
+ @edited 2009-05-10
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Stopwatch_h
+#define G3D_Stopwatch_h
+
+#include "G3D/platform.h"
+#include "G3D/Queue.h"
+#include "G3D/G3DGameUnits.h"
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+/**
+ \brief Accurately measure durations and framerates.
+
+ Example 1: For profiling code in the context of a rendering loop:
+ <pre>
+ sw.tick();
+ ...timed code...
+ sw.tock();
+
+ screenPrintf("%f\n", sw.smoothFPS());
+ </pre>
+
+
+ Example 2: For profiling pieces of a sequence:
+ <pre>
+ Stopwatch sw;
+ slowOperation();
+ sw.after("slowOperation");
+ kdTree.balance();
+ sw.after("Balance tree");
+ </pre>
+ */
+class Stopwatch {
+private:
+
+ std::string myName;
+ double startTime;
+ std::string prevMark;
+ double prevTime;
+
+ /** True between tick and tock */
+ bool inBetween;
+
+ /** The initial cycle count. */
+ uint64 cycleStart;
+
+ /** The time at which tick was called. */
+ RealTime timeStart;
+
+ /** The time at which the previous tock was called, -1 if never. */
+ RealTime lastTockTime;
+
+ RealTime lastDuration;
+ int64 lastCycleCount;
+
+ /** Frames per second. */
+ double m_fps;
+
+ /** Weighted fps */
+ double emwaFPS;
+ double m_smoothFPS;
+
+ /** Weighted duration */
+ RealTime emwaDuration;
+
+ /** The overhead for calling into the class. */
+ int64 cycleOverhead;
+
+ /** Called from the constructor. */
+ void computeOverhead();
+
+public:
+
+ Stopwatch(const std::string& name = "Stopwatch");
+
+ /** Returns the number of times that tick was called per wall-clock second;
+ e.g. frames-per-second. */
+ double FPS() const {
+ return m_fps;
+ }
+
+ /** Amount of time between the most recent tick and tock calls. 0 if tick has
+ never been called. */
+ RealTime elapsedTime() const {
+ return lastDuration;
+ }
+
+ /** Time-smoothed value that is stable to the nearest 1%.
+ This is useful if you are displaying elapsed time in real-time
+ and want a stable number.*/
+ RealTime smoothElapsedTime() const {
+ return emwaDuration;
+ }
+
+ /** Time-smoothed value of fps that is stable to the nearest integer for fps > 10 and
+ to the first decimal place for fps <= 10.
+ This is useful if you
+ are displaying the frame rate in real-time and want a stable (readable) number.*/
+ double smoothFPS() const {
+ return m_smoothFPS;
+ }
+
+ /** The elapsed cycle time between tick and tock. An attempt is made to factor out all
+ tick/tock overhead, so that back-to-back calls should return zero.
+ Unreliable on non-x86 platforms.*/
+ uint64 elapsedCycles() const {
+ return lastCycleCount;
+ }
+
+ /** Call at the beginning of the period that you want timed. */
+ void tick();
+
+ /** Call at the end of the period that you want timed. */
+ void tock();
+
+
+ /** Reset the start time used by after() and the emwa value.*/
+ void reset();
+
+ /** Call after an operation has completed, with the name of the operation, to
+ print a debug message listing the time since the previous after() call. */
+ void after(const std::string& s = "");
+
+};
+
+/** Because it is hard to remember the proper capitalization. */
+typedef Stopwatch StopWatch;
+
+}
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/System.h b/dep/include/g3dlite/G3D/System.h
index 81abff3fb50..56ef9c8e3dc 100644
--- a/dep/include/g3dlite/G3D/System.h
+++ b/dep/include/g3dlite/G3D/System.h
@@ -1,21 +1,23 @@
/**
@file System.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm
@cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1
@cite Michael Herf http://www.stereopsis.com/memcpy.html
@created 2003-01-25
- @edited 2006-04-26
+ @edited 2008-10-14
*/
-#ifndef G3D_SYSTEM_H
-#define G3D_SYSTEM_H
+#ifndef G3D_System_h
+#define G3D_System_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
+#include "G3D/G3DGameUnits.h"
+#include "G3D/BinaryFormat.h"
#include <string>
#ifdef G3D_OSX
@@ -24,64 +26,249 @@
namespace G3D {
-typedef double RealTime;
+/**
+ Routine used by the demos to find the data. Searches in
+ ../data, ../../data, etc. up to 5 levels back. Checks
+ common locations like \verbatim c:\libraries\g3d-<version>\data \endverbatim
+ and some hard-coded paths on the Brown University file
+ system.
+
+ @deprecated
+ */
+std::string demoFindData(bool errorIfNotFound = true);
+
+/** G3D, SDL, and IJG libraries require license documentation
+ to be distributed with your program. This generates the
+ string that must appear in your documentation.
+ <B>Your program can be commercial, closed-source</B> under
+ any license you want.
+ @deprecated Use System::license
+*/
+std::string license();
+
+/**
+@brief The order in which the bytes of an integer are stored on a
+machine.
+
+Intel/AMD chips tend to be G3D_LITTLE_ENDIAN, Mac PPC's and Suns are
+G3D_BIG_ENDIAN. However, this is primarily used to specify the byte
+order of file formats, which are fixed.
+*/
+enum G3DEndian {
+ G3D_BIG_ENDIAN,
+ G3D_LITTLE_ENDIAN
+};
+
+/**
+ @brief OS and processor abstraction.
+ The first time any method is called the processor will be analyzed.
+ Future calls are then fast.
+
+ Timing function overview:
+ System::getCycleCount
+ - actual cycle count
+
+ System::getTick
+ - High-resolution time in seconds since program started
+
+ System::getLocalTime
+ - High-resolution time in seconds since Jan 1, 1970
+ (because it is stored in a double, this may be less
+ accurate than getTick)
+ */
class System {
public:
+ /**
+ @param size Size of memory that the system was trying to allocate
- /** Called automatically by the other System routines.*/
- static void init();
+ @param recoverable If true, the system will attempt to allocate again
+ if the callback returns true. If false, malloc is going to return
+ NULL and this invocation is just to notify the application.
- /**
- Guarantees that the start of the array is aligned to the
- specified number of bytes.
+ @return Return true to force malloc to attempt allocation again if the
+ error was recoverable.
*/
- static void* alignedMalloc(size_t bytes, size_t alignment);
+ typedef bool (*OutOfMemoryCallback)(size_t size, bool recoverable);
- /**
- Uses pooled storage to optimize small allocations (1 byte to 5 kilobytes).
- Can be 10x to 100x faster than calling ::malloc or new.
+private:
- The result must be freed with free.
+ bool m_initialized;
+ int m_cpuSpeed;
+ bool m_hasCPUID;
+ bool m_hasRDTSC;
+ bool m_hasMMX;
+ bool m_hasSSE;
+ bool m_hasSSE2;
+ bool m_hasSSE3;
+ bool m_has3DNOW;
+ bool m_has3DNOW2;
+ bool m_hasAMDMMX;
+ std::string m_cpuVendor;
+ int m_numCores;
- Threadsafe on Win32.
+ /** this holds the data directory set by the application (currently
+ GApp) for use by findDataFile */
+ std::string m_appDataDir;
+
+ G3DEndian m_machineEndian;
+ std::string m_cpuArch;
+ std::string m_operatingSystem;
+
+# ifdef G3D_WIN32
+ /** Used by getTick() for timing */
+ LARGE_INTEGER m_start;
+ LARGE_INTEGER m_counterFrequency;
+#else
+ struct timeval m_start;
+#endif
+
+ std::string m_version;
+ OutOfMemoryCallback m_outOfMemoryCallback;
+
+#ifdef G3D_OSX
+ /** In Cycles/Second */
+ SInt32 m_OSXCPUSpeed;
+ double m_secondsPerNS;
+#endif
+
+ /** The Real-World time of System::getTick() time 0. Set by initTime */
+ RealTime m_realWorldGetTickTime0;
- @sa calloc realloc OutOfMemoryCallback free
+ uint32 m_highestCPUIDFunction;
+
+ /** @brief Used for the singleton instance only. */
+ System();
+
+ /** @brief The singleton instance.
+
+ Used instead of a global variable to ensure that the order of
+ intialization is correct, which is critical because other
+ globals may allocate memory using System::malloc.
*/
- static void* malloc(size_t bytes);
+ static System& instance();
- static void* calloc(size_t n, size_t x);
+ enum CPUIDFunction {
+ CPUID_VENDOR_ID = 0x00000000,
+ CPUID_PROCESSOR_FEATURES = 0x00000001,
+ CPUID_NUM_CORES = 0x00000004,
+ CPUID_GET_HIGHEST_FUNCTION = 0x80000000,
+ CPUID_EXTENDED_FEATURES = 0x80000001};
+
+ /** Helper macro to call cpuid functions and return all values
+
+ See http://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/
+ or http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf
+
+ for description of the arguments.
+ */
+ static void cpuid(CPUIDFunction func, uint32& areg, uint32& breg, uint32& creg, uint32& dreg);
+
+ void init();
+
+ /** Called from init() */
+ void getStandardProcessorExtensions();
+
+ /** Called from init() */
+ void initTime();
+
+public:
+
+ /** Returns the speed of processor 0 in MHz.
+ Always returns 0 on linux.*/
+ inline static int cpuSpeedMHz() {
+ return instance().m_cpuSpeed;
+ }
+
+ /** Returns the number of logical processor cores (i.e., the
+ number of execution units for threads) */
+ inline static int numCores() {
+ return instance().m_numCores;
+ }
+
+ inline static bool hasCPUID() {
+ return instance().m_hasCPUID;
+ }
+
+ inline static bool hasRDTSC() {
+ return instance().m_hasRDTSC;
+ }
+
+ inline static bool hasSSE() {
+ return instance().m_hasSSE;
+ }
+
+ inline static bool hasSSE2() {
+ return instance().m_hasSSE2;
+ }
+
+ inline static bool hasSSE3() {
+ return instance().m_hasSSE3;
+ }
+
+ inline static bool hasMMX() {
+ return instance().m_hasMMX;
+ }
+
+ inline static bool has3DNow() {
+ return instance().m_has3DNOW;
+ }
+
+ inline static const std::string& cpuVendor() {
+ return instance().m_cpuVendor;
+ }
/**
- @param size Size of memory that the system was trying to allocate
- @param recoverable If true, the system will attempt to allocate again
- if the callback returns true. If false, malloc is going to return
- NULL and this invocation is just to notify the application.
- @return Return true to force malloc to attempt allocation again if the
- error was recoverable.
- */
- typedef bool (*OutOfMemoryCallback)(size_t size, bool recoverable);
+ Returns the endianness of this machine.
+ */
+ inline static G3DEndian machineEndian() {
+ return instance().m_machineEndian;
+ }
+
+ /** e.g., "Windows", "GNU/Linux" */
+ inline static const std::string& operatingSystem() {
+ return instance().m_operatingSystem;
+ }
+
+ /** e.g., 80686 */
+ inline static const std::string& cpuArchitecture() {
+ return instance().m_cpuArch;
+ }
/**
- When System::malloc fails to allocate memory because the system is
- out of memory, it invokes this handler (if it is not NULL).
- The argument to the callback is the amount of memory that malloc
- was trying to allocate when it ran out. If the callback returns
- true, System::malloc will attempt to allocate the memory again.
- If the callback returns false, then System::malloc will return NULL.
+ Returns the current date as a string in the form YYYY-MM-DD
+ */
+ static std::string currentDateString();
- You can use outOfMemoryCallback to free data structures or to
- register the failure.
- */
- static OutOfMemoryCallback outOfMemoryCallback;
+ /**
+ Guarantees that the start of the array is aligned to the
+ specified number of bytes.
+ */
+ static void* alignedMalloc(size_t bytes, size_t alignment);
+
+ /**
+ Uses pooled storage to optimize small allocations (1 byte to 5
+ kilobytes). Can be 10x to 100x faster than calling ::malloc or
+ new.
+
+ The result must be freed with free.
+
+ Threadsafe on Win32.
+
+ @sa calloc realloc OutOfMemoryCallback free
+ */
+ static void* malloc(size_t bytes);
+
+ static void* calloc(size_t n, size_t x);
/**
Version of realloc that works with System::malloc.
*/
static void* realloc(void* block, size_t bytes);
- /** Returns a string describing how well System::malloc is using its internal pooled storage.
- "heap" memory was slow to allocate; the other data sizes are comparatively fast.*/
+ /** Returns a string describing how well System::malloc is using
+ its internal pooled storage. "heap" memory was slow to
+ allocate; the other data sizes are comparatively fast.*/
static std::string mallocPerformance();
static void resetMallocPerformanceCounters();
@@ -104,18 +291,217 @@ public:
static void alignedFree(void* ptr);
/** An implementation of memcpy that may be up to 2x as fast as the C library
- one on some processors. Guaranteed to have the same behavior as memcpy
- in all cases. */
+ one on some processors. Guaranteed to have the same behavior as memcpy
+ in all cases. */
static void memcpy(void* dst, const void* src, size_t numBytes);
/** An implementation of memset that may be up to 2x as fast as the C library
- one on some processors. Guaranteed to have the same behavior as memset
- in all cases. */
+ one on some processors. Guaranteed to have the same behavior as memset
+ in all cases. */
static void memset(void* dst, uint8 value, size_t numBytes);
+ /**
+ Returns the fully qualified filename for the currently running executable.
+
+ This is more reliable than arg[0], which may be intentionally set
+ to an incorrect value by a calling program, relative to a now
+ non-current directory, or obfuscated by sym-links.
+
+ @cite Linux version written by Nicolai Haehnle <prefect_@gmx.net>, http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-getexename&forum=cotd&id=-1
+ */
+ static std::string currentProgramFilename();
+
+ /** Name of this program. Note that you can mutate this string to
+ set your app name explicitly.*/
+ static std::string& appName();
+
+ /** G3D Version string */
+ inline static const std::string& version() {
+ return instance().m_version;
+ }
+
+ /**
+ @brief The optimization status of the G3D library (not the program compiled against it)
+
+ Either "Debug" or "Release", depending on whether _DEBUG was
+ defined at compile-time for the library.
+ */
+ static const std::string& build();
+
+ /**
+ Causes the current thread to yield for the specified duration
+ and consume almost no CPU.
+ The sleep will be extremely precise; it uses System::time()
+ to calibrate the exact yeild time.
+ */
+ static void sleep(RealTime t);
+
+ /**
+ Clears the console.
+ Console programs only.
+ */
+ static void consoleClearScreen();
+
+ /**
+ Returns true if a key is waiting.
+ Console programs only.
+ */
+ static bool consoleKeyPressed();
+
+ /**
+ Blocks until a key is read (use consoleKeyPressed to determine if
+ a key is waiting to be read) then returns the character code for
+ that key.
+ */
+ static int consoleReadKey();
+
+ /**
+ The actual time (measured in seconds since
+ Jan 1 1970 midnight).
+
+ Adjusted for local timezone and daylight savings
+ time. This is as accurate and fast as getCycleCount().
+ */
+ static RealTime time();
+
+ /**
+ To count the number of cycles a given operation takes:
+
+ <PRE>
+ unsigned long count;
+ System::beginCycleCount(count);
+ ...
+ System::endCycleCount(count);
+ // count now contains the cycle count for the intervening operation.
+ </PRE>
+ */
+ /* static void beginCycleCount(uint64& cycleCount);
+ static void endCycleCount(uint64& cycleCount);
+
+ static uint64 getCycleCount(); */
+
+ inline static void setOutOfMemoryCallback(OutOfMemoryCallback c) {
+ instance().m_outOfMemoryCallback = c;
+ }
+
+ /**
+ When System::malloc fails to allocate memory because the system is
+ out of memory, it invokes this handler (if it is not NULL).
+ The argument to the callback is the amount of memory that malloc
+ was trying to allocate when it ran out. If the callback returns
+ true, System::malloc will attempt to allocate the memory again.
+ If the callback returns false, then System::malloc will return NULL.
+
+ You can use outOfMemoryCallback to free data structures or to
+ register the failure.
+ */
+ inline static OutOfMemoryCallback outOfMemoryCallback() {
+ return instance().m_outOfMemoryCallback;
+ }
+
+ /** Set an environment variable for the current process */
+ static void setEnv(const std::string& name, const std::string& value);
+
+ /** Get an environment variable for the current process. Returns NULL if the variable doesn't exist. */
+ static const char* getEnv(const std::string& name);
+
+ /**
+ Prints a human-readable description of this machine
+ to the text output stream. Either argument may be NULL.
+ */
+ static void describeSystem(
+ class TextOutput& t);
+
+ static void describeSystem(
+ std::string& s);
+
+ /** On Win32, returns the clipboard text contents. Does nothing on other
+ platforms (yet) */
+ static std::string getClipboardText();
+
+ /** Copies the text to the clipboard on Win32. */
+ static void setClipboardText(const std::string& s);
+
+ /**
+ Tries to locate the resource by looking in related directories.
+ If found, returns the full path to the resource, otherwise
+ returns the empty string.
+ */
+ static std::string findDataFile(const std::string& full, bool errorIfNotFound = true);
+
+ /**
+ Sets the path that the application is using as its data directory.
+ Used by findDataDir as an initial search location. GApp sets this
+ upon constrution.
+ */
+ static void setAppDataDir(const std::string& path);
+
};
-} // namespace
+/* don't need that for MaNGOS, not portable to Win64...
+#ifdef _MSC_VER
+ inline uint64 System::getCycleCount() {
+ uint32 timehi, timelo;
+
+ // Use the assembly instruction rdtsc, which gets the current
+ // cycle count (since the process started) and puts it in edx:eax.
+ __asm
+ {
+ rdtsc;
+ mov timehi, edx;
+ mov timelo, eax;
+ }
+
+ return ((uint64)timehi << 32) + (uint64)timelo;
+ }
+
+#elif defined(G3D_LINUX)
+
+ inline uint64 System::getCycleCount() {
+ uint32 timehi, timelo;
+
+ __asm__ __volatile__ (
+ "rdtsc "
+ : "=a" (timelo),
+ "=d" (timehi)
+ : );
+
+ return ((uint64)timehi << 32) + (uint64)timelo;
+ }
+
+#elif defined(G3D_OSX)
+
+ inline uint64 System::getCycleCount() {
+ //Note: To put off extra processing until the end, this does not
+ //return the actual clock cycle count. It is a bus cycle count.
+ //When endCycleCount() is called, it converts the two into a difference
+ //of clock cycles
+
+ return (uint64) UnsignedWideToUInt64(UpTime());
+ //return (uint64) mach_absolute_time();
+ }
#endif
+inline void System::beginCycleCount(uint64& cycleCount) {
+ cycleCount = getCycleCount();
+}
+
+
+inline void System::endCycleCount(uint64& cycleCount) {
+#ifndef G3D_OSX
+ cycleCount = getCycleCount() - cycleCount;
+#else
+ AbsoluteTime end = UpTime();
+ Nanoseconds diffNS =
+ AbsoluteDeltaToNanoseconds(end, UInt64ToUnsignedWide(cycleCount));
+ cycleCount =
+ (uint64) ((double) (instance().m_OSXCPUSpeed) *
+ (double) UnsignedWideToUInt64(diffNS) * instance().m_secondsPerNS);
+#endif
+}
+ */
+
+} // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Table.h b/dep/include/g3dlite/G3D/Table.h
index aded5c38555..287efa94d97 100644
--- a/dep/include/g3dlite/G3D/Table.h
+++ b/dep/include/g3dlite/G3D/Table.h
@@ -3,109 +3,101 @@
Templated hash table class.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-04-22
- @edited 2006-10-14
- Copyright 2000-2006, Morgan McGuire.
+ @edited 2010-01-28
+ Copyright 2000-2010, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_TABLE_H
-#define G3D_TABLE_H
+#ifndef G3D_Table_h
+#define G3D_Table_h
+
+#include <cstddef>
+#include <string>
#include "G3D/platform.h"
#include "G3D/Array.h"
#include "G3D/debug.h"
#include "G3D/System.h"
#include "G3D/g3dmath.h"
-#include "G3D/Crypto.h"
-#include <cstddef>
-#include <string>
+#include "G3D/EqualsTrait.h"
+#include "G3D/HashTrait.h"
+#include "G3D/MemoryManager.h"
-#ifdef G3D_WIN32
+#ifdef _MSC_VER
# pragma warning (push)
// Debug name too long warning
# pragma warning (disable : 4786)
#endif
-template<typename Key>
-struct GHashCode{};
+namespace G3D {
-template <>
-struct GHashCode<int>
-{
- size_t operator()(int key) const { return static_cast<size_t>(key); }
-};
+/**
+ An unordered data structure mapping keys to values.
-template <>
-struct GHashCode<G3D::uint32>
-{
- size_t operator()(G3D::uint32 key) const { return static_cast<size_t>(key); }
-};
+ There are two ways of definining custom hash functions (G3D provides built-in ones for most classes):
-template <>
-struct GHashCode<G3D::uint64>
-{
- size_t operator()(G3D::uint64 key) const { return static_cast<size_t>(key); }
-};
+ <pre>
+ class Foo {
+ public:
+ std::string name;
+ int index;
+ static size_t hashCode(const Foo& key) {
+ return HashTrait<std::string>::hashCode(key.name) + key.index;
+ }
+ };
-template <>
-struct GHashCode<void*>
-{
- size_t operator()(const void* key) const { return reinterpret_cast<size_t>(key); }
-};
+ template<> struct HashTrait<class Foo> {
+ static size_t hashCode(const Foo& key) { return HashTrait<std::string>::hashCode(key.name) + key.index; }
+ };
-template<class T>
-struct GHashCode<T*>
-{
- size_t operator()(const T* key) const { return reinterpret_cast<size_t>(key); }
-};
-template <>
-struct GHashCode<const std::string>
-{
- size_t operator()(const std::string& key) const { return static_cast<size_t>(G3D::Crypto::crc32(key.c_str(), key.size())); }
-};
+ // Use Foo::hashCode
+ Table<Foo, std::string, Foo> fooTable1;
-template <>
-struct GHashCode<std::string>
-{
- size_t operator()(const std::string& key) const { return static_cast<size_t>(G3D::Crypto::crc32(key.c_str(), key.size())); }
-};
+ // Use HashTrait<Foo>
+ Table<Foo, std::string> fooTable2;
+ </pre>
-namespace G3D {
-/**
- An unordered data structure mapping keys to values.
+ Key must be a pointer, an int, a std::string or provide overloads for:
- Key must be a pointer, an int, a std::string, a class with a hashCode() method,
- or provide overloads for:
+ <PRE>
+ template<> struct HashTrait<class Key> {
+ static size_t hashCode(const Key& key) { return reinterpret_cast<size_t>( ... ); }
+ };
+ </PRE>
+
+ and one of
<PRE>
- template<> struct GHashCode<class Key> {
- size_t operator()(Key key) const { return reinterpret_cast<size_t>( ... ); }
+ template<> struct EqualsTrait<class Key>{
+ static bool equals(const Key& a, const Key& b) { return ... ; }
};
- bool operator==(const Key&, const Key&);
+
+ bool operator==(const Key&, const Key&);
</PRE>
- G3D pre-defines GHashCode functions for common types (like <CODE>int</CODE> and <CODE>std::string</CODE>).
+ G3D pre-defines HashTrait specializations for common types (like <CODE>int</CODE> and <CODE>std::string</CODE>).
If you use a Table with a different type you must write those functions yourself. For example,
an enum would use:
<PRE>
- template<> struct GHashCode<MyEnum> {
- size_t operator()(MyEnum key) const { return reinterpret_cast<size_t>( key ); }
+ template<> struct HashTrait<MyEnum> {
+ static size_t equals(const MyEnum& key) const { return reinterpret_cast<size_t>( key ); }
};
</PRE>
And rely on the default enum operator==.
+
Periodically check that debugGetLoad() is low (> 0.1). When it gets near
1.0 your hash function is badly designed and maps too many inputs to
the same output.
*/
-template<class Key, class Value, class HashFunc = GHashCode<Key> >
+template<class Key, class Value, class HashFunc = HashTrait<Key>, class EqualsFunc = EqualsTrait<Key> >
class Table {
public:
@@ -116,164 +108,259 @@ public:
public:
Key key;
Value value;
+ Entry() {}
+ Entry(const Key& k) : key(k) {}
+ Entry(const Key& k, const Value& v) : key(k), value(v) {}
+ bool operator==(const Entry &peer) const { return (key == peer.key && value == peer.value); }
+ bool operator!=(const Entry &peer) const { return !operator==(peer); }
};
private:
+
+ typedef Table<Key, Value, HashFunc, EqualsFunc> ThisType;
+
/**
Linked list nodes used internally by HashTable.
*/
class Node {
public:
- size_t hashCode;
Entry entry;
+ size_t hashCode;
Node* next;
- /** Provide pooled allocation for speed. */
- inline void* operator new (size_t size) {
- return System::malloc(size);
+ private:
+
+ // Private to require use of the allocator
+ Node(const Key& k, const Value& v, size_t h, Node* n)
+ : entry(k, v), hashCode(h), next(n) {
}
- inline void operator delete (void* p) {
- System::free(p);
+ Node(const Key& k, size_t h, Node* n)
+ : entry(k), hashCode(h), next(n) {
+ }
+
+ public:
+
+ static Node* create(const Key& k, const Value& v, size_t h, Node* n, MemoryManager::Ref& mm) {
+ Node* node = (Node*)mm->alloc(sizeof(Node));
+ return new (node) Node(k, v, h, n);
}
- Node(Key key, Value value, size_t hashCode, Node* next) {
- this->entry.key = key;
- this->entry.value = value;
- this->hashCode = hashCode;
- this->next = next;
+ static Node* create(const Key& k, size_t hashCode, Node* n, MemoryManager::Ref& mm) {
+ Node* node = (Node*)mm->alloc(sizeof(Node));
+ return new (node) Node(k, hashCode, n);
+ }
+
+ static void destroy(Node* n, MemoryManager::Ref& mm) {
+ n->~Node();
+ mm->free(n);
}
/**
Clones a whole chain;
*/
- Node* clone() {
- return new Node(this->entry.key, this->entry.value, hashCode, (next == NULL) ? NULL : next->clone());
+ Node* clone(MemoryManager::Ref& mm) {
+ return create(this->entry.key, this->entry.value, hashCode, (next == NULL) ? NULL : next->clone(mm), mm);
}
};
- HashFunc m_HashFunc;
+ void checkIntegrity() const {
+# ifdef G3D_DEBUG
+ debugAssert(m_bucket == NULL || isValidHeapPointer(m_bucket));
+ for (size_t b = 0; b < m_numBuckets; ++b) {
+ Node* node = m_bucket[b];
+ debugAssert(node == NULL || isValidHeapPointer(node));
+ while (node != NULL) {
+ debugAssert(node == NULL || isValidHeapPointer(node));
+ node = node->next;
+ }
+ }
+# endif
+ }
- /**
- Number of elements in the table.
- */
- size_t _size;
+ /** Number of elements in the table.*/
+ size_t m_size;
/**
- Array of Node*.
- We don't use Array<Node*> because Table is lower level.
+ Array of Node*.
+
+ We don't use Array<Node*> because Table is lower-level than Array.
Some elements may be NULL.
*/
- Node** bucket;
-
+ Node** m_bucket;
+
/**
- Length of the bucket array.
+ Length of the m_bucket array.
*/
- size_t numBuckets;
+ size_t m_numBuckets;
- /**
- Re-hashes for a larger bucket size.
- */
- void resize(size_t numBuckets) {
+ MemoryManager::Ref m_memoryManager;
- Node** oldBucket = bucket;
- bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16);
- System::memset(bucket, 0, sizeof(Node*) * numBuckets);
+ void* alloc(size_t s) const {
+ return m_memoryManager->alloc(s);
+ }
- for (size_t b = 0; b < this->numBuckets; b++) {
- Node* node = oldBucket[b];
+ void free(void* p) const {
+ return m_memoryManager->free(p);
+ }
+ /**
+ Re-hashes for a larger m_bucket size.
+ */
+ void resize(size_t newSize) {
+
+ // Hang onto the old m_bucket array
+ Node** oldBucket = m_bucket;
+
+ // Allocate a new m_bucket array with the new size
+ m_bucket = (Node**)alloc(sizeof(Node*) * newSize);
+ // Set all pointers to NULL
+ System::memset(m_bucket, 0, newSize * sizeof(Node*));
+ debugAssertM(m_bucket != NULL, "MemoryManager::alloc returned NULL. Out of memory.");
+ // Move each node to its new hash location
+ for (size_t b = 0; b < m_numBuckets; ++b) {
+ Node* node = oldBucket[b];
+
+ // There is a linked list of nodes at this m_bucket
while (node != NULL) {
+ // Hang onto the old next pointer
Node* nextNode = node->next;
+
+ // Insert at the head of the list for m_bucket[i]
+ size_t i = node->hashCode % newSize;
+ node->next = m_bucket[i];
+ m_bucket[i] = node;
- // insert at the head of the list for bucket[i]
- size_t i = node->hashCode % numBuckets;
- node->next = bucket[i];
- bucket[i] = node;
-
+ // Move on to the next node
node = nextNode;
}
+
+ // Drop the old pointer for cleanliness when debugging
+ oldBucket[b] = NULL;
}
- System::alignedFree(oldBucket);
- this->numBuckets = numBuckets;
+ // Delete the old storage
+ free(oldBucket);
+ this->m_numBuckets = newSize;
+
+ checkIntegrity();
}
- void copyFrom(const Table<Key, Value>& h) {
- this->_size = h._size;
- this->numBuckets = h.numBuckets;
- this->bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16);
- System::memset(this->bucket, 0, sizeof(Node*) * numBuckets);
- for (size_t b = 0; b < this->numBuckets; b++) {
- if (h.bucket[b] != NULL) {
- bucket[b] = h.bucket[b]->clone();
+
+ void copyFrom(const ThisType& h) {
+ if (&h == this) {
+ return;
+ }
+
+ debugAssert(m_bucket == NULL);
+ m_size = h.m_size;
+ m_numBuckets = h.m_numBuckets;
+ m_bucket = (Node**)alloc(sizeof(Node*) * m_numBuckets);
+ // No need to NULL elements since we're about to overwrite them
+
+ for (size_t b = 0; b < m_numBuckets; ++b) {
+ if (h.m_bucket[b] != NULL) {
+ m_bucket[b] = h.m_bucket[b]->clone(m_memoryManager);
+ } else {
+ m_bucket[b] = NULL;
}
}
+
+ checkIntegrity();
}
/**
Frees the heap structures for the nodes.
*/
void freeMemory() {
- for (size_t b = 0; b < numBuckets; b++) {
- Node* node = bucket[b];
- while (node != NULL) {
+ checkIntegrity();
+
+ for (size_t b = 0; b < m_numBuckets; b++) {
+ Node* node = m_bucket[b];
+ while (node != NULL) {
Node* next = node->next;
- delete node;
+ Node::destroy(node, m_memoryManager);
node = next;
- }
+ }
+ m_bucket[b] = NULL;
}
- System::alignedFree(bucket);
- bucket = NULL;
- numBuckets = 0;
- _size = 0;
+ free(m_bucket);
+ m_bucket = NULL;
+ m_numBuckets = 0;
+ m_size = 0;
}
public:
/**
- Creates an empty hash table. This causes some heap allocation to occur.
+ Creates an empty hash table using the default MemoryManager.
*/
- Table() {
- numBuckets = 10;
- _size = 0;
- bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16);
- System::memset(bucket, 0, sizeof(Node*) * numBuckets);
+ Table() : m_bucket(NULL) {
+ m_memoryManager = MemoryManager::create();
+ m_numBuckets = 0;
+ m_size = 0;
+ m_bucket = NULL;
+ checkIntegrity();
+ }
+
+ /** Changes the internal memory manager to m */
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ clear();
+ debugAssert(m_bucket == NULL);
+ m_memoryManager = m;
}
+ /**
+ Recommends that the table resize to anticipate at least this number of elements.
+ */
+ void setSizeHint(size_t n) {
+ size_t s = n * 3;
+ if (s > m_numBuckets) {
+ resize(s);
+ }
+ }
+
/**
- Destroys all of the memory allocated by the table, but does <B>not</B>
- call delete on keys or values if they are pointers. If you want to
- deallocate things that the table points at, use getKeys() and Array::deleteAll()
- to delete them.
+ Destroys all of the memory allocated by the table, but does <B>not</B>
+ call delete on keys or values if they are pointers. If you want to
+ deallocate things that the table points at, use getKeys() and Array::deleteAll()
+ to delete them.
*/
virtual ~Table() {
freeMemory();
}
- Table(const Table<Key, Value>& h) {
+ /** Uses the default memory manager */
+ Table(const ThisType& h) {
+ m_memoryManager = MemoryManager::create();
+ m_numBuckets = 0;
+ m_size = 0;
+ m_bucket = NULL;
this->copyFrom(h);
+ checkIntegrity();
}
- Table& operator=(const Table<Key, Value>& h) {
+
+ Table& operator=(const ThisType& h) {
// No need to copy if the argument is this
if (this != &h) {
// Free the existing nodes
freeMemory();
this->copyFrom(h);
+ checkIntegrity();
}
return *this;
}
/**
- Returns the length of the deepest bucket.
+ Returns the length of the deepest m_bucket.
*/
size_t debugGetDeepestBucketSize() const {
size_t deepest = 0;
- for (size_t b = 0; b < numBuckets; b++) {
+ for (size_t b = 0; b < m_numBuckets; b++) {
size_t count = 0;
- Node* node = bucket[b];
+ Node* node = m_bucket[b];
while (node != NULL) {
node = node->next;
++count;
@@ -288,8 +375,29 @@ public:
}
/**
+ Returns the average size of non-empty buckets.
+ */
+ float debugGetAverageBucketSize() const {
+ size_t num = 0;
+ size_t count = 0;
+
+ for (size_t b = 0; b < m_numBuckets; b++) {
+ Node* node = m_bucket[b];
+ if (node != NULL) {
+ ++num;
+ while (node != NULL) {
+ node = node->next;
+ ++count;
+ }
+ }
+ }
+
+ return (float)((double)count / num);
+ }
+
+ /**
A small load (close to zero) means the hash table is acting very
- efficiently most of the time. A large load (close to 1) means
+ efficiently most of the time. A large load (close to 1) means
the hash table is acting poorly-- all operations will be very slow.
A large load will result from a bad hash function that maps too
many keys to the same code.
@@ -302,7 +410,7 @@ public:
Returns the number of buckets.
*/
size_t debugGetNumBuckets() const {
- return numBuckets;
+ return m_numBuckets;
}
/**
@@ -310,7 +418,7 @@ public:
*/
class Iterator {
private:
- friend class Table<Key, Value>;
+ friend class Table<Key, Value, HashFunc, EqualsFunc>;
/**
Bucket index.
@@ -321,31 +429,31 @@ public:
Linked list node.
*/
Node* node;
- Table<Key, Value>* table;
- size_t numBuckets;
- Node** bucket;
+ ThisType* table;
+ size_t m_numBuckets;
+ Node** m_bucket;
bool isDone;
/**
Creates the end iterator.
*/
- Iterator(const Table<Key, Value>* table) : table(const_cast<Table<Key, Value>*>(table)) {
+ Iterator(const ThisType* table) : table(const_cast<ThisType*>(table)) {
isDone = true;
}
- Iterator(const Table<Key, Value>* table, size_t numBuckets, Node** bucket) :
- table(const_cast<Table<Key, Value>*>(table)),
- numBuckets(numBuckets),
- bucket(bucket) {
-
- if (numBuckets == 0) {
+ Iterator(const ThisType* table, size_t m_numBuckets, Node** m_bucket) :
+ table(const_cast<ThisType*>(table)),
+ m_numBuckets(m_numBuckets),
+ m_bucket(m_bucket) {
+
+ if (m_numBuckets == 0) {
// Empty table
isDone = true;
return;
}
index = 0;
- node = bucket[index];
+ node = m_bucket[index];
isDone = false;
findNext();
}
@@ -357,11 +465,11 @@ public:
void findNext() {
while (node == NULL) {
index++;
- if (index >= numBuckets) {
+ if (index >= m_numBuckets) {
isDone = true;
break;
} else {
- node = bucket[index];
+ node = m_bucket[index];
}
}
}
@@ -378,7 +486,7 @@ public:
} else {
return
(table == other.table) &&
- (node == other.node) &&
+ (node == other.node) &&
(index == other.index);
}
}
@@ -412,15 +520,20 @@ public:
operator Entry*() const {
return &(node->entry);
}
+
+ bool hasMore() const {
+ return ! isDone;
+ }
};
+
/**
- C++ STL style iterator method. Returns the first Entry, which
+ C++ STL style iterator method. Returns the first Entry, which
contains a key and value. Use preincrement (++entry) to get to
the next element. Do not modify the table while iterating.
*/
Iterator begin() const {
- return Iterator(this, numBuckets, bucket);
+ return Iterator(this, m_numBuckets, m_bucket);
}
/**
@@ -435,134 +548,175 @@ public:
Removes all elements
*/
void clear() {
- freeMemory();
- numBuckets = 20;
- _size = 0;
- bucket = (Node**)System::alignedMalloc(sizeof(Node*) * numBuckets, 16);
- System::memset(bucket, 0, sizeof(Node*) * numBuckets);
+ freeMemory();
+ m_numBuckets = 0;
+ m_size = 0;
+ m_bucket = NULL;
}
+
/**
Returns the number of keys.
*/
size_t size() const {
- return _size;
+ return m_size;
}
+
/**
If you insert a pointer into the key or value of a table, you are
- responsible for deallocating the object eventually. Inserting
+ responsible for deallocating the object eventually. Inserting
key into a table is O(1), but may cause a potentially slow rehashing.
*/
void set(const Key& key, const Value& value) {
- size_t code = m_HashFunc(key);
- size_t b = code % numBuckets;
+ getCreateEntry(key).value = value;
+ }
- // Go to the bucket
- Node* n = bucket[b];
+private:
- // No bucket, so this must be the first
- if (n == NULL) {
- bucket[b] = new Node(key, value, code, NULL);
- ++_size;
- return;
+ /** Helper for remove() and getRemove() */
+ bool remove(const Key& key, Key& removedKey, Value& removedValue, bool updateRemoved) {
+ if (m_numBuckets == 0) {
+ return false;
}
+ size_t code = HashFunc::hashCode(key);
+ size_t b = code % m_numBuckets;
- size_t bucketLength = 1;
+ // Go to the m_bucket
+ Node* n = m_bucket[b];
- // Sometimes a bad hash code will cause all elements
- // to collide. Detect this case and don't rehash when
- // it occurs; nothing good will come from the rehashing.
- bool allSameCode = true;
+ if (n == NULL) {
+ return false;
+ }
- // Try to find the node
- do {
- allSameCode = allSameCode && (code == n->hashCode);
+ Node* previous = NULL;
+
+ // Try to find the node
+ do {
+ if ((code == n->hashCode) && EqualsFunc::equals(n->entry.key, key)) {
+ // This is the node; remove it
- if ((code == n->hashCode) && (n->entry.key == key)) {
- // Replace the existing node.
- n->entry.value = value;
- return;
- }
+ // Replace the previous's next pointer
+ if (previous == NULL) {
+ m_bucket[b] = n->next;
+ } else {
+ previous->next = n->next;
+ }
- n = n->next;
- ++bucketLength;
- } while (n != NULL);
+ if (updateRemoved) {
+ removedKey = n->entry.key;
+ removedValue = n->entry.value;
+ }
+ // Delete the node
+ Node::destroy(n, m_memoryManager);
+ --m_size;
+ return true;
+ }
- const size_t maxBucketLength = 5;
- if ((bucketLength > maxBucketLength) & ! allSameCode && (numBuckets < _size * 20)) {
- // This bucket was really large; rehash if all elements
- // don't have the same hashcode the number of buckets is reasonable.
- resize(numBuckets * 2 + 1);
- }
+ previous = n;
+ n = n->next;
+ } while (n != NULL);
- // Not found; insert at the head.
- b = code % numBuckets;
- bucket[b] = new Node(key, value, code, bucket[b]);
- ++_size;
+ return false;
+ //alwaysAssertM(false, "Tried to remove a key that was not in the table.");
}
- /**
- Removes an element from the table if it is present. It is an error
- to remove an element that isn't present.
+public:
+
+ /** If @a member is present, sets @a removed to the element
+ being removed and returns true. Otherwise returns false
+ and does not write to @a removed. */
+ bool getRemove(const Key& key, Key& removedKey, Value& removedValue) {
+ return remove(key, removedKey, removedValue, true);
+ }
+
+ /**
+ Removes an element from the table if it is present.
+ @return true if the element was found and removed, otherwise false
*/
- void remove(const Key& key) {
+ bool remove(const Key& key) {
+ Key x;
+ Value v;
+ return remove(key, x, v, false);
+ }
- size_t code = m_HashFunc(key);
- size_t b = code % numBuckets;
+private:
- // Go to the bucket
- Node* n = bucket[b];
+ Entry* getEntryPointer(const Key& key) const {
+ if (m_numBuckets == 0) {
+ return NULL;
+ }
- // Make sure it was found
- alwaysAssertM(n != NULL, "Tried to remove a key that was not in the table.");
+ size_t code = HashFunc::hashCode(key);
+ size_t b = code % m_numBuckets;
- Node* previous = NULL;
+ Node* node = m_bucket[b];
- // Try to find the node
- do {
- if ((code == n->hashCode) && (n->entry.key == key)) {
- // This is the node; remove it
- if (previous == NULL) {
- bucket[b] = n->next;
- } else {
- previous->next = n->next;
- }
- // Delete the node
- delete n;
- --_size;
- return;
- }
+ while (node != NULL) {
+ if ((node->hashCode == code) && EqualsFunc::equals(node->entry.key, key)) {
+ return &(node->entry);
+ }
+ node = node->next;
+ }
- previous = n;
- n = n->next;
- } while (n != NULL);
+ return NULL;
+ }
- alwaysAssertM(false, "Tried to remove a key that was not in the table.");
+public:
+
+ /** If a value that is EqualsFunc to @a member is present, returns a pointer to the
+ version stored in the data structure, otherwise returns NULL.
+ */
+ const Key* getKeyPointer(const Key& key) const {
+ const Entry* e = getEntryPointer(key);
+ if (e == NULL) {
+ return NULL;
+ } else {
+ return &(e->key);
+ }
}
/**
Returns the value associated with key.
- @deprecated Use get(key, val) or
+ @deprecated Use get(key, val) or getPointer(key)
*/
Value& get(const Key& key) const {
+ Entry* e = getEntryPointer(key);
+ debugAssertM(e != NULL, "Key not found");
+ return e->value;
+ }
- size_t code = m_HashFunc(key);
- size_t b = code % numBuckets;
- Node* node = bucket[b];
+ /** Returns a pointer to the element if it exists, or NULL if it does not.
+ Note that if your value type <i>is</i> a pointer, the return value is
+ a pointer to a pointer. Do not remove the element while holding this
+ pointer.
- while (node != NULL) {
- if ((node->hashCode == code) && (node->entry.key == key)) {
- return node->entry.value;
- }
- node = node->next;
- }
+ It is easy to accidentally mis-use this method. Consider making
+ a Table<Value*> and using get(key, val) instead, which makes you manage
+ the memory for the values yourself and is less likely to result in
+ pointer errors.
+ */
+ Value* getPointer(const Key& key) const {
+ if (m_numBuckets == 0) {
+ return NULL;
+ }
+
+ size_t code = HashFunc::hashCode(key);
+ size_t b = code % m_numBuckets;
+
+ Node* node = m_bucket[b];
- debugAssertM(false, "Key not found");
- // The next line is here just to make
- // a compiler warning go away.
- return node->entry.value;
+ while (node != NULL) {
+ if ((node->hashCode == code) && EqualsFunc::equals(node->entry.key, key)) {
+ // found key
+ return &(node->entry.value);
+ }
+ node = node->next;
+ }
+
+ // Failed to find key
+ return NULL;
}
/**
@@ -570,43 +724,134 @@ public:
If the key is not present, returns false.
*/
bool get(const Key& key, Value& val) const {
- size_t code = m_HashFunc(key);
- size_t b = code % numBuckets;
+ Value* v = getPointer(key);
+ if (v != NULL) {
+ val = *v;
+ return true;
+ } else {
+ return false;
+ }
+ }
- Node* node = bucket[b];
- while (node != NULL) {
- if ((node->hashCode == code) && (node->entry.key == key)) {
- // found key
- val = node->entry.value;
- return true;
- }
- node = node->next;
- }
- // Failed to find key
- return false;
+ /** Called by getCreate() and set()
+
+ \param created Set to true if the entry was created by this method.
+ */
+ Entry& getCreateEntry(const Key& key, bool& created) {
+ created = false;
+
+ if (m_numBuckets == 0) {
+ resize(10);
+ }
+
+ size_t code = HashFunc::hashCode(key);
+ size_t b = code % m_numBuckets;
+
+ // Go to the m_bucket
+ Node* n = m_bucket[b];
+
+ // No m_bucket, so this must be the first
+ if (n == NULL) {
+ m_bucket[b] = Node::create(key, code, NULL, m_memoryManager);
+ ++m_size;
+ created = true;
+ return m_bucket[b]->entry;
+ }
+
+ size_t bucketLength = 1;
+
+ // Sometimes a bad hash code will cause all elements
+ // to collide. Detect this case and don't rehash when
+ // it occurs; nothing good will come from the rehashing.
+ bool allSameCode = true;
+
+ // Try to find the node
+ do {
+ allSameCode = allSameCode && (code == n->hashCode);
+
+ if ((code == n->hashCode) && EqualsFunc::equals(n->entry.key, key)) {
+ // This is the a pre-existing node
+ return n->entry;
+ }
+
+ n = n->next;
+ ++bucketLength;
+ } while (n != NULL);
+
+ const size_t maxBucketLength = 3;
+ // (Don't bother changing the size of the table if all entries
+ // have the same hashcode--they'll still collide)
+ if ((bucketLength > maxBucketLength) &&
+ ! allSameCode &&
+ (m_numBuckets < m_size * 15)) {
+
+ // This m_bucket was really large; rehash if all elements
+ // don't have the same hashcode the number of buckets is
+ // reasonable.
+
+ // Back off the scale factor as the number of buckets gets
+ // large
+ float f = 3.0f;
+ if (m_numBuckets > 1000000) {
+ f = 1.5f;
+ } else if (m_numBuckets > 100000) {
+ f = 2.0f;
+ }
+ int newSize = iMax((int)(m_numBuckets * f) + 1, (int)(m_size * f));
+ resize(newSize);
+ }
+
+ // Not found; insert at the head.
+ b = code % m_numBuckets;
+ m_bucket[b] = Node::create(key, code, m_bucket[b], m_memoryManager);
+ ++m_size;
+ created = true;
+ return m_bucket[b]->entry;
}
+ Entry& getCreateEntry(const Key& key) {
+ bool ignore;
+ return getCreateEntry(key, ignore);
+ }
+
+
+ /** Returns the current value that key maps to, creating it if necessary.*/
+ Value& getCreate(const Key& key) {
+ return getCreateEntry(key).value;
+ }
+
+ /** \param created True if the element was created. */
+ Value& getCreate(const Key& key, bool& created) {
+ return getCreateEntry(key, created).value;
+ }
+
+
/**
Returns true if key is in the table.
*/
bool containsKey(const Key& key) const {
- size_t code = m_HashFunc(key);
- size_t b = code % numBuckets;
+ if (m_numBuckets == 0) {
+ return false;
+ }
- Node* node = bucket[b];
+ size_t code = HashFunc::hashCode(key);
+ size_t b = code % m_numBuckets;
+
+ Node* node = m_bucket[b];
while (node != NULL) {
- if ((node->hashCode == code) && (node->entry.key == key)) {
+ if ((node->hashCode == code) && EqualsFunc::equals(node->entry.key, key)) {
return true;
}
node = node->next;
- }
+ } while (node != NULL);
return false;
}
+
/**
Short syntax for get.
*/
@@ -617,6 +862,7 @@ public:
/**
Returns an array of all of the keys in the table.
You can iterate over the keys to get the values.
+ @deprecated
*/
Array<Key> getKeys() const {
Array<Key> keyArray;
@@ -626,8 +872,8 @@ public:
void getKeys(Array<Key>& keyArray) const {
keyArray.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
- for (size_t i = 0; i < numBuckets; i++) {
- Node* node = bucket[i];
+ for (size_t i = 0; i < m_numBuckets; i++) {
+ Node* node = m_bucket[i];
while (node != NULL) {
keyArray.append(node->entry.key);
node = node->next;
@@ -636,24 +882,17 @@ public:
}
/**
- Calls delete on all of the keys. Does not clear the table,
- however, so you are left with a table of dangling pointers.
-
- Same as <CODE>getKeys().deleteAll();</CODE>
-
- To delete all of the values, you may want something like
- <PRE>
- Array<Key> keys = table.getKeys();
- Set<Value> value;
- for (int k = 0; k < keys.length(); k++) {
- value.insert(keys[k]);
- }
- value.getMembers().deleteAll();
- keys.deleteAll();
- </PRE>
+ Calls delete on all of the keys and then clears the table.
*/
void deleteKeys() {
- getKeys().deleteAll();
+ for (size_t i = 0; i < m_numBuckets; i++) {
+ Node* node = m_bucket[i];
+ while (node != NULL) {
+ delete node->entry.key;
+ node = node->next;
+ }
+ }
+ clear();
}
/**
@@ -662,13 +901,14 @@ public:
at most once.
Does not clear the table, so you are left with a table
- of dangling pointers.
+ of NULL pointers.
*/
void deleteValues() {
- for (int i = 0; i < numBuckets; i++) {
- Node* node = bucket[i];
+ for (size_t i = 0; i < m_numBuckets; ++i) {
+ Node* node = m_bucket[i];
while (node != NULL) {
delete node->entry.value;
+ node->entry.value = NULL;
node = node->next;
}
}
@@ -677,9 +917,8 @@ public:
} // namespace
-#ifdef G3D_WIN32
+#ifdef _MSC_VER
# pragma warning (pop)
#endif
#endif
-
diff --git a/dep/include/g3dlite/G3D/TextInput.h b/dep/include/g3dlite/G3D/TextInput.h
new file mode 100644
index 00000000000..33eb8c48e53
--- /dev/null
+++ b/dep/include/g3dlite/G3D/TextInput.h
@@ -0,0 +1,801 @@
+/**
+ @file TextInput.h
+
+ Simple text lexer/tokenizer.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @cite Based on a lexer written by Aaron Orenstein.
+
+ @created 2002-11-27
+ @edited 2009-11-24
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_TextInput_h
+#define G3D_TextInput_h
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Set.h"
+#include "G3D/ParseError.h"
+#include <string>
+#include <queue>
+#include <ctype.h>
+#include <stdio.h>
+
+namespace G3D {
+
+/**
+ For use with TextInput.
+ */
+class Token {
+public:
+
+ /**
+ More detailed type information than Type.
+ */
+ enum ExtendedType {
+ DOUBLE_QUOTED_TYPE,
+ SINGLE_QUOTED_TYPE,
+ SYMBOL_TYPE,
+ FLOATING_POINT_TYPE,
+ INTEGER_TYPE,
+ BOOLEAN_TYPE,
+ LINE_COMMENT_TYPE,
+ BLOCK_COMMENT_TYPE,
+ NEWLINE_TYPE,
+ END_TYPE
+ };
+
+ /**
+ Strings are enclosed in quotes, symbols are not.
+ */
+ enum Type {
+ STRING = DOUBLE_QUOTED_TYPE,
+ SYMBOL = SYMBOL_TYPE,
+ NUMBER = FLOATING_POINT_TYPE,
+ BOOLEAN = BOOLEAN_TYPE,
+ COMMENT = LINE_COMMENT_TYPE,
+ NEWLINE = NEWLINE_TYPE,
+ END = END_TYPE
+ };
+
+private:
+
+ friend class TextInput;
+
+ /**
+ Holds the actual value, which might be any type. If a number, it will be
+ parsed at runtime.
+ */
+ std::string _string;
+
+ bool _bool;
+ int _line;
+ int _character;
+ Type _type;
+ ExtendedType _extendedType;
+
+public:
+
+ Token() :
+ _string(""),
+ _bool(false),
+ _line(0),
+ _character(0),
+ _type(END),
+ _extendedType(END_TYPE) {}
+
+ Token(Type t, ExtendedType e, const std::string& s, int L, int c)
+ : _string(s), _bool(false), _line(L), _character(c), _type(t), _extendedType(e) {}
+
+ Token(Type t, ExtendedType e, const std::string& s, bool b, int L, int c)
+ : _string(s), _bool(b), _line(L), _character(c), _type(t), _extendedType(e) {}
+
+ Type type() const {
+ return _type;
+ }
+
+ ExtendedType extendedType() const {
+ return _extendedType;
+ }
+
+ /**
+ The value of a single or double quote string (not including the quotes),
+ the name of a symbol, or the exact textual representation of a number as
+ parsed from the input.
+ */
+ const std::string& string() const {
+ return _string;
+ }
+
+ bool boolean() const {
+ return _bool;
+ }
+
+ /**
+ Starting line of the input from which this token was parsed. Starts
+ at 1.
+ */
+ int line() const {
+ return _line;
+ }
+
+ /**
+ Starting character position in the input line from which this token was
+ parsed. Starts at 1.
+ */
+ int character() const {
+ return _character;
+ }
+
+ /** Return the numeric value for a number type, or zero if this is
+ not a number type.
+ */
+ double number() const;
+};
+
+
+/**
+ A simple style tokenizer for reading text files. TextInput handles a
+ superset of C++,Java, Matlab, and Bash code text including single
+ line comments, block comments, quoted strings with escape sequences,
+ and operators. TextInput recognizes several categories of tokens,
+ which are separated by white space, quotation marks, or the end of a
+ recognized operator:
+
+ <ul>
+ <li><CODE>Token::SINGLE_QUOTED_TYPE</CODE> string of characters surrounded by single quotes, e.g., 'x', '\\0', 'foo'.
+ <li><CODE>Token::DOUBLE_QUOTED_TYPE</CODE> string of characters surrounded by double quotes, e.g., "x", "abc\txyz", "b o b".
+ <li><CODE>Token::SYMBOL_TYPE</CODE> legal C++ operators, keywords, and identifiers. e.g., >=, Foo, _X, class, {
+ <li><CODE>Token::INTEGER_TYPE</CODE> numbers without decimal places or exponential notation. e.g., 10, 0x17F, 32, 0, -155
+ <li><CODE>Token::FLOATING_POINT_TYPE</CODE> numbers with decimal places or exponential notation. e.g., 1e3, -1.2, .4, 0.5
+ <li><CODE>Token::BOOLEAN_TYPE</CODE> special symbols like "true" and "false"; the exact details can be configured in TextInput::Settings
+ <li><CODE>Token::LINE_COMMENT_TYPE</CODE> (disabled by default); generated for line comments as specified by TextInput::Settings
+ <li><CODE>Token::BLOCK_COMMENT_TYPE</CODE> (disabled by default); generated for c-style block comments as specified by TextInput::Settings
+ <li><CODE>Token::NEWLINE_TYPE</CODE> (disabled by default); generated for any of "\\r", "\\n" or "\\r\\n"
+ </ul>
+
+ <P>The special ".." and "..." tokens are always recognized in
+ addition to normal C++ operators. Additional tokens can be made
+ available by changing the Settings.
+
+ Negative numbers are handled specially because of the ambiguity between unary minus and negative numbers--
+ see the note on TextInput::read.
+
+ TextInput does not have helper functions for types with non-obvious
+ formatting, or helpers that would be redundant. Use the serialize
+ methods instead for parsing specific types like int, Vector3, and
+ Color3.
+
+ Inside quoted strings escape sequences are converted. Thus the
+ string token for ["a\\nb"] is 'a', followed by a newline, followed by
+ 'b'. Outside of quoted strings, escape sequences are not converted,
+ so the token sequence for [a\\nb] is symbol 'a', symbol '\\', symbol
+ 'nb' (this matches what a C++ parser would do). The exception is
+ that a specified TextInput::Settings::otherCommentCharacter preceeded
+ by a backslash is assumed to be an escaped comment character and is
+ returned as a symbol token instead of being parsed as a comment
+ (this is what a LaTex or VRML parser would do).
+
+ <B>Examples</B>
+
+ <PRE>
+ TextInput ti(TextInput::FROM_STRING, "name = \"Max\", height = 6");
+
+ Token t;
+
+ t = ti.read();
+ debugAssert(t.type == Token::SYMBOL);
+ debugAssert(t.sval == "name");
+
+ ti.read();
+ debugAssert(t.type == Token::SYMBOL);
+ debugAssert(t.sval == "=");
+
+ std::string name = ti.read().sval;
+ ti.read();
+ </PRE>
+
+ <PRE>
+ TextInput ti(TextInput::FROM_STRING, "name = \"Max\", height = 6");
+ ti.readSymbols("name", "=");
+ std::string name = ti.readString();
+ ti.readSymbols(",", "height", "=");
+ double height = ti. readNumber();
+ </PRE>
+
+ Assumes that the file is not modified once opened.
+ */
+class TextInput {
+public:
+
+ /** Tokenizer configuration options. */
+ class Settings {
+ public:
+ /** If true, C-style slash-star marks a multi-line comment.
+
+ See generateCommentTokens for rules on how this is applied.
+
+ Default is true.
+ */
+ bool cppBlockComments;
+
+ /** If true, // begins a single line comment.
+
+ See generateCommentTokens for rules on how this is applied.
+
+ Default is true.
+ */
+ bool cppLineComments;
+
+ /** If true, otherCommentCharacter and otherCommentCharacter2
+ are used to begin single line comments in the same way
+ cppLineComments is.
+
+ See generateCommentTokens for rules on how this is applied.
+
+ Default is true.
+ */
+ bool otherLineComments;
+
+ /** If true, \\r, \\n, \\t, \\0, \\\\ and other escape sequences inside
+ strings are converted to the equivalent C++ escaped character.
+ If false, backslashes are treated literally. It is convenient to
+ set to false if reading Windows paths, for example, like
+ c:\\foo\\bar.
+
+ Default is true.
+ */
+ bool escapeSequencesInStrings;
+
+ /** If not '\\0', specifies a character that begins single line
+ comments ('#' and '%' are popular choices). This is independent
+ of the cppLineComments flag. If the character appears in text with
+ a backslash in front of it, it is considered escaped and is not
+ treated as a comment character.
+
+ Default is '\\0'.
+ */
+ char otherCommentCharacter;
+
+ /** Another (optional) 1-comment character. Useful for files that
+ support multiple comment syntaxes. Default is '\\0'.
+ */
+ char otherCommentCharacter2;
+
+ /** If true, comments enabled by cppBlockComments, cppLineComments
+ and otherLineComments will generate their respective tokens.
+ If false, the same settings will enable parsing and ignoring
+ comments
+
+ Default is false.
+ */
+ bool generateCommentTokens;
+
+ /** If true, newlines will generate tokens.
+ If false, newlines will be discarded as whitespace when parsed
+ outside of other tokens.
+
+ Default is false.
+ */
+ bool generateNewlineTokens;
+
+ /** If true, "-1" parses as the number -1 instead of the
+ symbol "-" followed by the number 1. Default is true.*/
+ bool signedNumbers;
+
+ /** If true, strings can be marked with single quotes (e.g.,
+ 'aaa'). If false, the quote character is parsed as a
+ symbol. Default is true. Backquote (`) is always parsed
+ as a symbol. */
+ bool singleQuotedStrings;
+
+ /** The character to use as a single quote. Defaults to "'" (backquote),
+ occasionally useful to set to "`" (forward quote) or to "," (comma) for
+ reading CSV files. */
+ char singleQuoteCharacter;
+
+ /** If set to a non-empty string, that string will be used in
+ place of the real file name (or in place of a pseudonym
+ constructed from the buffer if given FROM_STRING) in
+ tokens and exceptions.
+
+ Default is empty.
+ */
+ std::string sourceFileName;
+
+
+ /** Added to the line number reported by peekLineNumber and in
+ exceptions. Useful for concatenating files that are
+ parsed separately. Default is zero. */
+ int startingLineNumberOffset;
+
+ /**
+ Parse -1.#IND00 as the floating point number returned by
+ nan(), -1.#INF00 as -inf(), and 1.#INF00 as inf(). Note
+ that the C99 standard specifies that a variety of formats
+ like "NaN" and "nan" are to be used; these are easier to
+ parse yourself and not currently supported by readNumber.
+
+ An alternative to specifying msvcSpecials is to read numbers as:
+ <pre>
+ Token x = t.read();
+ Token y = t.peek();
+ if ((x.string() == "-1.") &&
+ (y.string() == "#INF00") &&
+ (y.character() == x.character() + 3) &&
+ (y.line() == x.line()) {
+ t.read();
+ return nan();
+ }
+ // ... similar cases for inf
+ </pre>
+
+ If the single-comment character was #, the floating point
+ special format overrides the comment and will be parsed
+ instead.
+
+ If signedNumbers is false msvcSpecials will not be parsed.
+
+ Default is true. */
+ bool msvcSpecials;
+
+ /**
+ Parse the following set of useful proof symbols:
+
+ =>
+ ::>
+ <::
+ :>
+ <:
+ |-
+ ::=
+ :=
+ <-
+
+ Default is false.
+ */
+ bool proofSymbols;
+
+ /**
+ When parsing booleans and msvcSpecials, is case significant?
+ Default is {true}
+ */
+ bool caseSensitive;
+
+ /** All symbols that will become the 'true' boolean token. See also caseSensitive.
+ Clear this value to disable parsing of true booleans.
+
+ Default is {true}.
+ */
+ Set<std::string> trueSymbols;
+
+ /** See trueSymbols. Default is {false}*/
+ Set<std::string> falseSymbols;
+
+ Settings();
+ };
+
+private:
+
+ std::deque<Token> stack;
+
+ /**
+ Characters to be tokenized.
+ */
+ Array<char> buffer;
+
+ /**
+ Offset of current character (the next character to consumed) in
+ input buffer.
+ */
+ int currentCharOffset;
+
+ /**
+ Line number of next character to be consumed from the input buffer. (1
+ indicates first line of input.)
+
+ Note that this is the line number of the @e next character to be
+ consumed from the input, not the line number of the @e last character
+ consumed!
+ */
+ int lineNumber;
+
+ /**
+ Character number (within the line) of the next character to be consumed
+ from the input buffer. (1 indicates first character of the line).
+
+ Note that this is the character number of the @e next character to be
+ consumed from the input, not the character number of the @e last
+ character consumed!
+ */
+ int charNumber;
+
+ /** Configuration options. This includes the file name that will be
+ reported in tokens and exceptions. */
+ Settings options;
+
+ void init();
+
+ /**
+ Consumes the next character from the input buffer, and returns that
+ character. Updates lineNumber and charNumber to reflect the location of
+ the next character in the input buffer.
+
+ Note: you shouldn't be using the return value of this function in most
+ cases. In general, you should peekInputChar() to get the next
+ character, determine what to do with it, then consume it with this
+ function (or with eatAndPeekInputChar()). Given that usage, in most
+ instances you already know what this function would return!
+ */
+ int eatInputChar();
+
+ /**
+ Returns the next character from the input buffer, without consuming any
+ characters. Can also be used to look deeper into the input buffer.
+ Does not modify lineNumber or charNumber.
+
+ @param distance Index of the character in the input buffer to peek at,
+ relative to the next character. Default is 0, for the next character in
+ the input buffer.
+ */
+ int peekInputChar(int distance = 0);
+
+ /**
+ Helper function to consume the next character in the input buffer and
+ peek at the one following (without consuming it).
+ */
+ inline int eatAndPeekInputChar() {
+ eatInputChar();
+ return peekInputChar(0);
+ }
+
+ /**
+ Read the next token, returning an END token if no more input is
+ available.
+ */
+ Token nextToken();
+
+ /**
+ Helper for nextToken. Appends characters to t._string until the end
+ delimiter is reached.
+
+ When called, the next character in the input buffer should be first the
+ first character after the opening delimiter character.
+ */
+ void parseQuotedString(unsigned char delimiter, Token& t);
+
+public:
+
+ class TokenException : public ParseError {
+ public:
+ /** Name of file being parsed when exception occurred.
+ \deprecated Use filename
+ */
+ std::string sourceFile;
+
+ virtual ~TokenException() {}
+
+ protected:
+
+ TokenException(
+ const std::string& src,
+ int ln,
+ int ch);
+
+ };
+
+ /** While parsing a number of the form 1.\#IN?00, ? was
+ not 'D' or 'F'. */
+ class BadMSVCSpecial : public TokenException {
+ public:
+
+ BadMSVCSpecial(
+ const std::string& src,
+ int ln,
+ int ch);
+ };
+
+ /** Thrown by the read methods. */
+ class WrongTokenType : public TokenException {
+ public:
+ Token::Type expected;
+ Token::Type actual;
+
+ WrongTokenType(
+ const std::string& src,
+ int ln,
+ int ch,
+ Token::Type e,
+ Token::Type a);
+ };
+
+ class WrongSymbol : public TokenException {
+ public:
+ std::string expected;
+ std::string actual;
+
+ WrongSymbol(
+ const std::string& src,
+ int ln,
+ int ch,
+ const std::string& e,
+ const std::string& a);
+ };
+
+
+ /** String read from input did not match expected string. */
+ class WrongString : public TokenException {
+ public:
+ std::string expected;
+ std::string actual;
+
+ WrongString(
+ const std::string& src,
+ int ln,
+ int ch,
+ const std::string& e,
+ const std::string& a);
+ };
+
+ TextInput(const std::string& filename, const Settings& settings = Settings());
+
+ enum FS {FROM_STRING};
+ /** Creates input directly from a string. The first argument must be
+ TextInput::FROM_STRING.
+ */
+ TextInput(FS fs, const std::string& str, const Settings& settings = Settings());
+
+ /** Returns true while there are tokens remaining. */
+ bool hasMore();
+
+ /** Read the next token (which will be the END token if ! hasMore()).
+
+ Signed numbers can be handled in one of two modes. If the option
+ TextInput::Settings::signedNumbers is true,
+ A '+' or '-' immediately before a number is prepended onto that number and
+ if there is intervening whitespace, it is read as a separate symbol.
+
+ If TextInput::Settings::signedNumbers is false,
+ read() does not distinguish between a plus or minus symbol next
+ to a number and a positive/negative number itself. For example, "x - 1" and "x -1"
+ will be parsed the same way by read().
+
+ In both cases, readNumber() will contract a leading "-" or "+" onto
+ a number.
+ */
+ Token read();
+
+ /** Calls read() until the result is not a newline or comment */
+ Token readSignificant();
+
+ /** Read one token (or possibly two) as a number or throws
+ WrongTokenType, and returns the number.
+
+ If the first token in the input is a number, it is returned directly.
+
+ If TextInput::Settings::signedNumbers is false and the input stream
+ contains a '+' or '-' symbol token immediately followed by a number
+ token, both tokens will be consumed and a single token will be
+ returned by this method.
+
+ WrongTokenType will be thrown if one of the input conditions
+ described above is not satisfied. When an exception is thrown, no
+ tokens are consumed.
+ */
+ double readNumber();
+
+ bool readBoolean();
+
+ /** Reads a string token or throws WrongTokenType, and returns the token.
+
+ Use this method (rather than readString) if you want the token's
+ location as well as its value.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a string. When an exception is thrown, no tokens are
+ consumed.
+ */
+ Token readStringToken();
+
+ /** Like readStringToken, but returns the token's string.
+
+ Use this method (rather than readStringToken) if you want the token's
+ value but don't really care about its location in the input. Use of
+ readStringToken is encouraged for better error reporting.
+ */
+ std::string readString();
+
+ /** Reads a specific string token or throws either WrongTokenType or
+ WrongString. If the next token in the input is a string matching @p
+ s, it will be consumed.
+
+ Use this method if you want to match a specific string from the
+ input. In that case, typically error reporting related to the token
+ is only going to occur because of a mismatch, so no location
+ information is needed by the caller.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a string. WrongString will be thrown if the next token in the
+ input stream is a string but does not match the @p s parameter. When
+ an exception is thrown, no tokens are consumed.
+ */
+ void readString(const std::string& s);
+
+ /** Reads a comment token or throws WrongTokenType, and returns the token.
+
+ Use this method (rather than readComment) if you want the token's
+ location as well as its value.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a comment. When an exception is thrown, no tokens are
+ consumed.
+ */
+ Token readCommentToken();
+
+ /** Like readCommentToken, but returns the token's string.
+
+ Use this method (rather than readCommentToken) if you want the token's
+ value but don't really care about its location in the input. Use of
+ readCommentToken is encouraged for better error reporting.
+ */
+ std::string readComment();
+
+ /** Reads a specific comment token or throws either WrongTokenType or
+ WrongString. If the next token in the input is a comment matching @p
+ s, it will be consumed.
+
+ Use this method if you want to match a specific comment from the
+ input. In that case, typically error reporting related to the token
+ is only going to occur because of a mismatch, so no location
+ information is needed by the caller.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a comment. WrongString will be thrown if the next token in the
+ input stream is a comment but does not match the @p s parameter. When
+ an exception is thrown, no tokens are consumed.
+ */
+ void readComment(const std::string& s);
+
+ /** Reads a newline token or throws WrongTokenType, and returns the token.
+
+ Use this method (rather than readNewline) if you want the token's
+ location as well as its value.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a newline. When an exception is thrown, no tokens are
+ consumed.
+ */
+ Token readNewlineToken();
+
+ /** Like readNewlineToken, but returns the token's string.
+
+ Use this method (rather than readNewlineToken) if you want the token's
+ value but don't really care about its location in the input. Use of
+ readNewlineToken is encouraged for better error reporting.
+ */
+ std::string readNewline();
+
+ /** Reads a specific newline token or throws either WrongTokenType or
+ WrongString. If the next token in the input is a newline matching @p
+ s, it will be consumed.
+
+ Use this method if you want to match a specific newline from the
+ input. In that case, typically error reporting related to the token
+ is only going to occur because of a mismatch, so no location
+ information is needed by the caller.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a newline. WrongString will be thrown if the next token in the
+ input stream is a newlin but does not match the @p s parameter. When
+ an exception is thrown, no tokens are consumed.
+ */
+ void readNewline(const std::string& s);
+
+ /** Reads a symbol token or throws WrongTokenType, and returns the token.
+
+ Use this method (rather than readSymbol) if you want the token's
+ location as well as its value.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a symbol. When an exception is thrown, no tokens are
+ consumed.
+ */
+ Token readSymbolToken();
+
+ /** Like readSymbolToken, but returns the token's string.
+
+ Use this method (rather than readSymbolToken) if you want the token's
+ value but don't really care about its location in the input. Use of
+ readSymbolToken is encouraged for better error reporting.
+ */
+ std::string readSymbol();
+
+ /** Reads a specific symbol token or throws either WrongTokenType or
+ WrongSymbol. If the next token in the input is a symbol matching @p
+ symbol, it will be consumed.
+
+ Use this method if you want to match a specific symbol from the
+ input. In that case, typically error reporting related to the token
+ is only going to occur because of a mismatch, so no location
+ information is needed by the caller.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a symbol. WrongSymbol will be thrown if the next token in the
+ input stream is a symbol but does not match the @p symbol parameter.
+ When an exception is thrown, no tokens are consumed.
+ */
+ void readSymbol(const std::string& symbol);
+
+
+ /** Read a series of two specific symbols. See readSymbol. */
+ inline void readSymbols(const std::string& s1, const std::string& s2) {
+ readSymbol(s1);
+ readSymbol(s2);
+ }
+
+ /** Read a series of three specific symbols. See readSymbol. */
+ inline void readSymbols(
+ const std::string& s1,
+ const std::string& s2,
+ const std::string& s3) {
+ readSymbol(s1);
+ readSymbol(s2);
+ readSymbol(s3);
+ }
+
+ /** Read a series of four specific symbols. See readSymbol. */
+ inline void readSymbols(
+ const std::string& s1,
+ const std::string& s2,
+ const std::string& s3,
+ const std::string& s4) {
+ readSymbol(s1);
+ readSymbol(s2);
+ readSymbol(s3);
+ readSymbol(s4);
+ }
+
+ /** Return a copy of the next token in the input stream, but don't remove
+ it from the input stream.
+ */
+ Token peek();
+
+ /** Returns the line number for the @e next token. See also peek. */
+ int peekLineNumber();
+
+ /** Returns the character number (relative to the line) for the @e next
+ token in the input stream. See also peek.
+ */
+ int peekCharacterNumber();
+
+ /** Take a previously read token and push it back at the front of the
+ input stream.
+
+ Can be used in the case where more than one token of read-ahead is
+ needed (i.e., when peek doesn't suffice).
+ */
+ void push(const Token& t);
+
+ /** Returns the filename from which this input is drawn, or the first few
+ characters of the string if created from a string.
+ If settings::filename is non-empty that will replace the
+ true filename.*/
+ const std::string& filename() const;
+};
+
+void deserialize(bool& b, TextInput& ti);
+void deserialize(int& b, TextInput& ti);
+void deserialize(uint8& b, TextInput& ti);
+void deserialize(double& b, TextInput& ti);
+void deserialize(float& b, TextInput& ti);
+void deserialize(std::string& b, TextInput& ti);
+
+} // namespace
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/TextOutput.h b/dep/include/g3dlite/G3D/TextOutput.h
new file mode 100644
index 00000000000..4c22b7d5653
--- /dev/null
+++ b/dep/include/g3dlite/G3D/TextOutput.h
@@ -0,0 +1,249 @@
+/**
+ @file TextOutput.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2004-06-21
+ @edited 2006-10-24
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_TEXTOUTPUT_H
+#define G3D_TEXTOUTPUT_H
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include <string>
+
+namespace G3D {
+
+/**
+ Convenient formatting of ASCII text written to a file.
+ <P>
+
+ The core writeString, writeNumber, and writeSymbol methods map to TextInput's
+ methods. Number and Symbol each print an additional space that is used to
+ separate adjacent tokens.
+
+ TextOutput::printf allows arbitrary text to be conveniently dumped
+ en-masse. Use [de]serialize(bool, TextOutput) and other overloads to read/write
+ primitive types in a standardized manner and
+
+ <P>
+ When a word-wrap line break occurs, all whitespace between words is replaced
+ with a single newline (the newline may be two characters-- see
+ G3D::TextOutput::Options::NewlineStyle). Word wrapping occurs against
+ the number of columns specified by Options::numColumns, <I>minus</I> the current
+ indent level.
+
+ Indenting adds the specified number of spaces immediately after a newline.
+ If a newline was followed by spaces in the original string, these are added
+ to the indent spaces. Indenting <B>will</B> indent blank lines and will leave
+ indents after the last newline of a file (if the indent level is non-zero at the end).
+
+ <P><B>Serialization/Marshalling</B>
+ <DT>Text serialization is accomplished using TextOutput by defining the pair of
+ methods:
+
+ <PRE>
+ void serialize(TextOutput& to) const;
+ void deserialize(TextInput& ti);
+ </PRE>
+
+ See also G3D::TextInput.
+
+ <P>
+ <B>BETA API</B>
+ <DT>This API is subject to change in future versions.
+ */
+class TextOutput {
+public:
+
+ class Settings {
+ public:
+ /**
+ WRAP_NONE Word wrapping is disabled
+ WRAP_WITHOUT_BREAKING Word-wrap, but don't break continuous lines that
+ are longer than numColumns (default)
+ WRAP_ALWAYS Wrap even if it means breaking a continuous line or
+ a quoted string.
+
+ Word wrapping is only allowed at whitespaces ('\\n', '\\r', '\\t', ' '); it
+ will not occur after commas, punctuation, minus signs, or any other characters
+ */
+ enum WordWrapMode {WRAP_NONE, WRAP_WITHOUT_BREAKING, WRAP_ALWAYS};
+
+ /** Defaults to WRAP_WITHOUT_BREAKING */
+ WordWrapMode wordWrap;
+
+ /** Is word-wrapping allowed to insert newlines inside double quotes?
+ Default: false */
+ bool allowWordWrapInsideDoubleQuotes;
+
+ /** Number of columns for word wrapping. Default: 8 */
+ int numColumns;
+
+ /** Number of spaces in each indent. Default: 4 */
+ int spacesPerIndent;
+
+ /** Style of newline used by word wrapping and by (optional) conversion.
+ default: Windows: NEWLINE_WINDOWS, Linux, OS X: NEWLINE_UNIX.
+ */
+ enum NewlineStyle {NEWLINE_WINDOWS, NEWLINE_UNIX};
+
+ NewlineStyle newlineStyle;
+
+ /** If true, all newlines are converted to NewlineStyle regardless of
+ how they start out. Default: true. */
+ bool convertNewlines;
+
+ /** Used by writeBoolean */
+ std::string trueSymbol;
+
+ /** Used by writeBoolean */
+ std::string falseSymbol;
+
+ Settings() :
+ wordWrap(WRAP_WITHOUT_BREAKING),
+ allowWordWrapInsideDoubleQuotes(false),
+ numColumns(80),
+ spacesPerIndent(4),
+ convertNewlines(true),
+ trueSymbol("true"),
+ falseSymbol("false") {
+ #ifdef G3D_WIN32
+ newlineStyle = NEWLINE_WINDOWS;
+ #else
+ newlineStyle = NEWLINE_UNIX;
+ #endif
+ }
+ };
+
+private:
+
+ /** Used by indentAndAppend to tell when we are writing the
+ first character of a new line.
+
+ So that push/popIndent work correctly, we cannot indent
+ immediately after writing a newline. Instead we must
+ indent on writing the first character <B>after</B> that
+ newline.
+ */
+ bool startingNewLine;
+
+ /** Number of characters at the end of the buffer since the last newline */
+ int currentColumn;
+
+ /** True if we have seen an open " and no close ".*/
+ bool inDQuote;
+
+ /** Empty if there is none */
+ std::string filename;
+
+ Array<char> data;
+
+ Settings option;
+
+ /** Number of indents to prepend before each line. Always set using setIndentLevel.*/
+ int indentLevel;
+
+ void setIndentLevel(int i);
+
+ /** Actual number of spaces to indent. */
+ int indentSpaces;
+
+ /** the newline character(s) */
+ std::string newline;
+
+ void setOptions(const Settings& _opt);
+
+ /** Converts to the desired newlines. Called from vprintf */
+ void convertNewlines(const std::string& in, std::string& out);
+
+ /** Called from vprintf */
+ void wordWrapIndentAppend(const std::string& str);
+
+ /** Appends the character to data, indenting whenever a newline is encountered.
+ Called from wordWrapIndentAppend */
+ void indentAppend(char c);
+
+public:
+
+ explicit TextOutput(const std::string& filename, const Settings& options = Settings());
+
+ /** Constructs a text output that can later be commited to a string instead of a file.*/
+ explicit TextOutput(const Settings& options = Settings());
+
+ /** Commit to the filename specified on the constructor.
+ <B>Not</B> called from the destructor; you must call
+ it yourself.
+ @param flush If true (default) the file is ready for reading when the method returns, otherwise
+ the method returns immediately and writes the file in the background.*/
+ void commit(bool flush = true);
+
+ /** Commits to this string */
+ void commitString(std::string& string);
+
+ /** Increase indent level by 1 */
+ void pushIndent();
+
+ void popIndent();
+
+ /** Produces a new string that contains the output */
+ std::string commitString();
+
+ /** Writes a quoted string. Special characters in the string (e.g., \\, \\t, \\n) are escaped so that
+ TextInput will produce the identical string on reading.*/
+ void writeString(const std::string& string);
+
+ void writeBoolean(bool b);
+
+ void writeNumber(double n);
+
+ void writeNumber(int n);
+
+ void writeNewline();
+ void writeNewlines(int numLines);
+
+ /** The symbol is written without quotes. Symbols are required to begin with a
+ letter or underscore and contain only letters, underscores, and numbers
+ or be a C++ symbol (e.g. "{", "(", "++", etc.)
+ so that they may be properly parsed by TextInput::readSymbol. Symbols are
+ printed with a trailing space.*/
+ void writeSymbol(const std::string& string);
+
+ /** Convenient idiom for writing multiple symbols in a row, e.g.
+ writeSymbols("name", "="); The empty symbols are not written.
+ */
+ void writeSymbols(
+ const std::string& a,
+ const std::string& b = "",
+ const std::string& c = "",
+ const std::string& d = "",
+ const std::string& e = "",
+ const std::string& f = "");
+
+ /** Normal printf conventions. Note that the output will be reformatted
+ for word-wrapping and newlines */
+ void __cdecl printf(const char* fmt, ...)
+ G3D_CHECK_PRINTF_METHOD_ARGS;
+
+ // Can't pass by reference because that confuses va_start
+ void __cdecl printf(const std::string fmt, ...);
+ void __cdecl vprintf(const char* fmt, va_list argPtr)
+ G3D_CHECK_VPRINTF_METHOD_ARGS;
+};
+
+// Primitive serializers
+void serialize(const bool& b, TextOutput& to);
+void serialize(const int& b, TextOutput& to);
+void serialize(const uint8& b, TextOutput& to);
+void serialize(const double& b, TextOutput& to);
+void serialize(const float& b, TextOutput& to);
+void serialize(const std::string& b, TextOutput& to);
+void serialize(const char* b, TextOutput& to);
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/ThreadSet.h b/dep/include/g3dlite/G3D/ThreadSet.h
new file mode 100644
index 00000000000..121f1415a1d
--- /dev/null
+++ b/dep/include/g3dlite/G3D/ThreadSet.h
@@ -0,0 +1,87 @@
+#ifndef G3D_THREADSET_H
+#define G3D_THREADSET_H
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/ReferenceCount.h"
+#include "G3D/GThread.h"
+#include "G3D/GMutex.h"
+
+namespace G3D {
+
+/** Manages a set of threads. All methods are threadsafe except for
+ the iterator begin/end.
+
+ @beta*/
+class ThreadSet : public ReferenceCountedObject {
+public:
+ /** Intended to allow future use with a template parameter.*/
+ typedef GThread Thread;
+
+ typedef ReferenceCountedPointer<Thread> ThreadRef;
+ typedef ReferenceCountedPointer<ThreadSet> Ref;
+ typedef Array<ThreadRef>::Iterator Iterator;
+ typedef Array<ThreadRef>::ConstIterator ConstIterator;
+
+private:
+
+ /** Protects m_thread */
+ GMutex m_lock;
+
+ /** Threads in the set */
+ Array<ThreadRef> m_thread;
+
+public:
+
+ /** Total number of threads (some of which may be completed). */
+ int size() const;
+
+ /** Number of threads that have been started */
+ int numStarted() const;
+
+ /** Start all threads that are not currently started.
+
+ @param lastThreadBehavior If USE_CURRENT_THREAD, takes the last unstarted thread and executes it manually on
+ the current thread. This helps to take full advantage of the machine when
+ running a large number of jobs and avoids the overhead of a thread start for single-thread groups.
+ Note that this forces start() to block until
+ that thread is complete.
+ */
+ void start(GThread::SpawnBehavior lastThreadBehavior = GThread::USE_NEW_THREAD) const;
+
+ /** Terminate all threads that are currently started */
+ void terminate() const;
+
+ /** Waits until all started threads have completed. */
+ void waitForCompletion() const;
+
+ /** Remove all (not stopping them) */
+ void clear();
+
+ /** Removes completed threads and returns the new size.*/
+ int removeCompleted();
+
+ /** Inserts a new thread, if it is not already present, and
+ returns the new number of threads.*/
+ int insert(const ThreadRef& t);
+
+ /** Removes a thread. Returns true if the thread was present and
+ removed. */
+ bool remove(const ThreadRef& t);
+
+ bool contains(const ThreadRef& t) const;
+
+ /** It is an error to mutate the ThreadSet while iterating through it. */
+ Iterator begin();
+
+ Iterator end();
+
+ ConstIterator begin() const;
+
+ ConstIterator end() const;
+};
+
+
+} // namespace G3D
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Triangle.h b/dep/include/g3dlite/G3D/Triangle.h
index 6852dac9492..590dbaad946 100644
--- a/dep/include/g3dlite/G3D/Triangle.h
+++ b/dep/include/g3dlite/G3D/Triangle.h
@@ -1,14 +1,14 @@
/**
@file Triangle.h
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2003-04-05
- @edited 2004-03-14
+ @edited 2008-10-06
@cite Random point method by Greg Turk, Generating random points in triangles. In A. S. Glassner, ed., Graphics Gems, pp. 24-28. Academic Press, 1990
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -19,6 +19,8 @@
#include "G3D/g3dmath.h"
#include "G3D/Vector3.h"
#include "G3D/Plane.h"
+#include "G3D/BoundsTrait.h"
+#include "G3D/debugAssert.h"
#include <string>
namespace G3D {
@@ -38,25 +40,30 @@ private:
/** edgeDirection[i] is the normalized vector v[i+1] - v[i] */
Vector3 edgeDirection[3];
- double edgeMagnitude[3];
+ float edgeMagnitude[3];
Plane _plane;
Vector3::Axis _primaryAxis;
/** vertex[1] - vertex[0] */
- Vector3 edge01;
+ Vector3 _edge01;
+
/** vertex[2] - vertex[0] */
- Vector3 edge02;
+ Vector3 _edge02;
float _area;
void init(const Vector3& v0, const Vector3& v1, const Vector3& v2);
public:
+
+ Triangle(class BinaryInput& b);
+ void serialize(class BinaryOutput& b);
+ void deserialize(class BinaryInput& b);
Triangle();
-
+
Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2);
-
+
~Triangle();
/** 0, 1, or 2 */
@@ -65,7 +72,17 @@ public:
return _vertex[n];
}
- double area() const;
+ /** vertex[1] - vertex[0] */
+ inline const Vector3& edge01() const {
+ return _edge01;
+ }
+
+ /** vertex[2] - vertex[0] */
+ inline const Vector3& edge02() const {
+ return _edge02;
+ }
+
+ float area() const;
Vector3::Axis primaryAxis() const {
return _primaryAxis;
@@ -81,6 +98,13 @@ public:
/** Returns a random point in the triangle. */
Vector3 randomPoint() const;
+ inline void getRandomSurfacePoint
+ (Vector3& P,
+ Vector3& N = Vector3::ignore()) const {
+ P = randomPoint();
+ N = normal();
+ }
+
/**
For two triangles to be equal they must have
the same vertices <I>in the same order</I>.
@@ -96,22 +120,41 @@ public:
return true;
}
- inline unsigned int hashCode() const {
+ inline size_t hashCode() const {
return
_vertex[0].hashCode() +
(_vertex[1].hashCode() >> 2) +
- _vertex[2].hashCode();
+ (_vertex[2].hashCode() >> 3);
}
void getBounds(class AABox&) const;
+ /**
+ @brief Intersect the ray at distance less than @a distance.
+
+ @param distance Set to the maximum distance (can be G3D::inf())
+ to search for an intersection. On return, this is the smaller
+ of the distance to the intersection, if one exists, and the original
+ value.
+
+ @param baryCoord If a triangle is hit before @a distance, a
+ the barycentric coordinates of the hit location on the triangle.
+ Otherwise, unmodified.
+
+ @return True if there was an intersection before the original distance.
+ */
+ bool intersect(const class Ray& ray, float& distance, float baryCoord[3]) const;
+};
+
+} // namespace G3D
+
+template <> struct HashTrait<G3D::Triangle> {
+ static size_t hashCode(const G3D::Triangle& key) { return key.hashCode(); }
};
-} // namespace
-inline unsigned int hashCode(const G3D::Triangle& t) {
- return t.hashCode();
-}
+template<> struct BoundsTrait<class G3D::Triangle> {
+ static void getBounds(const G3D::Triangle& t, G3D::AABox& out) { t.getBounds(out); }
+};
#endif
-
diff --git a/dep/include/g3dlite/G3D/UprightFrame.h b/dep/include/g3dlite/G3D/UprightFrame.h
new file mode 100644
index 00000000000..ad5157cb14b
--- /dev/null
+++ b/dep/include/g3dlite/G3D/UprightFrame.h
@@ -0,0 +1,83 @@
+/**
+ @file UprightFrame.h
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ */
+
+#ifndef G3D_UPRIGHTFRAME_H
+#define G3D_UPRIGHTFRAME_H
+
+#include "G3D/platform.h"
+#include "G3D/Spline.h"
+#include "G3D/Vector3.h"
+#include "G3D/CoordinateFrame.h"
+
+namespace G3D {
+
+/**
+ Coordinate frame expressed in Euler angles.
+ Unlike a G3D::Quat, UprightFrame always keeps the reference frame from rolling about its own z axis.
+ Particularly useful for cameras.
+
+ @sa G3D::CoordinateFrame, G3D::Matrix4, G3D::PhysicsFrame, G3D::UprightSpline, G3D::UprightSplineManipulator
+ */
+class UprightFrame {
+public:
+
+ Vector3 translation;
+
+ /** -pi/2 < pitch < pi/2 in radians about the X-axis */
+ float pitch;
+
+ /** In radians about the Y-axis */
+ float yaw;
+
+ inline UprightFrame(const Vector3& t = Vector3::zero(), float p = 0, float y = 0)
+ : translation(t), pitch(p), yaw(y) {}
+
+ UprightFrame(const CoordinateFrame& cframe);
+
+ CoordinateFrame toCoordinateFrame() const;
+
+ /** Supports implicit cast to CoordinateFrame */
+ inline operator CoordinateFrame() const {
+ return toCoordinateFrame();
+ }
+
+ /** Required for use with spline */
+ UprightFrame operator+(const UprightFrame& other) const;
+
+ /** Required for use with spline */
+ UprightFrame operator*(const float k) const;
+
+ /**
+ Unwraps the yaw values in the elements of the array such that
+ they still represent the same angles but strictly increase/decrease
+ without wrapping about zero. For use with Spline<UprightFrame>
+ */
+ static void unwrapYaw(UprightFrame* a, int N);
+
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+};
+
+/** Shortest-path linear velocity spline for camera positions. Always keeps the camera from rolling.
+@sa G3D::UprightSplineManipulator, G3D::UprightFrame
+*/
+class UprightSpline : public Spline<UprightFrame> {
+protected:
+
+ virtual void ensureShortestPath(UprightFrame* A, int N) const {
+ UprightFrame::unwrapYaw(A, N);
+ }
+
+public:
+
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Vector2.h b/dep/include/g3dlite/G3D/Vector2.h
index 273ab6b4d07..dba7353785e 100644
--- a/dep/include/g3dlite/G3D/Vector2.h
+++ b/dep/include/g3dlite/G3D/Vector2.h
@@ -1,29 +1,35 @@
/**
@file Vector2.h
-
+
2D vector class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2001-06-02
- @edited 2006-01-14
- Copyright 2000-2006, Morgan McGuire.
+ @edited 2008-11-30
+
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
#ifndef G3D_VECTOR2_H
#define G3D_VECTOR2_H
+#include <string>
+
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
-#include "Vector2int16.h"
-#include <string>
+#include "G3D/Table.h"
+#include "G3D/HashTrait.h"
+#include "G3D/Vector2int16.h"
+#include "G3D/Random.h"
namespace G3D {
-class Vector2;
+class Vector2;
class Vector3;
class Vector4;
+class Any;
/**
Do not subclass-- this implementation makes assumptions about the
@@ -38,29 +44,42 @@ private:
bool operator>=(const Vector2&) const;
public:
- // coordinates
- float x, y;
+ float x;
+ float y;
+
+ /** \param any Must either Vector2(#, #) or Vector2 {x = #, y = #}*/
+ Vector2(const Any& any);
+
+ /** Converts the Vector2 to an Any. */
+ operator Any() const;
- // construction
+ /** Creates the zero vector */
Vector2();
+ Vector2(class TextInput& t);
+ Vector2(class BinaryInput& b);
Vector2(float x, float y);
Vector2(float coordinate[2]);
Vector2(double coordinate[2]);
- Vector2(const Vector2& rkVector);
- Vector2(const class Vector2int16& v);
+ Vector2(const Vector2& other);
+ Vector2(const Vector2int16& other);
+
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ void serialize(class TextOutput& t) const;
+ void deserialize(class TextInput& t);
- float& operator[] (int i);
- const float& operator[] (int i) const;
- operator float* ();
- operator const float* () const;
+ float& operator[](int i);
+ const float& operator[](int i) const;
// assignment and comparison
- Vector2& operator= (const Vector2& rkVector);
- bool operator== (const Vector2& rkVector) const;
- bool operator!= (const Vector2& rkVector) const;
- unsigned int hashCode() const;
+ Vector2& operator=(const Vector2& other);
+ bool operator==(const Vector2& other) const;
+ bool operator!=(const Vector2& other) const;
+ size_t hashCode() const;
bool fuzzyEq(const Vector2& other) const;
bool fuzzyNe(const Vector2& other) const;
+
/** Returns true if this vector has finite length */
bool isFinite() const;
@@ -71,14 +90,21 @@ public:
bool isUnit() const;
// arithmetic operations
- Vector2 operator+ (const Vector2& rkVector) const;
- Vector2 operator- (const Vector2& rkVector) const;
- Vector2 operator* (float fScalar) const;
- Vector2 operator* (const Vector2& rkVector) const;
- Vector2 operator/ (const Vector2& rkVector) const;
- Vector2 operator/ (float fScalar) const;
- Vector2 operator- () const;
+ Vector2 operator+(const Vector2& v) const;
+ Vector2 operator-(const Vector2& v) const;
+ Vector2 operator*(float s) const;
+
+ /** Array (pointwise) multiplication */
+ Vector2 operator*(const Vector2& v) const;
+
+ /** Array division */
+ Vector2 operator/(const Vector2& v) const;
+ Vector2 operator/(float s) const;
+ /** Unary minus */
+ Vector2 operator-() const;
+
+ /** x + y */
inline float sum() const {
return x + y;
}
@@ -87,7 +113,7 @@ public:
Linear interpolation
*/
inline Vector2 lerp(const Vector2& v, float alpha) const {
- return (*this) + (v - *this) * alpha;
+ return (*this) + (v - *this) * alpha;
}
inline Vector2 clamp(const Vector2& low, const Vector2& high) const {
@@ -103,16 +129,21 @@ public:
}
// arithmetic updates
- Vector2& operator+= (const Vector2& rkVector);
- Vector2& operator-= (const Vector2& rkVector);
- Vector2& operator*= (float fScalar);
- Vector2& operator/= (float fScalar);
- Vector2& operator*= (const Vector2& rkVector);
- Vector2& operator/= (const Vector2& rkVector);
+ Vector2& operator+=(const Vector2&);
+ Vector2& operator-=(const Vector2&);
+ Vector2& operator*=(float);
+ Vector2& operator/=(float);
+ Vector2& operator*=(const Vector2&);
+ Vector2& operator/=(const Vector2&);
// vector operations
+
+ /** */
float length() const;
+
+ /** Returns a unit-length vector */
Vector2 direction() const;
+
/**
Potentially less accurate but faster than direction().
Only works if System::hasSSE is true.
@@ -121,37 +152,34 @@ public:
return direction();
}
- float squaredLength () const;
- float dot (const Vector2& rkVector) const;
- float unitize (float fTolerance = 1e-06);
+ float squaredLength() const;
+ float dot(const Vector2& s) const;
- Vector2 min(const Vector2 &v) const;
- Vector2 max(const Vector2 &v) const;
+ /**
+ Make this vector have unit length and return the old length.
+ If the vector length was less than tolerance, do not normalize.
+ */
+ float unitize(float fTolerance = 1e-06);
- // Random unit vector
- static Vector2 random();
+ Vector2 min(const Vector2& v) const;
+ Vector2 max(const Vector2& v) const;
+
+ /** Uniformly distributed random vector on the unit sphere */
+ static Vector2 random(Random& r = Random::common());
// Special values.
// Intentionally not inlined: see Matrix3::identity() for details.
static const Vector2& zero();
- inline static const Vector2& one() { static const Vector2 v(1, 1); return v; }
+ static const Vector2& one();
static const Vector2& unitX();
static const Vector2& unitY();
- static const Vector2& inf();
+ static const Vector2& inf();
static const Vector2& nan();
/** smallest (most negative) representable vector */
- static const Vector2& minFinite();
+ static const Vector2& minFinite();
/** Largest representable vector */
static const Vector2& maxFinite();
- // Deprecated. See Matrix3::identity() for details.
- /** @deprecated Use Vector2::zero() */
- static const Vector2 ZERO;
- /** @deprecated Use Vector2::unitX() */
- static const Vector2 UNIT_S;
- /** @deprecated Use Vector2::unitY() */
- static const Vector2 UNIT_T;
-
std::string toString() const;
// 2-char swizzles
@@ -205,49 +233,47 @@ inline Vector2 operator*(int s, const Vector2& v) {
return v * (float)s;
}
-inline unsigned int hashCode(const G3D::Vector2& v) {
- return v.hashCode();
-}
inline Vector2::Vector2 () : x(0.0f), y(0.0f) {
}
+
inline Vector2::Vector2(float _x, float _y) : x(_x), y(_y) {
}
+
inline Vector2::Vector2 (float afCoordinate[2]) {
x = afCoordinate[0];
y = afCoordinate[1];
}
+
+
inline Vector2::Vector2 (double afCoordinate[2]) {
x = (float)afCoordinate[0];
y = (float)afCoordinate[1];
}
+
inline Vector2::Vector2 (const Vector2& rkVector) {
x = rkVector.x;
y = rkVector.y;
}
+
inline Vector2::Vector2 (const Vector2int16& v) : x(v.x), y(v.y) {
}
+
inline float& Vector2::operator[] (int i) {
return ((float*)this)[i];
}
+
inline const float& Vector2::operator[] (int i) const {
return ((float*)this)[i];
}
-inline Vector2::operator float* () {
- return (float*)this;
-}
-
-inline Vector2::operator const float* () const {
- return (float*)this;
-}
inline Vector2& Vector2::operator= (const Vector2& rkVector) {
x = rkVector.x;
@@ -255,42 +281,55 @@ inline Vector2& Vector2::operator= (const Vector2& rkVector) {
return *this;
}
+
inline bool Vector2::operator== (const Vector2& rkVector) const {
return ( x == rkVector.x && y == rkVector.y);
}
+
inline bool Vector2::operator!= (const Vector2& rkVector) const {
return ( x != rkVector.x || y != rkVector.y);
}
+
inline Vector2 Vector2::operator+ (const Vector2& rkVector) const {
return Vector2(x + rkVector.x, y + rkVector.y);
}
+
inline Vector2 Vector2::operator- (const Vector2& rkVector) const {
return Vector2(x - rkVector.x, y - rkVector.y);
}
+
inline Vector2 Vector2::operator* (float fScalar) const {
return Vector2(fScalar*x, fScalar*y);
}
+
+
inline Vector2 Vector2::operator- () const {
return Vector2( -x, -y);
}
+
+
inline Vector2& Vector2::operator+= (const Vector2& rkVector) {
x += rkVector.x;
y += rkVector.y;
return *this;
}
+
+
inline Vector2& Vector2::operator-= (const Vector2& rkVector) {
x -= rkVector.x;
y -= rkVector.y;
return *this;
}
+
+
inline Vector2& Vector2::operator*= (float fScalar) {
x *= fScalar;
y *= fScalar;
@@ -298,34 +337,44 @@ inline Vector2& Vector2::operator*= (float fScalar) {
}
+
+
inline Vector2& Vector2::operator*= (const Vector2& rkVector) {
x *= rkVector.x;
y *= rkVector.y;
return *this;
}
+
+
inline Vector2& Vector2::operator/= (const Vector2& rkVector) {
x /= rkVector.x;
y /= rkVector.y;
return *this;
}
+
inline Vector2 Vector2::operator* (const Vector2& rkVector) const {
return Vector2(x * rkVector.x, y * rkVector.y);
}
+
+
inline Vector2 Vector2::operator/ (const Vector2& rkVector) const {
return Vector2(x / rkVector.x, y / rkVector.y);
}
+
inline float Vector2::squaredLength () const {
return x*x + y*y;
}
+
inline float Vector2::length () const {
return sqrtf(x*x + y*y);
}
+
inline Vector2 Vector2::direction () const {
float lenSquared = x * x + y * y;
@@ -336,39 +385,63 @@ inline Vector2 Vector2::direction () const {
}
}
+
+
inline float Vector2::dot (const Vector2& rkVector) const {
return x*rkVector.x + y*rkVector.y;
}
+
+
inline Vector2 Vector2::min(const Vector2 &v) const {
return Vector2(G3D::min(v.x, x), G3D::min(v.y, y));
}
+
+
inline Vector2 Vector2::max(const Vector2 &v) const {
return Vector2(G3D::max(v.x, x), G3D::max(v.y, y));
}
+
+
inline bool Vector2::fuzzyEq(const Vector2& other) const {
return G3D::fuzzyEq((*this - other).squaredLength(), 0);
}
+
+
inline bool Vector2::fuzzyNe(const Vector2& other) const {
return G3D::fuzzyNe((*this - other).squaredLength(), 0);
}
+
+
inline bool Vector2::isFinite() const {
return G3D::isFinite(x) && G3D::isFinite(y);
}
+
+
inline bool Vector2::isZero() const {
return (x == 0.0f) && (y == 0.0f);
}
+
+
inline bool Vector2::isUnit() const {
return squaredLength() == 1.0f;
}
-}
+} // namespace G3D
+
+template <>
+struct HashTrait<G3D::Vector2> {
+ static size_t hashCode(const G3D::Vector2& key) {
+ return key.hashCode();
+ }
+};
+
// Intentionally outside namespace to avoid operator overloading confusion
inline G3D::Vector2 operator*(double s, const G3D::Vector2& v) {
@@ -378,7 +451,4 @@ inline G3D::Vector2 operator*(int s, const G3D::Vector2& v) {
return v * (float)s;
}
-inline unsigned int hashCode(const G3D::Vector2& v);
-
#endif
-
diff --git a/dep/include/g3dlite/G3D/Vector2int16.h b/dep/include/g3dlite/G3D/Vector2int16.h
index c4211b0aaab..ba72266d75a 100644
--- a/dep/include/g3dlite/G3D/Vector2int16.h
+++ b/dep/include/g3dlite/G3D/Vector2int16.h
@@ -1,6 +1,6 @@
/**
@file Vector2int16.h
-
+
@maintainer Morgan McGuire, matrix@brown.edu
@created 2003-08-09
@@ -15,17 +15,15 @@
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
+#include "G3D/HashTrait.h"
namespace G3D {
/**
+ \class Vector2int16
A Vector2 that packs its fields into uint16s.
*/
-#ifdef G3D_WIN32
- // Switch to tight alignment
- #pragma pack(push, 2)
-#endif
-
+G3D_BEGIN_PACKED_CLASS(2)
class Vector2int16 {
private:
// Hidden operators
@@ -41,6 +39,7 @@ public:
Vector2int16() : x(0), y(0) {}
Vector2int16(G3D::int16 _x, G3D::int16 _y) : x(_x), y(_y){}
Vector2int16(const class Vector2& v);
+ Vector2int16(class BinaryInput& bi);
inline G3D::int16& operator[] (int i) {
debugAssert(((unsigned int)i) <= 1);
@@ -52,6 +51,52 @@ public:
return ((G3D::int16*)this)[i];
}
+ inline Vector2int16 operator+(const Vector2int16& other) const {
+ return Vector2int16(x + other.x, y + other.y);
+ }
+
+ inline Vector2int16 operator-(const Vector2int16& other) const {
+ return Vector2int16(x - other.x, y - other.y);
+ }
+
+ inline Vector2int16 operator*(const Vector2int16& other) const {
+ return Vector2int16(x * other.x, y * other.y);
+ }
+
+ inline Vector2int16 operator*(const int s) const {
+ return Vector2int16(x * s, y * s);
+ }
+
+ inline Vector2int16& operator+=(const Vector2int16& other) {
+ x += other.x;
+ y += other.y;
+ return *this;
+ }
+
+ /** Shifts both x and y */
+ inline Vector2int16 operator>>(const int s) const {
+ return Vector2int16(x >> s, y >> s);
+ }
+
+ /** Shifts both x and y */
+ inline Vector2int16 operator<<(const int s) const {
+ return Vector2int16(x << s, y << s);
+ }
+
+ inline Vector2int16& operator-=(const Vector2int16& other) {
+ x -= other.x;
+ y -= other.y;
+ return *this;
+ }
+
+ inline Vector2int16& operator*=(const Vector2int16& other) {
+ x *= other.x;
+ y *= other.y;
+ return *this;
+ }
+
+ Vector2int16 clamp(const Vector2int16& lo, const Vector2int16& hi);
+
inline bool operator== (const Vector2int16& rkVector) const {
return ((int32*)this)[0] == ((int32*)&rkVector)[0];
}
@@ -60,16 +105,23 @@ public:
return ((int32*)this)[0] != ((int32*)&rkVector)[0];
}
-}
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-;
+ Vector2int16 max(const Vector2int16& v) const {
+ return Vector2int16(iMax(x, v.x), iMax(y, v.y));
+ }
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
+ Vector2int16 min(const Vector2int16& v) const {
+ return Vector2int16(iMin(x, v.x), iMin(y, v.y));
+ }
+ void serialize(class BinaryOutput& bo) const;
+ void deserialize(class BinaryInput& bi);
}
-#endif
+G3D_END_PACKED_CLASS(2)
+}
+
+template<> struct HashTrait<G3D::Vector2int16> {
+ static size_t hashCode(const G3D::Vector2int16& key) { return static_cast<size_t>(key.x + ((int)key.y << 16)); }
+};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Vector3.h b/dep/include/g3dlite/G3D/Vector3.h
index 140eb284e12..4825efb9985 100644
--- a/dep/include/g3dlite/G3D/Vector3.h
+++ b/dep/include/g3dlite/G3D/Vector3.h
@@ -1,21 +1,26 @@
/**
@file Vector3.h
-
+
3D vector class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
- @edited 2005-08-23
- Copyright 2000-2006, Morgan McGuire.
+ @edited 2009-11-01
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_VECTOR3_H
-#define G3D_VECTOR3_H
+#ifndef G3D_Vector3_h
+#define G3D_Vector3_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
+#include "G3D/Random.h"
+#include "G3D/Vector2.h"
+#include "G3D/Table.h"
+#include "G3D/HashTrait.h"
+#include "G3D/PositionTrait.h"
#include "G3D/Vector2.h"
#include <iostream>
#include <string>
@@ -23,13 +28,15 @@
namespace G3D {
class Vector2;
-class Vector3;
class Vector4;
+class Vector4int8;
+class Vector3int32;
+class Any;
/**
<B>Swizzles</B>
Vector classes have swizzle operators, e.g. <CODE>v.xy()</CODE>, that
- allow selection of arbitrary sub-fields. These cannot be used as write
+ allow selection of arbitrary sub-fields. These cannot be used as write
masks. Examples
<PRE>
@@ -41,30 +48,19 @@ b = v.xz();
j = b.xx();
</PRE>
+
<B>Warning</B>
Do not subclass-- this implementation makes assumptions about the
memory layout.
*/
class Vector3 {
-private:
- /**
- Reflect this vector about the (not necessarily unit) normal.
- Note that if used for a collision or ray reflection you
- must negate the resulting vector to get a direction pointing
- <I>away</I> from the collision.
-
- <PRE>
- V' N V
+public:
- r ^ -,
- \ | /
- \|/
- </PRE>
+ // coordinates
+ float x, y, z;
- See also Vector3::reflectionDirection
- */
- Vector3 reflectAbout(const Vector3& normal) const;
+private:
// Hidden operators
bool operator<(const Vector3&) const;
@@ -73,34 +69,43 @@ private:
bool operator>=(const Vector3&) const;
public:
- // construction
+ /** Initializes to zero */
Vector3();
+
+ /** \param any Must either Vector3(#, #, #) or Vector3 {x = #, y = #, z = #}*/
+ Vector3(const Any& any);
+
+ /** Converts the Vector3 to an Any. */
+ operator Any() const;
+
+ /** Divides by 127 */
+ Vector3(const Vector4int8&);
+ Vector3(const class Vector3int32& v);
+ explicit Vector3(class BinaryInput& b);
Vector3(float _x, float _y, float _z);
- Vector3(const class Vector2& v, float _z);
- Vector3(float coordinate[3]);
- Vector3(double coordinate[3]);
- Vector3(const Vector3& rkVector);
+ explicit Vector3(const class Vector2& v, float _z);
+ explicit Vector3(float coordinate[3]);
+ explicit Vector3(double coordinate[3]);
Vector3(const class Vector3int16& v);
+ explicit Vector3(class TextInput& t);
+ explicit Vector3(const class Color3& c);
- // coordinates
- float x, y, z;
+ /** Format is three float32's */
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ /** Format is "(%f, %f, %f)" */
+ void serialize(class TextOutput& t) const;
+ void deserialize(class TextInput& t);
// access vector V as V[0] = V.x, V[1] = V.y, V[2] = V.z
//
// WARNING. These member functions rely on
// (1) Vector3 not having virtual functions
// (2) the data packed in a 3*sizeof(float) memory block
- const float& operator[] (int i) const;
+ const float& __fastcall operator[] (int i) const;
float& operator[] (int i);
- inline operator float* () {
- return (float*)this;
- }
-
- operator const float* () const {
- return (float*)this;
- }
-
enum Axis {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, DETECT_AXIS=-1};
/**
@@ -110,10 +115,10 @@ public:
Axis primaryAxis() const;
// assignment and comparison
- Vector3& operator= (const Vector3& rkVector);
+ Vector3& __fastcall operator= (const Vector3& rkVector);
bool operator== (const Vector3& rkVector) const;
bool operator!= (const Vector3& rkVector) const;
- unsigned int hashCode() const;
+ size_t hashCode() const;
bool fuzzyEq(const Vector3& other) const;
bool fuzzyNe(const Vector3& other) const;
@@ -125,29 +130,33 @@ public:
/** Returns true if this vector has length ~= 1 */
bool isUnit() const;
-
+
// arithmetic operations
- Vector3 operator+ (const Vector3& v) const;
- Vector3 operator- (const Vector3& v) const;
- Vector3 operator* (float s) const;
- Vector3 operator/ (float s) const;
- Vector3 operator* (const Vector3& v) const;
- Vector3 operator/ (const Vector3& v) const;
- Vector3 operator- () const;
+ Vector3 __fastcall operator+ (const Vector3& v) const;
+ Vector3 __fastcall operator- (const Vector3& v) const;
+ Vector3 __fastcall operator* (float s) const;
+ inline Vector3 __fastcall operator/ (float s) const {
+ return *this * (1.0f / s);
+ }
+ Vector3 __fastcall operator* (const Vector3& v) const;
+ Vector3 __fastcall operator/ (const Vector3& v) const;
+ Vector3 __fastcall operator- () const;
// arithmetic updates
- Vector3& operator+= (const Vector3& v);
- Vector3& operator-= (const Vector3& v);
- Vector3& operator*= (float s);
- Vector3& operator/= (float s);
- Vector3& operator*= (const Vector3& v);
- Vector3& operator/= (const Vector3& v);
+ Vector3& __fastcall operator+= (const Vector3& v);
+ Vector3& __fastcall operator-= (const Vector3& v);
+ Vector3& __fastcall operator*= (float s);
+ inline Vector3& __fastcall operator/= (float s) {
+ return (*this *= (1.0f / s));
+ }
+ Vector3& __fastcall operator*= (const Vector3& v);
+ Vector3& __fastcall operator/= (const Vector3& v);
- /** @deprecated Use magnitude */
- float G3D_DEPRECATED length() const;
+ /** Same as magnitude */
+ float length() const;
float magnitude() const;
-
+
/**
The result is a nan vector if the length is almost zero.
*/
@@ -160,17 +169,39 @@ public:
Vector3 fastDirection() const;
/**
+ Reflect this vector about the (not necessarily unit) normal.
+ Assumes that both the before and after vectors point away from
+ the base of the normal.
+
+ Note that if used for a collision or ray reflection you
+ must negate the resulting vector to get a direction pointing
+ <I>away</I> from the collision.
+
+ <PRE>
+ V' N V
+
+ r ^ -,
+ \ | /
+ \|/
+ </PRE>
+
+ See also Vector3::reflectionDirection
+ */
+ Vector3 reflectAbout(const Vector3& normal) const;
+
+ /**
See also G3D::Ray::reflect.
- The length is 1.
+ The length is 1.
<PRE>
V' N V
-
+
r ^ /
\ | /
\|'-
</PRE>
*/
Vector3 reflectionDirection(const Vector3& normal) const;
+
/**
Returns Vector3::zero() if the length is nearly zero, otherwise
@@ -192,7 +223,7 @@ public:
where iExit is the index of refraction for the
previous material and iEnter is the index of refraction
for the new material. Like Vector3::reflectionDirection,
- the result has length 1 and is
+ the result has length 1 and is
pointed <I>away</I> from the intersection.
Returns Vector3::zero() in the case of total internal refraction.
@@ -206,7 +237,7 @@ public:
See also G3D::Ray::refract.
<PRE>
N V
-
+
^ /
| /
|'-
@@ -224,30 +255,26 @@ public:
return direction();
}
- /** Returns a normalized vector. May be computed with lower precision than unit */
+ /** Returns a normalized vector. May be computed with lower
+ precision than unit */
inline Vector3 fastUnit() const {
return fastDirection();
}
- /** @deprecated Use squaredMagnitude */
- float G3D_DEPRECATED squaredLength() const;
+ /** Same as squaredMagnitude */
+ float squaredLength() const;
float squaredMagnitude () const;
-
- /** @deprecated Use squaredMagnitude */
- inline float G3D_DEPRECATED norm() const {
- return squaredMagnitude();
- }
-
- float dot(const Vector3& rkVector) const;
-
- float G3D_DEPRECATED unitize(float fTolerance = 1e-06);
+
+ float __fastcall dot(const Vector3& rkVector) const;
+
+ float unitize(float tolerance = 1e-06);
/** Cross product. Note that two cross products in a row
can be computed more cheaply: v1 x (v2 x v3) = (v1 dot v3) v2 - (v1 dot v2) v3.
*/
- Vector3 cross(const Vector3& rkVector) const;
- Vector3 unitCross (const Vector3& rkVector) const;
+ Vector3 __fastcall cross(const Vector3& rkVector) const;
+ Vector3 unitCross(const Vector3& rkVector) const;
/**
Returns a matrix such that v.cross() * w = v.cross(w).
@@ -259,8 +286,18 @@ public:
*/
class Matrix3 cross() const;
- Vector3 min(const Vector3 &v) const;
- Vector3 max(const Vector3 &v) const;
+ Vector3 __fastcall min(const Vector3 &v) const;
+ Vector3 __fastcall max(const Vector3 &v) const;
+
+ /** Smallest element */
+ inline float min() const {
+ return G3D::min(G3D::min(x, y), z);
+ }
+
+ /** Largest element */
+ inline float max() const {
+ return G3D::max(G3D::max(x, y), z);
+ }
std::string toString() const;
@@ -282,31 +319,62 @@ public:
Linear interpolation
*/
inline Vector3 lerp(const Vector3& v, float alpha) const {
- return (*this) + (v - *this) * alpha;
+ return (*this) + (v - *this) * alpha;
}
/** Gram-Schmidt orthonormalization. */
static void orthonormalize (Vector3 akVector[3]);
- /** Random unit vector, uniformly distributed */
- static Vector3 random();
+ /** \brief Random unit vector, uniformly distributed on the sphere.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-random.png
+ */
+ static Vector3 random(Random& r = Random::common());
+
+ /** \brief Random unit vector, distributed according to \f$\max(\cos \theta,0)\f$.
- /** Random unit vector, distributed
- so that the probability of V is proportional
- to max(V dot Normal, 0).
+ That is, so that the probability of \f$\vec{V}\f$ is proportional
+ to \f$\max(\vec{v} \cdot \vec{n}, 0)\f$. Useful in photon mapping for
+ Lambertian scattering.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-coshemirandom.png
+
+ \param n Unit vector at the center of the distribution.
@cite Henrik Wann Jensen, Realistic Image Synthesis using Photon Mapping eqn 2.24
*/
- static Vector3 cosRandom(const Vector3& normal);
+ static Vector3 cosHemiRandom(const Vector3& n, Random& r = Random::common());
+
+ /** \brief Random unit vector, distributed according to \f$\max(\cos^k \theta,0)\f$.
+
+ That is, so that the probability of \f$\vec{V}\f$ is
+ proportional to \f$\max((\vec{v} \cdot \vec{n})^k, 0)\f$.
+ Useful in photon mapping for glossy scattering.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-cospowhemirandom.png
+
+ \param n Unit vector at the center of the distribution.
+
+ @cite Ashikhmin and Shirley, An anisotropic Phong BRDF model, Journal of Graphics Tools, 2002
+ */
+ static Vector3 cosPowHemiRandom(const Vector3& n, const float k, Random& r = Random::common());
/**
- Random vector distributed over the hemisphere about normal.
+ \brief Random vector distributed over the hemisphere about normal.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-hemirandom.png
*/
- static Vector3 hemiRandom(const Vector3& normal);
+ static Vector3 hemiRandom(const Vector3& normal, Random& r = Random::common());
- // Input W must be initialize to a nonzero vector, output is {U,V,W}
- // an orthonormal basis. A hint is provided about whether or not W
- // is already unit length.
+ /** Input W must be initialize to a nonzero vector, output is {U,V,W}
+ an orthonormal basis. A hint is provided about whether or not W
+ is already unit length.
+ @deprecated Use getTangents
+ */
static void generateOrthonormalBasis (Vector3& rkU, Vector3& rkV,
Vector3& rkW, bool bUnitLengthW = true);
@@ -319,33 +387,37 @@ public:
}
// Special values.
- inline static const Vector3& zero() { static Vector3 v(0, 0, 0); return v; }
- inline static const Vector3& one() { static Vector3 v(1, 1, 1); return v; }
- inline static const Vector3& unitX() { static Vector3 v(1, 0, 0); return v; }
- inline static const Vector3& unitY() { static Vector3 v(0, 1, 0); return v; }
- inline static const Vector3& unitZ() { static Vector3 v(0, 0, 1); return v; }
- inline static const Vector3& inf() { static Vector3 v((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); return v; }
- inline static const Vector3& nan() { static Vector3 v((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); return v; }
+ static const Vector3& zero();
+ static const Vector3& one();
+ static const Vector3& unitX();
+ static const Vector3& unitY();
+ static const Vector3& unitZ();
+ static const Vector3& inf();
+ static const Vector3& nan();
+
/** Smallest (most negative) representable vector */
- inline static const Vector3& minFinite(){ static Vector3 v(-FLT_MAX, -FLT_MAX, -FLT_MAX); return v; }
+ static const Vector3& minFinite();
+
/** Largest representable vector */
- inline static const Vector3& maxFinite(){ static Vector3 v(FLT_MAX, FLT_MAX, FLT_MAX); return v; }
-
- // Deprecated. See Matrix3::identity() for details.
- /** @deprecated Use Vector3::zero() */
- static const Vector3 ZERO;
- /** @deprecated Use Vector3::zero() */
- static const Vector3 ZERO3;
- /** @deprecated Use Vector3::unitX() */
- static const Vector3 UNIT_X;
- /** @deprecated Use Vector3::unitY() */
- static const Vector3 UNIT_Y;
- /** @deprecated Use Vector3::unitZ() */
- static const Vector3 UNIT_Z;
- /** @deprecated Use Vector3::inf() */
- static const Vector3 INF3;
- /** @deprecated Use Vector3::nan() */
- static const Vector3 NAN3;
+ static const Vector3& maxFinite();
+
+
+ /** Creates two orthonormal tangent vectors X and Y such that
+ if Z = this, X x Y = Z.*/
+ inline void getTangents(Vector3& X, Vector3& Y) const {
+ debugAssertM(G3D::fuzzyEq(length(), 1.0f),
+ "makeAxes requires Z to have unit length");
+
+ // Choose another vector not perpendicular
+ X = (abs(x) < 0.9f) ? Vector3::unitX() : Vector3::unitY();
+
+ // Remove the part that is parallel to Z
+ X -= *this * this->dot(X);
+ X /= X.length();
+
+ Y = this->cross(X);
+ }
+
// 2-char swizzles
@@ -473,8 +545,8 @@ public:
Vector4 yzzz() const;
Vector4 zzzz() const;
- /** A value that can be passed to ignore a parameter. Never look at the result of dummy. */
- static Vector3 dummy;
+ /** Can be passed to ignore a vector3 parameter */
+ static Vector3& ignore();
};
inline G3D::Vector3 operator*(float s, const G3D::Vector3& v) {
@@ -491,11 +563,236 @@ inline G3D::Vector3 operator*(int s, const G3D::Vector3& v) {
std::ostream& operator<<(std::ostream& os, const Vector3&);
+
+void serialize(const Vector3::Axis& a, class BinaryOutput& bo);
+void deserialize(Vector3::Axis& a, class BinaryInput& bo);
+
+
+//----------------------------------------------------------------------------
+inline Vector3::Vector3() : x(0.0f), y(0.0f), z(0.0f) {
}
-unsigned int hashCode(const G3D::Vector3& v);
+//----------------------------------------------------------------------------
-#include "Vector3.inl"
+inline Vector3::Vector3 (float fX, float fY, float fZ) : x(fX), y(fY), z(fZ) {
+}
-#endif
+//----------------------------------------------------------------------------
+inline Vector3::Vector3 (float V[3]) : x(V[0]), y(V[1]), z(V[2]){
+}
+
+//----------------------------------------------------------------------------
+inline Vector3::Vector3 (double V[3]) : x((float)V[0]), y((float)V[1]), z((float)V[2]){
+}
+
+//----------------------------------------------------------------------------
+inline const float& Vector3::operator[] (int i) const {
+ return ((float*)this)[i];
+}
+
+inline float& Vector3::operator[] (int i) {
+ return ((float*)this)[i];
+}
+
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator= (const Vector3& rkVector) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::fuzzyEq(const Vector3& other) const {
+ return G3D::fuzzyEq((*this - other).squaredMagnitude(), 0);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::fuzzyNe(const Vector3& other) const {
+ return G3D::fuzzyNe((*this - other).squaredMagnitude(), 0);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::isFinite() const {
+ return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z);
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector3::operator== (const Vector3& rkVector) const {
+ return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector3::operator!= (const Vector3& rkVector) const {
+ return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator+ (const Vector3& rkVector) const {
+ return Vector3(x + rkVector.x, y + rkVector.y, z + rkVector.z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator- (const Vector3& rkVector) const {
+ return Vector3(x - rkVector.x, y - rkVector.y, z - rkVector.z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator* (const Vector3& rkVector) const {
+ return Vector3(x * rkVector.x, y * rkVector.y, z * rkVector.z);
+}
+
+inline Vector3 Vector3::operator*(float f) const {
+ return Vector3(x * f, y * f, z * f);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator/ (const Vector3& rkVector) const {
+ return Vector3(x / rkVector.x, y / rkVector.y, z / rkVector.z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator- () const {
+ return Vector3(-x, -y, -z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator+= (const Vector3& rkVector) {
+ x += rkVector.x;
+ y += rkVector.y;
+ z += rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator-= (const Vector3& rkVector) {
+ x -= rkVector.x;
+ y -= rkVector.y;
+ z -= rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator*= (float fScalar) {
+ x *= fScalar;
+ y *= fScalar;
+ z *= fScalar;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator*= (const Vector3& rkVector) {
+ x *= rkVector.x;
+ y *= rkVector.y;
+ z *= rkVector.z;
+ return *this;
+}
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator/= (const Vector3& rkVector) {
+ x /= rkVector.x;
+ y /= rkVector.y;
+ z /= rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::squaredMagnitude () const {
+ return x*x + y*y + z*z;
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::squaredLength () const {
+ return squaredMagnitude();
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::magnitude() const {
+ return ::sqrtf(x*x + y*y + z*z);
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::length() const {
+ return magnitude();
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::direction () const {
+ const float lenSquared = squaredMagnitude();
+ const float invSqrt = 1.0f / sqrtf(lenSquared);
+ return Vector3(x * invSqrt, y * invSqrt, z * invSqrt);
+}
+
+//----------------------------------------------------------------------------
+
+inline Vector3 Vector3::fastDirection () const {
+ float lenSquared = x * x + y * y + z * z;
+ float invSqrt = rsq(lenSquared);
+ return Vector3(x * invSqrt, y * invSqrt, z * invSqrt);
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::dot (const Vector3& rkVector) const {
+ return x*rkVector.x + y*rkVector.y + z*rkVector.z;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::cross (const Vector3& rkVector) const {
+ return Vector3(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z,
+ x*rkVector.y - y*rkVector.x);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::unitCross (const Vector3& rkVector) const {
+ Vector3 kCross(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z,
+ x*rkVector.y - y*rkVector.x);
+ kCross.unitize();
+ return kCross;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::min(const Vector3 &v) const {
+ return Vector3(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z));
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::max(const Vector3 &v) const {
+ return Vector3(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z));
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector3::isZero() const {
+ return G3D::fuzzyEq(squaredMagnitude(), 0.0f);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::isUnit() const {
+ return G3D::fuzzyEq(squaredMagnitude(), 1.0f);
+}
+
+} // namespace G3D
+
+
+template <>
+struct HashTrait<G3D::Vector3> {
+ static size_t hashCode(const G3D::Vector3& key) {
+ return key.hashCode();
+ }
+};
+
+
+template<> struct PositionTrait<class G3D::Vector2> {
+ static void getPosition(const G3D::Vector2& v, G3D::Vector3& p) { p = G3D::Vector3(v, 0); }
+};
+
+template<> struct PositionTrait<class G3D::Vector3> {
+ static void getPosition(const G3D::Vector3& v, G3D::Vector3& p) { p = v; }
+};
+
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Vector3int16.h b/dep/include/g3dlite/G3D/Vector3int16.h
index e0631125960..3197ea49d1a 100644
--- a/dep/include/g3dlite/G3D/Vector3int16.h
+++ b/dep/include/g3dlite/G3D/Vector3int16.h
@@ -1,6 +1,6 @@
/**
@file Vector3int16.h
-
+
@maintainer Morgan McGuire, matrix@brown.edu
@created 2003-04-07
@@ -14,17 +14,22 @@
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
+#include "G3D/HashTrait.h"
+
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+#pragma warning (disable : 4127)
+#endif
+
namespace G3D {
/**
+ \class Vector3int16
A Vector3 that packs its fields into uint16s.
*/
-#ifdef G3D_WIN32
- // Switch to tight alignment
- #pragma pack(push, 2)
-#endif
-
+G3D_BEGIN_PACKED_CLASS(2)
class Vector3int16 {
private:
// Hidden operators
@@ -41,16 +46,82 @@ public:
Vector3int16() : x(0), y(0), z(0) {}
Vector3int16(G3D::int16 _x, G3D::int16 _y, G3D::int16 _z) : x(_x), y(_y), z(_z) {}
Vector3int16(const class Vector3& v);
-}
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-;
+ Vector3int16(class BinaryInput& bi);
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
+ void serialize(class BinaryOutput& bo) const;
+ void deserialize(class BinaryInput& bi);
+
+ inline G3D::int16& operator[] (int i) {
+ debugAssert(i <= 2);
+ return ((G3D::int16*)this)[i];
+ }
+
+ inline const G3D::int16& operator[] (int i) const {
+ debugAssert(i <= 2);
+ return ((G3D::int16*)this)[i];
+ }
+
+ inline Vector3int16 operator+(const Vector3int16& other) const {
+ return Vector3int16(x + other.x, y + other.y, z + other.z);
+ }
+
+ inline Vector3int16 operator-(const Vector3int16& other) const {
+ return Vector3int16(x - other.x, y - other.y, z - other.z);
+ }
+
+ inline Vector3int16 operator*(const Vector3int16& other) const {
+ return Vector3int16(x * other.x, y * other.y, z * other.z);
+ }
+ inline Vector3int16 operator*(const int s) const {
+ return Vector3int16(int16(x * s), int16(y * s), int16(z * s));
+ }
+
+ inline Vector3int16& operator+=(const Vector3int16& other) {
+ x += other.x;
+ y += other.y;
+ z += other.y;
+ return *this;
+ }
+
+ inline Vector3int16& operator-=(const Vector3int16& other) {
+ x -= other.x;
+ y -= other.y;
+ z -= other.z;
+ return *this;
+ }
+
+ inline Vector3int16& operator*=(const Vector3int16& other) {
+ x *= other.x;
+ y *= other.y;
+ z *= other.z;
+ return *this;
+ }
+
+ inline bool operator== (const Vector3int16& rkVector) const {
+ return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
+ }
+
+ inline bool operator!= (const Vector3int16& rkVector) const {
+ return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
+ }
+
+ Vector3int16 max(const Vector3int16& v) const {
+ return Vector3int16(std::max(x, v.x), std::max(y, v.y), std::max(z, v.z));
+ }
+
+ Vector3int16 min(const Vector3int16& v) const {
+ return Vector3int16(std::min(x, v.x), std::min(y, v.y), std::min(z, v.z));
+ }
+
+ std::string toString() const;
}
-#endif
+G3D_END_PACKED_CLASS(2)
+
+}
+
+template <> struct HashTrait<G3D::Vector3int16> {
+ static size_t hashCode(const G3D::Vector3int16& key) { return static_cast<size_t>(key.x + ((int)key.y << 5) + ((int)key.z << 10)); }
+};
+#endif
diff --git a/dep/include/g3dlite/G3D/Vector3int32.h b/dep/include/g3dlite/G3D/Vector3int32.h
new file mode 100644
index 00000000000..2f256ea0300
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Vector3int32.h
@@ -0,0 +1,128 @@
+/**
+ @file Vector3int32.h
+
+ @maintainer Morgan McGuire, matrix@brown.edu
+
+ @created 2008-07-01
+ @edited 2008-07-01
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef VECTOR3INT32_H
+#define VECTOR3INT32_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/HashTrait.h"
+
+namespace G3D {
+
+/**
+ \ Vector3int32
+ A Vector3 that packs its fields into uint32s.
+ */
+G3D_BEGIN_PACKED_CLASS(4)
+class Vector3int32 {
+private:
+ // Hidden operators
+ bool operator<(const Vector3int32&) const;
+ bool operator>(const Vector3int32&) const;
+ bool operator<=(const Vector3int32&) const;
+ bool operator>=(const Vector3int32&) const;
+
+public:
+ G3D::int32 x;
+ G3D::int32 y;
+ G3D::int32 z;
+
+ Vector3int32() : x(0), y(0), z(0) {}
+ Vector3int32(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
+ Vector3int32(const class Vector3int16& v);
+ Vector3int32(const class Vector3& v);
+ Vector3int32(class BinaryInput& bi);
+
+ void serialize(class BinaryOutput& bo) const;
+ void deserialize(class BinaryInput& bi);
+
+ inline G3D::int32& operator[] (int i) {
+ debugAssert(i <= 2);
+ return ((G3D::int32*)this)[i];
+ }
+
+ inline const G3D::int32& operator[] (int i) const {
+ debugAssert(i <= 2);
+ return ((G3D::int32*)this)[i];
+ }
+
+ inline Vector3int32 operator+(const Vector3int32& other) const {
+ return Vector3int32(x + other.x, y + other.y, z + other.z);
+ }
+
+ inline Vector3int32 operator-(const Vector3int32& other) const {
+ return Vector3int32(x - other.x, y - other.y, z - other.z);
+ }
+
+ inline Vector3int32 operator*(const Vector3int32& other) const {
+ return Vector3int32(x * other.x, y * other.y, z * other.z);
+ }
+
+ inline Vector3int32 operator*(const int s) const {
+ return Vector3int32(x * s, y * s, z * s);
+ }
+
+ inline Vector3int32& operator+=(const Vector3int32& other) {
+ x += other.x;
+ y += other.y;
+ z += other.y;
+ return *this;
+ }
+
+ inline Vector3int32& operator-=(const Vector3int32& other) {
+ x -= other.x;
+ y -= other.y;
+ z -= other.z;
+ return *this;
+ }
+
+ inline Vector3int32& operator*=(const Vector3int32& other) {
+ x *= other.x;
+ y *= other.y;
+ z *= other.z;
+ return *this;
+ }
+
+ inline bool operator== (const Vector3int32& rkVector) const {
+ return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
+ }
+
+ inline bool operator!= (const Vector3int32& rkVector) const {
+ return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
+ }
+
+ Vector3int32 max(const Vector3int32& v) const {
+ return Vector3int32(iMax(x, v.x), iMax(y, v.y), iMax(z, v.z));
+ }
+
+ Vector3int32 min(const Vector3int32& v) const {
+ return Vector3int32(iMin(x, v.x), iMin(y, v.y), iMin(z, v.z));
+ }
+
+ std::string toString() const;
+}
+G3D_END_PACKED_CLASS(4)
+
+}
+
+template <> struct HashTrait<G3D::Vector3int32> {
+ static size_t hashCode(const G3D::Vector3int32& key) {
+ // Mask for the top bit of a uint32
+ const G3D::uint32 top = (1UL << 31);
+ // Mask for the bottom 10 bits of a uint32
+ const G3D::uint32 bot = 0x000003FF;
+ return static_cast<size_t>(((key.x & top) | ((key.y & top) >> 1) | ((key.z & top) >> 2)) |
+ (((key.x & bot) << 19) ^ ((key.y & bot) << 10) ^ (key.z & bot)));
+ }
+};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Vector4.h b/dep/include/g3dlite/G3D/Vector4.h
index 1bf243e5ed7..5e511451f86 100644
--- a/dep/include/g3dlite/G3D/Vector4.h
+++ b/dep/include/g3dlite/G3D/Vector4.h
@@ -1,31 +1,36 @@
/**
@file Vector4.h
-
+
Homogeneous vector class.
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2002-07-09
- @edited 2005-03-28
+ @edited 2008-11-01
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_VECTOR4_H
-#define G3D_VECTOR4_H
+#ifndef G3D_Vector4_h
+#define G3D_Vector4_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
#include "G3D/Vector3.h"
#include "G3D/Vector2.h"
+#include "G3D/Table.h"
+#include "G3D/HashTrait.h"
+#include "G3D/PositionTrait.h"
#include <string>
namespace G3D {
-class Vector2;
+class Vector2;
class Vector3;
class Vector4;
+class Vector4int8;
+class Any;
/**
Do not subclass-- this implementation makes assumptions about the
@@ -40,6 +45,13 @@ private:
bool operator>=(const Vector4&) const;
public:
+
+ /** \param any Must either Vector4(#, #, #, #) or Vector3 {x = #, y = #, z = #, w =#}*/
+ Vector4(const Any& any);
+
+ /** Converts the Vector4 to an Any. */
+ operator Any() const;
+
// construction
Vector4();
Vector4(float fX, float fY, float fZ, float fW);
@@ -50,6 +62,13 @@ public:
Vector4(const Vector2& v1, const Vector2& v2);
Vector4(const Vector2& v1, float fz, float fw);
+ /** Divides by 127 when converting */
+ Vector4(const Vector4int8&);
+
+ Vector4(class BinaryInput& b);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
// coordinates
float x, y, z, w;
@@ -60,14 +79,14 @@ public:
// (2) the data packed in a 4*sizeof(float) memory block
float& operator[] (int i);
const float& operator[] (int i) const;
- operator float* ();
- operator const float* () const;
// assignment and comparison
Vector4& operator= (const Vector4& rkVector);
bool operator== (const Vector4& rkVector) const;
bool operator!= (const Vector4& rkVector) const;
+ static const Vector4& zero();
+
inline void set(float _x, float _y, float _z, float _w) {
x = _x;
y = _y;
@@ -89,12 +108,12 @@ public:
w = _w;
}
- unsigned int hashCode() const;
+ size_t hashCode() const;
bool fuzzyEq(const Vector4& other) const;
bool fuzzyNe(const Vector4& other) const;
- inline static const Vector4& inf() { static Vector4 v((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); return v; }
- inline static const Vector4& nan() { static Vector4 v((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); return v; }
+ static const Vector4& inf();
+ static const Vector4& nan();
/** sqrt(this->dot(*this)) */
float length() const;
@@ -116,7 +135,7 @@ public:
// arithmetic operations
Vector4 operator+ (const Vector4& rkVector) const;
Vector4 operator- (const Vector4& rkVector) const;
-
+
inline Vector4 operator*(const Vector4& rkVector) const {
return Vector4(x * rkVector.x, y * rkVector.y, z * rkVector.z, w * rkVector.w);
}
@@ -125,6 +144,8 @@ public:
return Vector4(x / rkVector.x, y / rkVector.y, z / rkVector.z, w / rkVector.w);
}
+ Vector4 operator*(const class Matrix4& M) const;
+
Vector4 operator* (float fScalar) const;
Vector4 operator/ (float fScalar) const;
Vector4 operator- () const;
@@ -511,15 +532,185 @@ public:
};
+
+//----------------------------------------------------------------------------
+inline Vector4::Vector4() {
+ x = y = z = w = 0;
}
-inline G3D::Vector4 operator* (float s, const G3D::Vector4& v) {
- return v * s;
+//----------------------------------------------------------------------------
+
+inline Vector4::Vector4 (float fX, float fY, float fZ, float fW) {
+ x = fX;
+ y = fY;
+ z = fZ;
+ w = fW;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4::Vector4 (float afCoordinate[4]) {
+ x = afCoordinate[0];
+ y = afCoordinate[1];
+ z = afCoordinate[2];
+ w = afCoordinate[3];
}
-unsigned int hashCode(const G3D::Vector4& v);
+//----------------------------------------------------------------------------
+inline Vector4::Vector4(const Vector4& rkVector) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ w = rkVector.w;
+}
+//----------------------------------------------------------------------------
+inline Vector4::Vector4(const Vector3& rkVector, float fW) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ w = fW;
+}
-#include "Vector4.inl"
+//----------------------------------------------------------------------------
+inline float& Vector4::operator[] (int i) {
+ return ((float*)this)[i];
+}
-#endif
+//----------------------------------------------------------------------------
+inline const float& Vector4::operator[] (int i) const {
+ return ((float*)this)[i];
+}
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator= (const Vector4& rkVector) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ w = rkVector.w;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector4::operator== (const Vector4& rkVector) const {
+ return ( (x == rkVector.x) && (y == rkVector.y) && (z == rkVector.z) && (w == rkVector.w));
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector4::operator!= (const Vector4& rkVector) const {
+ return ( x != rkVector.x || y != rkVector.y || z != rkVector.z || w != rkVector.w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator+ (const Vector4& rkVector) const {
+ return Vector4(x + rkVector.x, y + rkVector.y, z + rkVector.z, w + rkVector.w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator- (const Vector4& rkVector) const {
+ return Vector4(x - rkVector.x, y - rkVector.y, z - rkVector.z, w - rkVector.w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator* (float fScalar) const {
+ return Vector4(fScalar*x, fScalar*y, fScalar*z, fScalar*w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator- () const {
+ return Vector4( -x, -y, -z, -w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator+= (const Vector4& rkVector) {
+ x += rkVector.x;
+ y += rkVector.y;
+ z += rkVector.z;
+ w += rkVector.w;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator-= (const Vector4& rkVector) {
+ x -= rkVector.x;
+ y -= rkVector.y;
+ z -= rkVector.z;
+ w -= rkVector.w;
+ return *this;
+}
+//----------------------------------------------------------------------------
+
+inline Vector4 Vector4::lerp(const Vector4& v, float alpha) const {
+ return (*this) + (v - *this) * alpha;
+}
+
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator*= (float fScalar) {
+ x *= fScalar;
+ y *= fScalar;
+ z *= fScalar;
+ w *= fScalar;
+ return *this;
+}
+
+
+//----------------------------------------------------------------------------
+inline float Vector4::dot(const Vector4& rkVector) const {
+ return x*rkVector.x + y*rkVector.y + z*rkVector.z + w*rkVector.w;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::min(const Vector4 &v) const {
+ return Vector4(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z), G3D::min(v.w, w));
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::max(const Vector4 &v) const {
+ return Vector4(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z), G3D::max(v.w, w));
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector4::isZero() const {
+ return (x == 0.0f) && (y == 0.0f) && (z == 0.0f) && (w == 0.0f);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector4::isFinite() const {
+ return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z) && G3D::isFinite(w);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector4::isUnit() const {
+ return squaredLength() == 1.0;
+}
+
+//----------------------------------------------------------------------------
+
+inline float Vector4::length() const {
+ return sqrtf(squaredLength());
+}
+
+//----------------------------------------------------------------------------
+
+inline float Vector4::squaredLength() const {
+ return x * x + y * y + z * z + w * w;
+}
+
+}
+
+template <> struct HashTrait<G3D::Vector4> {
+ static size_t hashCode(const G3D::Vector4& key) { return key.hashCode(); }
+};
+
+
+template<> struct PositionTrait<class G3D::Vector4> {
+ static void getPosition(const G3D::Vector4& v, G3D::Vector3& p) { p = v.xyz(); }
+};
+
+inline G3D::Vector4 operator* (float s, const G3D::Vector4& v) {
+ return v * s;
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/Vector4int8.h b/dep/include/g3dlite/G3D/Vector4int8.h
new file mode 100644
index 00000000000..544b693e8b3
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Vector4int8.h
@@ -0,0 +1,113 @@
+/**
+ @file Vector4int8.h
+
+ Homogeneous vector class.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-02-09
+ @edited 2007-02-09
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_VECTOR4INT8_H
+#define G3D_VECTOR4INT8_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+class Vector3;
+class Vector4;
+
+/**
+ Homogeneous vector stored efficiently in four signed int8s.
+
+ */
+class Vector4int8 {
+private:
+ // Hidden operators
+ bool operator<(const Vector4int8&) const;
+ bool operator>(const Vector4int8&) const;
+ bool operator<=(const Vector4int8&) const;
+ bool operator>=(const Vector4int8&) const;
+
+
+ /** For fast operations, treat this packed data structure as
+ an int32 */
+ inline uint32& asInt32() {
+ return *reinterpret_cast<uint32*>(this);
+ }
+
+ inline const uint32& asInt32() const {
+ return *reinterpret_cast<const uint32*>(this);
+ }
+
+public:
+ // construction
+ inline Vector4int8() : x(0), y(0), z(0), w(0) {}
+
+ /** Multiplies the source by 127 and clamps to (-128, 127) when converting */
+ Vector4int8(const Vector4& source);
+
+ /** Multiplies the source by 127 and clamps to (-128, 127) when converting */
+ Vector4int8(const Vector3& source, int8 w);
+
+ inline Vector4int8(int8 x, int8 y, int8 z, int8 w) : x(x), y(y), z(z), w(w) {}
+
+ Vector4int8(class BinaryInput& b);
+ void serialize(class BinaryOutput& b) const;
+ void deserialize(class BinaryInput& b);
+
+ // coordinates
+ int8 x, y, z, w;
+
+ inline operator int8* () {
+ return reinterpret_cast<int8*>(this);
+ }
+
+ inline operator const int8* () const {
+ return reinterpret_cast<const int8*>(this);
+ }
+
+ // access vector V as V[0] = V.x, V[1] = V.y, V[2] = V.z, etc.
+ //
+ // WARNING. These member functions rely on
+ // (1) Vector4int8 not having virtual functions
+ // (2) the data packed in a 4*sizeof(int8) memory block
+ inline int8& operator[] (int i) {
+ debugAssert(i >= 0 && i <= 4);
+ return ((int8*)this)[i];
+ }
+
+ const int8& operator[] (int i) const {
+ debugAssert(i >= 0 && i <= 4);
+ return ((const int8*)this)[i];
+ }
+
+ // assignment and comparison
+ Vector4int8& operator= (const Vector4int8& other) {
+ asInt32() = other.asInt32();
+ return *this;
+ }
+
+ inline bool operator== (const Vector4int8& other) const {
+ return asInt32() == other.asInt32();
+ }
+
+ inline bool operator!= (const Vector4int8& other) const {
+ return ! (*this == other);
+ }
+
+ inline unsigned int hashCode() const {
+ return asInt32();
+ }
+};
+
+} // namespace G3D
+
+
+#endif
diff --git a/dep/include/g3dlite/G3D/WeakCache.h b/dep/include/g3dlite/G3D/WeakCache.h
new file mode 100644
index 00000000000..f9fdc4bbd5b
--- /dev/null
+++ b/dep/include/g3dlite/G3D/WeakCache.h
@@ -0,0 +1,122 @@
+/**
+ @file WeakCache.h
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2007-05-16
+ @edited 2007-05-16
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_WEAKCACHE_H
+#define G3D_WEAKCACHE_H
+
+#include "G3D/ReferenceCount.h"
+#include "G3D/Table.h"
+
+namespace G3D {
+
+/**
+ A cache that does not prevent its members from being garbage collected.
+ Useful to avoid loading or computing an expression twice. Useful
+ for memoization and dynamic programming.
+
+ Maintains a table of weak pointers. Weak pointers do not prevent
+ an object from being garbage collected. If the object is garbage
+ collected, the cache removes its reference.
+
+ There are no "contains" or "iterate" methods because elements can be
+ flushed from the cache at any time if they are garbage collected.
+
+ Example:
+ <pre>
+ WeakCache<std::string, TextureRef> textureCache;
+
+ TextureRef loadTexture(std::string s) {
+ TextureRef t = textureCache[s];
+
+ if (t.isNull()) {
+ t = Texture::fromFile(s);
+ textureCache.set(s, t);
+ }
+
+ return t;
+ }
+
+
+ </pre>
+ */
+template<class Key, class ValueRef>
+class WeakCache {
+ typedef WeakReferenceCountedPointer<typename ValueRef::element_type> ValueWeakRef;
+
+private:
+
+ Table<Key, ValueWeakRef> table;
+
+public:
+ /**
+ Returns NULL if the object is not in the cache
+ */
+ ValueRef operator[](const Key& k) {
+ if (table.containsKey(k)) {
+ ValueWeakRef w = table[k];
+ ValueRef s = w.createStrongPtr();
+ if (s.isNull()) {
+ // This object has been collected; clean out its key
+ table.remove(k);
+ }
+ return s;
+ } else {
+ return NULL;
+ }
+ }
+
+ void set(const Key& k, ValueRef v) {
+ table.set(k, v);
+ }
+
+ /** Removes k from the cache or does nothing if it is not currently in the cache.*/
+ void remove(const Key& k) {
+ if (table.containsKey(k)) {
+ table.remove(k);
+ }
+ }
+};
+
+#if 0 // To turn off all WeakCaching
+template<class Key, class ValueRef>
+class WeakCache {
+private:
+
+ Table<Key, ValueRef> table;
+
+public:
+ /**
+ Returns NULL if the object is not in the cache
+ */
+ ValueRef operator[](const Key& k) {
+ if (table.containsKey(k)) {
+ return table[k];
+ } else {
+ return NULL;
+ }
+ }
+
+ void set(const Key& k, ValueRef v) {
+ table.set(k, v);
+ }
+
+ /** Removes k from the cache or does nothing if it is not currently in the cache.*/
+ void remove(const Key& k) {
+ if (table.containsKey(k)) {
+ table.remove(k);
+ }
+ }
+};
+#endif
+
+}
+#endif
+
diff --git a/dep/include/g3dlite/G3D/Welder.h b/dep/include/g3dlite/G3D/Welder.h
new file mode 100644
index 00000000000..2c2554da7b6
--- /dev/null
+++ b/dep/include/g3dlite/G3D/Welder.h
@@ -0,0 +1,82 @@
+#ifndef G3D_Welder_h
+#define G3D_Welder_h
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector2.h"
+
+namespace G3D {
+
+class Any;
+
+class Welder {
+private:
+
+ Welder() {}
+
+public:
+
+ class Settings {
+ public:
+ /** Surfaces with normals that are within this angle of each
+ other are considered to be curved. Default value is toRadians(70.0f).*/
+ float normalSmoothingAngle;
+ float vertexWeldRadius;
+ float textureWeldRadius;
+ float normalWeldRadius;
+
+ inline Settings(float normalSmoothAngle = toRadians(70.0f)) :
+ normalSmoothingAngle(normalSmoothAngle),
+ vertexWeldRadius(0.0001f),
+ textureWeldRadius(0.0001f),
+ normalWeldRadius(0.01f) {}
+
+
+ Settings(const Any& any);
+ operator Any() const;
+ };
+
+/**
+ Mutates geometry, texCoord, and indexArray so that the output has collocated vertices collapsed (welded).
+
+ @param vertices Input and output
+ @param textureCoords Input and output
+ @param normals Output only
+ @param indices Input and output. This is an array of trilist indices.
+ @param oldToNewIndex Output argument
+ @param normalSmoothingAngle Varies from 0 (flat shading) to toRadians(180) for extremely smooth shading. Default is toRadians(70)
+ */
+ static void weld(
+ Array<Vector3>& vertices,
+ Array<Vector2>& textureCoords,
+ Array<Vector3>& normals,
+ Array<Array<int>*>& indices,
+ const Settings& settings);
+
+ /**
+ Mutates geometry, texCoord, and indexArray so that the output has collocated vertices collapsed (welded).
+
+ @param vertices Input and output
+ @param textureCoords Input and output
+ @param normals Output only
+ @param indices Input and output. This is an array of trilist indices.
+ @param oldToNewIndex Output argument
+ @param normalSmoothingAngle Varies from 0 (flat shading) to toRadians(180) for extremely smooth shading. Default is toRadians(70)
+ */
+ inline static void weld(
+ Array<Vector3>& vertices,
+ Array<Vector2>& textureCoords,
+ Array<Vector3>& normals,
+ Array<int>& indices,
+ const Settings& settings) {
+
+ Array<Array<int>*> meta;
+ meta.append(&indices);
+ weld(vertices, textureCoords, normals, meta, settings);
+ }
+};
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/WrapMode.h b/dep/include/g3dlite/G3D/WrapMode.h
new file mode 100644
index 00000000000..8ef38a77c23
--- /dev/null
+++ b/dep/include/g3dlite/G3D/WrapMode.h
@@ -0,0 +1,93 @@
+/**
+ @file WrapMode.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-04-17
+ @edited 2007-04-17
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_WrapMode_h
+#define G3D_WrapMode_h
+
+#include "G3D/platform.h"
+#include "G3D/enumclass.h"
+
+#ifdef IGNORE
+# undef IGNORE
+#endif
+#ifdef ZERO
+# undef ZERO
+#endif
+#ifdef ERROR
+# undef ERROR
+#endif
+
+namespace G3D {
+
+/**
+ Describes the behavior of G3D::Texture, G3D::Map2D, G3D::Image3,
+ etc. when accessing an out-of-bounds pixel. Not all classes support
+ all modes.
+
+ Refer to these as scoped enums, e.g., <code>WrapMode m = WrapMode::CLAMP;</code>.
+
+ WrapMode::IGNORE silently discards attempts to write to out
+ of bounds locations and returns an undefined value for reading
+ from out of bounds locations.
+
+ WrapMode::ERROR generates an error when the
+ pixel indices are out of bounds
+
+ WrapMode::CLAMP makes out of bounds pixels equal to the last in-range pixel along that dimension.
+
+ WrapMode::TILE computes out of bounds pixels modulo the dimension
+
+ WrapMode::ZERO treats out of bounds values as the zero value, which varies in definition
+ according to the class used. For example, with a G3D::Texture, ZERO = Color4(0,0,0,0).
+
+ Uses the "Intelligent Enum" design pattern
+ http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4001/
+ */
+class WrapMode {
+public:
+ /** Don't use this enum; use WrapMode instances instead. */
+ enum Value {
+ CLAMP,
+ TILE,
+ ZERO,
+ IGNORE,
+ ERROR
+ };
+
+private:
+
+ Value value;
+
+public:
+
+ G3D_DECLARE_ENUM_CLASS_METHODS(WrapMode);
+
+ inline const char* toString() const {
+ static const char* s[] = {"CLAMP", "TILE", "ZERO", "IGNORE", "ERROR"};
+ return s[value];
+ }
+
+ inline explicit WrapMode(const std::string& x) : value(ERROR) {
+ static const char* s[] = {"CLAMP", "TILE", "ZERO", "IGNORE", "ERROR"};
+ for (int i = 0; i < 5; ++i) {
+ if (x == s[i]) {
+ value = (Value)i;
+ }
+ }
+ }
+};
+
+} // namespace G3D
+
+G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::WrapMode);
+
+#endif
diff --git a/dep/include/g3dlite/G3D/constants.h b/dep/include/g3dlite/G3D/constants.h
new file mode 100644
index 00000000000..dd5cb3649e5
--- /dev/null
+++ b/dep/include/g3dlite/G3D/constants.h
@@ -0,0 +1,129 @@
+/**
+ @file G3D/constants.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2009-05-20
+ @edited 2009-05-20
+*/
+#ifndef G3D_constants_h
+#define G3D_constants_h
+
+#include "G3D/platform.h"
+#include "G3D/enumclass.h"
+
+namespace G3D {
+
+/** These are defined to have the same value as the equivalent OpenGL
+ constant. */
+class PrimitiveType {
+public:
+ enum Value {
+ POINTS = 0x0000,
+ LINES = 0x0001,
+ LINE_STRIP = 0x0003,
+ TRIANGLES = 0x0004,
+ TRIANGLE_STRIP = 0x0005,
+ TRIANGLE_FAN = 0x0006,
+ QUADS = 0x0007,
+ QUAD_STRIP = 0x0008
+ };
+
+private:
+
+ Value value;
+
+public:
+
+ G3D_DECLARE_ENUM_CLASS_METHODS(PrimitiveType);
+};
+
+
+/** Values for SuperSurface::GPUGeom::refractionHint. */
+class RefractionQuality {
+public:
+ enum Value {
+ /** No refraction; a translucent object will appear as if it had the same index of refraction
+ as the surrounding medium and objects will be undistorted in the background. */
+ NONE = 0,
+
+ /** Use a static environment map (cube or paraboloid) for computing transmissivity.*/
+ STATIC_ENV = 25,
+
+ /** Use a dynamically rendered 2D environment map; distort the background. This looks good for many scenes
+ but avoids the cost of rendering a cube map for DYNAMIC_ENV. */
+ DYNAMIC_FLAT = 50,
+
+ /** Use a dynamically rendered 2D environment map that is re-captured per transparent object. This works well
+ for transparent objects that are separated by a significant camera space z distance but overlap in screen space.*/
+ DYNAMIC_FLAT_MULTILAYER = 55,
+
+ /** Render a dynamic environment map */
+ DYNAMIC_ENV = 75,
+
+ /** Use the best method available, ideally true ray tracing. */
+ BEST = 100
+ };
+
+private:
+
+ /** Used for to/from string conversion. Last is the emtpy string as a sentinel */
+ static const std::string str[7];
+ static const Value enm[6];
+ Value value;
+
+public:
+ G3D_DECLARE_ENUM_CLASS_METHODS(RefractionQuality);
+
+ RefractionQuality(const class Any&);
+ RefractionQuality& operator=(const Any&);
+ operator Any() const;
+ const std::string& toString() const;
+};
+
+
+/** Values for SuperSurface::GPUGeom::mirrorHint. */
+class MirrorQuality {
+public:
+
+ enum Value {
+ /** Reflections are black */
+ NONE = 0,
+
+ /** Use a static environment map. This is what most games use */
+ STATIC_ENV = 25,
+
+ /** Planar reflection, typically for water or glass windows. This assumes that the mirror is flat;
+ it is distinct from RefractionQuality::DYNAMIC_FLAT, which assumes the <i>background</i> is flat.*/
+ DYNAMIC_PLANAR = 50,
+
+ /** Render a dynamic environment map. */
+ DYNAMIC_ENV = 75,
+
+ /** Use the best method available, ideally true ray tracing. */
+ BEST = 100
+ };
+
+private:
+
+ /** Used for to/from string conversion. Last is the emtpy string as a sentinel */
+ static const std::string str[6];
+ static const Value enm[5];
+
+ Value value;
+
+public:
+ G3D_DECLARE_ENUM_CLASS_METHODS(MirrorQuality);
+ MirrorQuality(const class Any&);
+ MirrorQuality& operator=(const Any&);
+ operator Any() const;
+ const std::string& toString() const;
+};
+
+} // namespace G3D
+
+G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::PrimitiveType)
+G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::RefractionQuality)
+G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::MirrorQuality)
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/debug.h b/dep/include/g3dlite/G3D/debug.h
index 408dd3ea146..a7697fe9c01 100644
--- a/dep/include/g3dlite/G3D/debug.h
+++ b/dep/include/g3dlite/G3D/debug.h
@@ -1,12 +1,66 @@
+/**
+ @file debug.h
-#ifndef G3D_LITE_DEBUG_H
-#define G3D_LITE_DEBUG_H
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
-#define debugStatement(x)
-#define debugAssert(x)
-#define debugAssertM(x, y)
-#define alwaysAssertM(x, y)
+ @created 2001-08-26
+ @edited 2006-02-16
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+*/
+
+#ifndef G3D_DEBUG_H
+#define G3D_DEBUG_H
+
+#include "G3D/platform.h"
+#ifdef _MSC_VER
+ #include <crtdbg.h>
+#endif
+
+#include "G3D/debugPrintf.h"
+#include "G3D/debugAssert.h"
+
+namespace G3D {
+
+#ifdef _MSC_VER
+ // Turn off 64-bit warnings
+# pragma warning(push)
+# pragma warning( disable : 4312)
+# pragma warning( disable : 4267)
+# pragma warning( disable : 4311)
#endif
+/**
+ Useful for debugging purposes.
+ */
+inline bool isValidHeapPointer(const void* x) {
+ #ifdef _MSC_VER
+ return
+ (x != (void*)0xcccccccc) && (x != (void*)0xdeadbeef) && (x != (void*)0xfeeefeee);
+ #else
+ return x != NULL;
+ #endif
+}
+
+/**
+ Returns true if the pointer is likely to be
+ a valid pointer (instead of an arbitrary number).
+ Useful for debugging purposes.
+ */
+inline bool isValidPointer(const void* x) {
+ #ifdef _MSC_VER
+ return x != ((void*)0xcccccccc) && (x != (void*)0xdeadbeef) && (x != (void*)0xfeeefeee);
+ #else
+ return x != NULL;
+ #endif
+}
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/debugAssert.h b/dep/include/g3dlite/G3D/debugAssert.h
new file mode 100644
index 00000000000..432e97e679d
--- /dev/null
+++ b/dep/include/g3dlite/G3D/debugAssert.h
@@ -0,0 +1,233 @@
+/**
+ @file debugAssert.h
+
+ debugAssert(expression);
+ debugAssertM(expression, message);
+
+ @cite
+ John Robbins, Microsoft Systems Journal Bugslayer Column, Feb 1999.
+ <A HREF="http://msdn.microsoft.com/library/periodic/period99/feb99_BUGSLAYE_BUGSLAYE.htm">
+ http://msdn.microsoft.com/library/periodic/period99/feb99_BUGSLAYE_BUGSLAYE.htm</A>
+
+ @cite
+ Douglas Cox, An assert() Replacement, Code of The Day, flipcode, Sept 19, 2000
+ <A HREF="http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-AssertReplace&forum=cotd&id=-1">
+ http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-AssertReplace&forum=cotd&id=-1</A>
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-08-26
+ @edited 2006-01-12
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_DEBUGASSERT_H
+#define G3D_DEBUGASSERT_H
+
+#include <string>
+#include "G3D/platform.h"
+
+#include <cstdlib>
+
+#ifdef _MSC_VER
+// conditional expression is constant
+# pragma warning (disable : 4127)
+#endif
+
+#ifdef G3D_LINUX
+ // Needed so we can define a global display
+ // pointer for debugAssert.
+#if SOMEONE_MADE_THIS_USEFUL
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+ #include <X11/Xatom.h>
+#endif
+#endif
+
+
+/**
+ @def debugBreak()
+
+ Break at the current location (i.e. don't push a procedure stack frame
+ before breaking).
+ */
+
+/**
+ @def debugAssert(exp)
+ Breaks if the expression is false. If G3D_DEBUG_NOGUI is defined, prompts at
+ the console, otherwise pops up a dialog. The user may then break (debug),
+ ignore, or halt the program.
+
+ The assertion is also posted to the clipboard under Win32.
+ */
+
+/**
+ @def debugAssertM(exp, msg)
+ Breaks if the expression is false and displays a message. If G3D_DEBUG_NOGUI
+ is defined, prompts at the console, otherwise pops up a dialog. The user may
+ then break (debug), ignore, or halt the program.
+
+ The assertion is also posted to the clipboard under Win32.
+ */
+
+/**
+ @def alwaysAssertM(exp, msg)
+ Same as debugAssertM except that it asserts in release builds as well.
+ */
+
+namespace G3D {
+typedef bool (*AssertionHook)(
+ const char* _expression,
+ const std::string& message,
+ const char* filename,
+ int lineNumber,
+ bool useGuiPrompt);
+
+/**
+ Allows customization of the global function invoked when a debugAssert fails.
+ The initial value is G3D::_internal::_handleDebugAssert_. G3D will invoke
+ rawBreak if the hook returns true. If NULL, assertions are not handled.
+*/
+void setAssertionHook(AssertionHook hook);
+
+AssertionHook assertionHook();
+
+/**
+ Called by alwaysAssertM in case of failure in release mode. If returns
+ true then the program exits with -1 (you can replace this with your own
+ version that throws an exception or has other failure modes).
+ */
+void setFailureHook(AssertionHook hook);
+AssertionHook failureHook();
+
+namespace _internal {
+ extern AssertionHook _debugHook;
+ extern AssertionHook _failureHook;
+} // internal
+} // G3D
+
+/**
+ @def __debugPromptShowDialog__
+ @internal
+ */
+
+#ifdef G3D_DEBUG
+
+# if defined(_MSC_VER)
+# define rawBreak() ::DebugBreak();
+# elif defined(__i386__)
+ // gcc on intel
+# define rawBreak() __asm__ __volatile__ ( "int $3" );
+# else
+ // some other gcc
+# define rawBreak() ::abort()
+# endif
+
+
+# define debugBreak() G3D::_internal::_releaseInputGrab_(); rawBreak(); G3D::_internal::_restoreInputGrab_();
+# define debugAssert(exp) debugAssertM(exp, "Debug assertion failure")
+
+ #ifdef G3D_DEBUG_NOGUI
+ #define __debugPromptShowDialog__ false
+ #else
+ #define __debugPromptShowDialog__ true
+ #endif
+
+ #define debugAssertM(exp, message) do { \
+ if (!(exp)) { \
+ G3D::_internal::_releaseInputGrab_(); \
+ if ((G3D::_internal::_debugHook != NULL) && \
+ G3D::_internal::_debugHook((const char*)(#exp), message, __FILE__, __LINE__, __debugPromptShowDialog__)) { \
+ rawBreak(); \
+ } \
+ G3D::_internal::_restoreInputGrab_(); \
+ } \
+ } while (0)
+
+ #define alwaysAssertM debugAssertM
+
+#else // Release
+ #ifdef G3D_DEBUG_NOGUI
+ #define __debugPromptShowDialog__ false
+ #else
+ #define __debugPromptShowDialog__ true
+ #endif
+
+ // In the release build, just define away assertions.
+ #define rawBreak() do {} while (0)
+ #define debugAssert(exp) do {} while (0)
+ #define debugAssertM(exp, message) do {} while (0)
+ #define debugBreak() do {} while (0)
+
+ // But keep the 'always' assertions
+ #define alwaysAssertM(exp, message) { \
+ if (!(exp)) { \
+ G3D::_internal::_releaseInputGrab_(); \
+ if ((G3D::_internal::_failureHook != NULL) && \
+ G3D::_internal::_failureHook(#exp, message, __FILE__, __LINE__, __debugPromptShowDialog__)) { \
+ ::exit(-1); \
+ } \
+ G3D::_internal::_restoreInputGrab_(); \
+ } \
+ }
+
+#endif // if debug
+
+
+
+namespace G3D { namespace _internal {
+
+#ifdef G3D_LINUX
+#if SOMEONE_MADE_THIS_USEFUL
+ /**
+ A pointer to the X11 display. Initially NULL. If set to a
+ non-null value (e.g. by SDLWindow), debugAssert attempts to use
+ this display to release the mouse/input grab when an assertion
+ fails.
+ */
+ extern Display* x11Display;
+
+ /**
+ A pointer to the X11 window. Initially NULL. If set to a
+ non-null value (e.g. by SDLWindow), debugAssert attempts to use
+ this window to release the mouse/input grab when an assertion
+ fails.
+ */
+ extern Window x11Window;
+#endif
+#endif
+
+/**
+ Pops up an assertion dialog or prints an assertion
+
+ ignoreAlways - return result of pressing the ignore button.
+ useGuiPrompt - if true, shows a dialog
+ */
+bool _handleDebugAssert_(
+ const char* expression,
+ const std::string& message,
+ const char* filename,
+ int lineNumber,
+ bool useGuiPrompt);
+
+bool _handleErrorCheck_(
+ const char* expression,
+ const std::string& message,
+ const char* filename,
+ int lineNumber,
+ bool useGuiPrompt);
+
+/** Attempts to give the user back their mouse and keyboard if they
+ were locked to the current window.
+ @internal*/
+void _releaseInputGrab_();
+
+/** Attempts to restore the state before _releaseInputGrab_.
+ @internal*/
+void _restoreInputGrab_();
+
+}; }; // namespace
+
+#endif
diff --git a/dep/include/g3dlite/G3D/debugPrintf.h b/dep/include/g3dlite/G3D/debugPrintf.h
new file mode 100644
index 00000000000..b42151cae9e
--- /dev/null
+++ b/dep/include/g3dlite/G3D/debugPrintf.h
@@ -0,0 +1,62 @@
+/**
+ @file debugPrintf.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-08-26
+ @edited 2007-07-20
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_DEBUGPRINTF_H
+#define G3D_DEBUGPRINTF_H
+
+#include "G3D/platform.h"
+#include <stdio.h>
+#include <cstdarg>
+#include "G3D/format.h"
+#include <string>
+
+namespace G3D {
+
+typedef void (*ConsolePrintHook)(const std::string&);
+
+namespace _internal {
+ extern ConsolePrintHook _consolePrintHook;
+}
+
+/** Called by consolePrintf after the log and terminal have been written to.
+ Used by GConsole to intercept printing routines.*/
+void setConsolePrintHook(ConsolePrintHook h);
+
+ConsolePrintHook consolePrintHook();
+
+/**
+ Sends output to the log and to the last GConsole instantiated.
+
+ Guarantees that the output has been flushed by the time the routine
+ returns.
+ @sa G3D::logPrintf, G3D::screenPrintf
+ @return The string that was printed
+ */
+std::string __cdecl consolePrintf(const char* fmt ...) G3D_CHECK_PRINTF_ARGS;
+std::string consolePrint(const std::string&);
+
+/**
+ Under visual studio, appears in the VS debug pane.
+ On unix-based operating systems the output is sent to stderr.
+
+ Also sends output to the console (G3D::consolePrintf) if there is a consolePrintHook,
+ and log (G3D::logPrintf), and flushes before returning.
+
+ @return The string that was printed
+*/
+std::string __cdecl debugPrintf(const char* fmt ...) G3D_CHECK_PRINTF_ARGS;
+std::string debugPrint(const std::string&);
+
+} // namespace G3D
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/enumclass.h b/dep/include/g3dlite/G3D/enumclass.h
new file mode 100644
index 00000000000..c7dfe45f14f
--- /dev/null
+++ b/dep/include/g3dlite/G3D/enumclass.h
@@ -0,0 +1,147 @@
+/**
+ @file G3D/enumclass.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2007-01-27
+ @edited 2007-07-20
+*/
+#ifndef G3D_enumclass_h
+#define G3D_enumclass_h
+
+#include "G3D/HashTrait.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+/**
+\def G3D_DECLARE_ENUM_CLASS_METHODS
+
+ \brief Creates a series of methods that turn a class into a scoped enumeration.
+
+ Uses the "Intelligent Enum" design pattern
+ http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4001/
+
+ Enum classes are initialized to their zero value by default.
+
+ See GLG3D/GKey.h for an example.
+ \sa G3D_DECLARE_ENUM_CLASS_HASHCODE
+ */
+#define G3D_DECLARE_ENUM_CLASS_METHODS(Classname)\
+ inline Classname(char v) : value((Value)v) {}\
+\
+ inline Classname() : value((Value)0) {}\
+\
+ inline Classname(const Value v) : value(v) {}\
+\
+ explicit inline Classname(int v) : value((Value)v) {}\
+\
+ /** Support cast back to the Value type, which is needed to allow implicit assignment inside unions. */\
+ /*inline operator Value() const {
+ return value;
+ }*/\
+\
+ inline operator int() const {\
+ return (int)value;\
+ }\
+\
+ inline bool operator== (const Classname other) const {\
+ return value == other.value;\
+ }\
+\
+ inline bool operator== (const Classname::Value other) const {\
+ return value == other;\
+ }\
+\
+ inline bool operator!= (const Classname other) const {\
+ return value != other.value;\
+ }\
+\
+ inline bool operator!= (const Classname::Value other) const {\
+ return value != other;\
+ }\
+\
+ inline bool operator< (const Classname other) const {\
+ return value < other.value;\
+ }\
+\
+ inline bool operator> (const Classname other) const {\
+ return value > other.value;\
+ }\
+\
+ inline bool operator>= (const Classname other) const {\
+ return value >= other.value;\
+ }\
+\
+ inline bool operator<= (const Classname other) const {\
+ return value <= other.value;\
+ }\
+\
+ inline bool operator< (const Value other) const {\
+ return value < other;\
+ }\
+\
+ inline bool operator> (const Value other) const {\
+ return value > other;\
+ }\
+\
+ inline bool operator<= (const Value other) const {\
+ return value <= other;\
+ }\
+\
+ inline bool operator>= (const Value other) const {\
+ return value >= other;\
+ }\
+\
+ inline Classname& operator-- () {\
+ value = (Value)((int)value - 1);\
+ return *this;\
+ }\
+\
+ inline Classname& operator++ () {\
+ value = (Value)((int)value + 1);\
+ return *this;\
+ }\
+\
+ inline Classname& operator+= (const int x) {\
+ value = (Value)((int)value + x);\
+ return *this;\
+ }\
+\
+ inline Classname& operator-= (const int x) {\
+ value = (Value)((int)value - x);\
+ return *this;\
+ }\
+\
+ inline Classname operator+ (const int x) const {\
+ return Classname((int)value + x);\
+ }\
+\
+ inline Classname operator- (const int x) const {\
+ return Classname((int)value - x);\
+ }\
+\
+ inline unsigned int hashCode() const {\
+ return (unsigned int)value;\
+ }\
+\
+ inline void serialize(BinaryOutput& b) const {\
+ b.writeInt32(value);\
+ }\
+\
+ inline void deserialize(BinaryInput& b) {\
+ value = (Value)b.readInt32();\
+ }
+
+/** \def G3D_DECLARE_ENUM_CLASS_HASHCODE
+*/
+#define G3D_DECLARE_ENUM_CLASS_HASHCODE(Classname)\
+template <> struct HashTrait<Classname::Value> \
+{ \
+ static size_t hashCode(Classname::Value key) { return static_cast<size_t>(key); } \
+}; \
+ \
+template <> struct HashTrait<Classname> \
+{ \
+ static size_t hashCode(Classname key) { return static_cast<size_t>(key.hashCode()); } \
+};
+
+#endif
diff --git a/dep/include/g3dlite/G3D/fileutils.h b/dep/include/g3dlite/G3D/fileutils.h
new file mode 100644
index 00000000000..9e49777d93a
--- /dev/null
+++ b/dep/include/g3dlite/G3D/fileutils.h
@@ -0,0 +1,254 @@
+/**
+ @file fileutils.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @author 2002-06-06
+ @edited 2010-02-06
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_fileUtils_h
+#define G3D_fileUtils_h
+
+#include "G3D/platform.h"
+#include <string>
+#include <stdio.h>
+#include "G3D/Array.h"
+#include "G3D/Set.h"
+#include "G3D/g3dmath.h"
+
+#ifdef G3D_WIN32
+// For chdir, mkdir, etc.
+# include <direct.h>
+#endif
+
+namespace G3D {
+
+ namespace _internal {
+ extern Set<std::string> currentFilesUsed;
+ }
+
+/** Returns all the files used by G3D and GLG3D during the current execution. */
+Array<std::string> filesUsed();
+
+std::string readWholeFile(
+ const std::string& filename);
+
+
+/** Reads from a zip file and decompresses the desired contents
+ into memory. Does not support recursive zip calls (i.e. a .zip
+ stored within another .zip)
+
+ @param file the path, of the format C:\\...\\something.zip\\...\\desiredfile.ext
+ @param data a pointer to the memory where the file will be stored
+ @param length the size of the file decompressed to memory */
+void zipRead(const std::string& file,
+ void*& data,
+ size_t& length);
+
+
+/** Closes the contents of a zip file that had been decompressed to
+ memory. Must be called in tandem with zipRead() to avoid memory
+ leaks.
+
+ @param data the pointer to the decompressed file in memory */
+void zipClose(void* data);
+
+
+/**
+ @param flush If true (default), the file is ready for reading as soon
+ as the function returns. If false, the function returns immediately and
+ writes the file in the background.
+ */
+void writeWholeFile(
+ const std::string& filename,
+ const std::string& str,
+ bool flush = true);
+
+/**
+ Creates the directory (which may optionally end in a /)
+ and any parents needed to reach it.
+ */
+void createDirectory(
+ const std::string& dir);
+
+/**
+ Fully qualifies a filename. The filename may contain wildcards,
+ in which case the wildcards will be preserved in the returned value.
+ */
+std::string resolveFilename(const std::string& filename);
+
+/**
+ Appends all files matching filespec to the files array. The names
+ will not contain paths unless includePath == true. These may be
+ relative to the current directory unless the filespec is fully qualified
+ (can be done with resolveFilename).
+ Wildcards can only appear to the right of the last slash in filespec.
+ Works with .zip files used as paths, if filespec is passed in the form
+ C:\\...\\something.zip\\* Does not work recursively with zipfiles (a
+ .zip within a .zip will not work)
+ */
+void getFiles(
+ const std::string& filespec,
+ Array<std::string>& files,
+ bool includePath = false);
+
+/**
+ Appends all directories matching filespec to the files array. The names
+ will not contain paths unless includePath == true. These may be
+ relative to the current directory unless the filespec is fully qualified
+ (can be done with resolveFilename).
+ Does not append special directories "." or "..".
+ Works with .zip files used as paths, if filespec is passed in the form
+ C:\\...\\something.zip\\* Does not work recursively with zipfiles (a
+ .zip within a .zip will not work)
+ */
+void getDirs(
+ const std::string& filespec,
+ Array<std::string>& files,
+ bool includePath = false);
+
+
+/** Returns true if the specified path exists and is a directory */
+bool isDirectory(const std::string& filespec);
+
+
+/** Returns true if the specified filename exists and is a zipfile */
+bool isZipfile(const std::string& filename);
+
+
+/** Returns the length of the file. If
+ filename specifies a path that contains a zipfile, but the
+ contents within are specified correctly, returns the
+ uncompressed size of the requested file. Returns -1 if
+ the file does not exist.
+
+ @param filename the path to test, may contain .zip
+*/
+int64 fileLength(const std::string& filename);
+
+/**
+ Copies the file
+ */
+void copyFile(
+ const std::string& source,
+ const std::string& dest);
+
+/** Returns a temporary file that is open for read/write access. This
+ tries harder than the ANSI tmpfile, so it may succeed when that fails. */
+FILE* createTempFile();
+
+/**
+ Returns true if the given file (or directory) exists.
+
+ \param filename the path to test. must not end in a trailing slash.
+ \param lookInZipfiles if the path does not exist, calls zipfileExists()
+ \param trustCache If true and \a lookInZipfiles is true, cache directory and zipfile contents
+ so that subsequent calls to the same directory are fast.
+
+ \sa G3D::clearFileSystemCache, G3D::zipfileExists
+ */
+bool fileExists
+(const std::string& filename,
+ bool lookInZipfiles = true,
+ bool trustCache = true);
+
+
+/** Clears the cache used by fileExists */
+void clearFileSystemCache();
+
+/**
+ Returns true if the given file (or directory) exists
+ within a zipfile. Called if fileExists initially
+ returns false and the lookInZipfiles flag has been set.
+ Must not end in a trailing slash. Does not work for recursive
+ zipfiles (.zips within another .zip)
+
+ @param filename the path to test
+ @param outZipfile the path to the .zip file
+ @param outInternalFile the path (within the .zip) where the desired file is located, if valid
+
+ */
+bool zipfileExists
+(const std::string& filename,
+ std::string& outZipfile,
+ std::string& outInternalFile);
+
+bool zipfileExists(const std::string& filename);
+
+/**
+ Parses a filename into four useful pieces.
+
+ Examples:
+
+ c:\\a\\b\\d.e
+ root = "c:\\"
+ path = "a" "b"
+ base = "d"
+ ext = "e"
+
+ /a/b/d.e
+ root = "/"
+ path = "a" "b"
+ base = "d"
+ ext = "e"
+
+ /a/b
+ root = "/"
+ path = "a"
+ base = "b"
+ ext = "e"
+
+ */
+void parseFilename(
+ const std::string& filename,
+ std::string& drive,
+ Array<std::string>& path,
+ std::string& base,
+ std::string& ext);
+
+
+/**
+ Returns the part of the filename that includes the base and ext from
+ parseFilename (i.e. everything to the right of the path).
+ */
+std::string filenameBaseExt(const std::string& filename);
+
+/**
+ Returns the extension on a filename.
+ */
+std::string filenameExt(const std::string& filename);
+
+
+/** Returns the portion of a filename to the left of the last period
+ and to the right of the last slash or colon.
+ */
+std::string filenameBase(const std::string& filename);
+
+/** Creates a unique filename base in the current directory using the
+ specified prefix and suffix.*/
+std::string generateFilenameBase(const std::string& prefix = "", const std::string& suffix = "");
+
+/**
+ Returns the drive (if Win32) and path from a filename, including
+ a slash if there was one.
+ <CODE>filenamePath(f) + filenameBaseExt(f) == f</CODE>
+ */
+std::string filenamePath(const std::string& filename);
+
+/** Returns true if '*' or '?' appears in the string */
+bool filenameContainsWildcards(const std::string& filename);
+
+/** Returns true if dst does not exist or src is newer than dst. Works on both files and directories. */
+bool fileIsNewer(const std::string& src, const std::string& dst);
+
+/** Appends file onto dirname, ensuring a / if needed. */
+std::string pathConcat(const std::string& dirname, const std::string& file);
+
+} // namespace
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/filter.h b/dep/include/g3dlite/G3D/filter.h
new file mode 100644
index 00000000000..609477b79c9
--- /dev/null
+++ b/dep/include/g3dlite/G3D/filter.h
@@ -0,0 +1,29 @@
+/**
+ @file G3D/filter.h
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2007-03-01
+ @edited 2007-03-01
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_FILTER_H
+#define G3D_FILTER_H
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+/**
+ Generates a set of 1D gaussian filter coefficients of size N. The coefficients
+ are centered on element (N-1)/2 and have standard deviation given by std. The coefficients
+ are normalized such that the sum across coeff is 1.0.
+
+ Matches the results returned by Matlab <code>fspecial('gaussian', [1, N], std)</code>
+ */
+void gaussian1D(Array<float>& coeff, int N = 5, float std = 0.5f);
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/format.h b/dep/include/g3dlite/G3D/format.h
index b2948bfcd25..3c7f0678876 100644
--- a/dep/include/g3dlite/G3D/format.h
+++ b/dep/include/g3dlite/G3D/format.h
@@ -1,8 +1,8 @@
/**
@file format.h
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@author 2000-09-09
@edited 2005-11-03
@@ -17,19 +17,6 @@
#include <string>
#include <stdio.h>
#include <cstdarg>
-#include <assert.h>
-#ifndef G3D_WIN32
- // Don't include varargs.h for some random
- // gcc reason
- //#include <varargs.h>
- #include <stdarg.h>
-#endif
-
-#ifndef _MSC_VER
- #ifndef __cdecl
- #define __cdecl __attribute__((cdecl))
- #endif
-#endif
namespace G3D {
@@ -40,7 +27,7 @@ namespace G3D {
string is under 160 characters (not including terminator) and slower
when the string is longer.
*/
-std::string format(
+std::string __cdecl format(
const char* fmt
...) G3D_CHECK_PRINTF_ARGS;
@@ -51,7 +38,7 @@ std::string vformat(
const char* fmt,
va_list argPtr) G3D_CHECK_VPRINTF_ARGS;
-}; // namespace
-#endif
+} // namespace
+#endif
diff --git a/dep/include/g3dlite/G3D/g3dfnmatch.h b/dep/include/g3dlite/G3D/g3dfnmatch.h
new file mode 100644
index 00000000000..464b3927eee
--- /dev/null
+++ b/dep/include/g3dlite/G3D/g3dfnmatch.h
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 1992, 1993
+ *The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *This product includes software developed by the University of
+ *California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *@(#)fnmatch.h8.1 (Berkeley) 6/2/93
+ *
+ * From FreeBSD fnmatch.h 1.7
+ * $Id: g3dfnmatch.h,v 1.1 2010/02/06 06:51:28 morgan3d Exp $
+ */
+#ifndef G3D_g3dfnmatch_h
+#define G3D_g3dfnmatch_h
+
+#include "G3D/platform.h"
+
+namespace G3D {
+
+#if defined(G3D_WIN32)
+
+# if ! defined(FNM_NOMATCH)
+# define FNM_NOMATCH 1 /* Match failed. */
+# define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
+# define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
+# define FNM_PERIOD 0x04 /* Period must be matched by period. */
+# define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
+# define FNM_CASEFOLD 0x10 /* Case insensitive search. */
+# define FNM_PREFIX_DIRS 0x20 /* Directory prefixes of pattern match too. */
+# endif
+
+#else
+
+ // On non-windows systems, include fnmatch directly
+# include <fnmatch.h>
+#endif
+
+
+/**
+ Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ Compares a filename or pathname to a pattern.
+
+The fnmatch() function checks whether the string argument matches the pattern argument, which is a shell wildcard pattern.
+The flags argument modifies the behaviour; it is the bitwise OR of zero or more of the following flags:
+
+- FNM_NOESCAPE If this flag is set, treat backslash as an ordinary character, instead of an escape character.
+- FNM_PATHNAME If this flag is set, match a slash in string only with a slash in pattern and not by an asterisk (*) or a question mark (?) metacharacter, nor by a bracket expression ([]) containing a slash.
+- FNM_PERIOD If this flag is set, a leading period in string has to be matched exactly by a period in pattern. A period is considered to be leading if it is the first character in string, or if both FNM_PATHNAME is set and the period immediately follows a slash.
+- FNM_FILE_NAME This is a GNU synonym for FNM_PATHNAME.
+- FNM_LEADING_DIR If this flag (a GNU extension) is set, the pattern is considered to be matched if it matches an initial segment of string which is followed by a slash. This flag is mainly for the internal use of glibc and is only implemented in certain cases.
+- FNM_CASEFOLD If this flag (a GNU extension) is set, the pattern is matched case-insensitively.
+
+\return Zero if \a string matches \a pattern, FNM_NOMATCH if there is no match or another non-zero value if there is an error
+
+ */
+int g3dfnmatch(const char *pattern, const char *string, int flags);
+}
+#endif
diff --git a/dep/include/g3dlite/G3D/g3dmath.h b/dep/include/g3dlite/G3D/g3dmath.h
index ecf355157c1..d16214ebb37 100644
--- a/dep/include/g3dlite/G3D/g3dmath.h
+++ b/dep/include/g3dlite/G3D/g3dmath.h
@@ -1,20 +1,20 @@
/**
@file g3dmath.h
-
+
Math util class.
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite highestBit by Jukka Liimatta
-
+
@created 2001-06-02
- @edited 2006-01-16
+ @edited 2009-04-07
Copyright 2000-2006, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3DMATH_H
-#define G3DMATH_H
+#ifndef G3D_g3dmath_h
+#define G3D_g3dmath_h
#ifdef _MSC_VER
// Disable conditional expression is constant, which occurs incorrectly on inlined functions
@@ -26,13 +26,22 @@
#include "G3D/platform.h"
#include <ctype.h>
-#include <string>
#include <float.h>
#include <limits>
+#include <stdlib.h>
+
+#ifdef _MSC_VER
+ // Visual Studio is missing inttypes.h
+# ifndef PRId64
+# define PRId64 "I64d"
+# endif
+#else
+#include <inttypes.h>
+#endif
/*These defines enable functionality introduced with the 1999 ISO C
**standard. They must be defined before the inclusion of math.h to
-**engage them. If optimisation is enabled, these functions will be
+**engage them. If optimisation is enabled, these functions will be
**inlined. With optimisation switched off, you have to link in the
**maths library using -lm.
*/
@@ -51,20 +60,23 @@
namespace G3D {
-#if defined(_MSC_VER)
+#ifdef _MSC_VER
+inline double __fastcall drand48() {
+ return ::rand() / double(RAND_MAX);
+}
#if !defined(_WIN64)
/**
Win32 implementation of the C99 fast rounding routines.
-
+
@cite routines are
Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
-
- Permission to use, copy, modify, distribute, and sell this file for any
- purpose is hereby granted without fee, provided that the above copyright
+
+ Permission to use, copy, modify, distribute, and sell this file for any
+ purpose is hereby granted without fee, provided that the above copyright
and this permission notice appear in all copies. No representations are
- made about the suitability of this software for any purpose. It is
+ made about the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
*/
@@ -104,83 +116,50 @@ __inline long int lrintf(float flt) {
#endif
-const double fuzzyEpsilon = 0.00001;
-/** Returns a reference to a static double.
+#define fuzzyEpsilon (0.00001f)
+/**
This value should not be tested against directly, instead
G3D::isNan() and G3D::isFinite() will return reliable results. */
-inline const double& inf() {
+double inf();
-// We already have <limits> included but
-// not using it in older gcc for safe compilations
-#if (__GNUC__ == 2)
- static const double i = 1.0/sin(0.0);
-#else
- // double is a standard type and should have infinity
- static const double i = std::numeric_limits<double>::infinity();
-#endif
- return i;
-}
-
-/** Returns a reference to a static double.
- This value should not be tested against directly, instead
+/** This value should not be tested against directly, instead
G3D::isNan() and G3D::isFinite() will return reliable results. */
-inline const double& nan() {
+double nan();
-// We already have <limits> included but
-// not using it in older gcc for safe compilations
-#if (__GNUC__ == 2)
- static const double n = 0.0/sin(0.0);
-#else
- // double is a standard type and should have quiet NaN
- static const double n = std::numeric_limits<double>::quiet_NaN();
-#endif
- return n;
-}
+float finf();
-/** Returns a reference to a static double. Use instead of G3D_PI. */
-inline const double& pi() {
- static const double p = 3.1415926535898;
- return p;
-}
+float fnan();
-/** Returns a reference to a static double. Use instead of G3D_HALF_PI. */
-inline const double& halfPi() {
- static const double p = 1.5707963267949;
- return p;
+inline double pi() {
+ return 3.1415926535898;
}
-/** Returns a reference to a static double. Use instead of G3D_TWO_PI. */
-inline const double& twoPi() {
- static const double p = 6.283185;
- return p;
+inline double halfPi() {
+ return 1.57079633;
}
-/** @def G3D_PI
- @deprecated Use G3D::pi() instead. */
-#define G3D_PI (3.1415926535898)
-/** @def G3D_HALF_PI
- @deprecated Use G3D::halfPi() instead. */
-#define G3D_HALF_PI (1.5707963267949)
-/** @def G3D_TWO_PI
- @deprecated Use G3D::twoPi() instead. */
-#define G3D_TWO_PI (6.283185)
+inline double twoPi() {
+ return 6.28318531;
+}
typedef signed char int8;
-typedef unsigned char uint8;
+typedef unsigned char uint8;
typedef short int16;
typedef unsigned short uint16;
typedef int int32;
typedef unsigned int uint32;
#ifdef _MSC_EXTENSIONS
- typedef __int64 int64;
- typedef unsigned __int64 uint64;
+ typedef __int64 int64;
+ typedef unsigned __int64 uint64;
+#elif ! defined(_MSC_VER)
+ typedef int64_t int64;
+ typedef uint64_t uint64;
#else
- typedef long long int64;
- typedef unsigned long long uint64;
+ typedef long long int64;
+ typedef unsigned long long uint64;
#endif
-typedef unsigned int uint;
typedef float float32;
typedef double float64;
@@ -192,6 +171,7 @@ int iCeil(double fValue);
Clamps the value to the range [low, hi] (inclusive)
*/
int iClamp(int val, int low, int hi);
+int16 iClamp(int16 val, int16 low, int16 hi);
double clamp(double val, double low, double hi);
float clamp(float val, float low, float hi);
@@ -223,7 +203,8 @@ inline int iSign(float f) {
return iSign((double)f);
}
-/**
+
+/**
Fast round to integer using the lrint routine.
Typically 6x faster than casting to integer.
*/
@@ -231,7 +212,7 @@ inline int iRound(double fValue) {
return lrint(fValue);
}
-/**
+/**
Fast round to integer using the lrint routine.
Typically 6x faster than casting to integer.
*/
@@ -242,6 +223,7 @@ inline int iRound(float f) {
/**
Returns a random number uniformly at random between low and hi
(inclusive).
+ @deprecated Use Random::integer
*/
int iRandom(int low, int hi);
@@ -264,6 +246,11 @@ bool isFinite(double x);
comparisons against nan return false.
*/
bool isNaN(double x);
+bool isNaN(float x);
+inline bool isNaN(int x) {
+ (void)x;
+ return false;
+}
/**
Computes x % 3.
@@ -271,77 +258,58 @@ bool isNaN(double x);
int iMod3(int x);
/**
- [0, 1]
- @deprecated use uniformRandom()
- */
-double unitRandom ();
-
-/**
- Uniform random number between low and hi, inclusive.
- @deprecated use uniformRandom()
- */
-double random(double low, double hi);
-
-/**
- [-1, 1]
- @deprecated use uniformRandom()
- */
-double symmetricRandom ();
-
-/**
Uniform random number between low and hi, inclusive. [low, hi]
+ @deprecated
+ @sa Random::uniform
*/
float uniformRandom(float low = 0.0f, float hi = 1.0f);
/**
- Normally distributed random number.
+ Normally distributed random number.
+
+ @deprecated
+ @sa Random::gaussian
*/
float gaussRandom(float mean = 0.0f, float stdev = 1.0f);
-#if defined(_MSC_VER) && (_MSC_VER <= 1200)
-
- /** VC6 lacks std::min and std::max */
- inline double min(double x, double y) {
- return std::_cpp_min(x, y);
- }
- /** VC6 lacks std::min and std::max */
- inline float min(float x, float y) {
- return std::_cpp_min(x, y);
- }
+/** Returns x<sup>5</sup> */
+template <class T>
+inline T pow5(T x) {
+ const T y = x * x;
+ return y * y * x;
+}
- /** VC6 lacks std::min and std::max */
- inline int min(int x, int y) {
- return std::_cpp_min(x, y);
- }
- /** VC6 lacks std::min and std::max */
- inline double max(double x, double y) {
- return std::_cpp_max(x, y);
- }
+template <class T>
+inline T min(const T& x, const T& y) {
+ return std::min<T>(x, y);
+}
- /** VC6 lacks std::min and std::max */
- inline float max(float x, float y) {
- return std::_cpp_max(x, y);
- }
+template <class T>
+inline T min(const T& x, const T& y, const T& z) {
+ return std::min<T>(std::min<T>(x, y), z);
+}
- /** VC6 lacks std::min and std::max */
- inline int max(int x, int y) {
- return std::_cpp_max(x, y);
- }
+template <class T>
+inline T min(const T& x, const T& y, const T& z, const T& w) {
+ return std::min<T>(std::min<T>(x, y), std::min<T>(z, w));
+}
-#else
- template <class T>
- inline T min(const T& x, const T& y) {
- return std::min<T>(x, y);
- }
+template <class T>
+inline T max(const T& x, const T& y) {
+ return std::max<T>(x, y);
+}
- template <class T>
- inline T max(const T& x, const T& y) {
- return std::max<T>(x, y);
- }
+template <class T>
+inline T max(const T& x, const T& y, const T& z) {
+ return std::max<T>(std::max<T>(x, y), z);
+}
-#endif
+template <class T>
+inline T max(const T& x, const T& y, const T& z, const T& w) {
+ return std::max<T>(std::max<T>(x, y), std::max<T>(z, w));
+}
int iMin(int x, int y);
int iMax(int x, int y);
@@ -357,7 +325,7 @@ double distance(double x, double y, double z);
the left. -1 means the number was 0.
@cite Based on code by jukka@liimatta.org
- */
+ */
int highestBit(uint32 x);
/**
@@ -367,8 +335,8 @@ int highestBit(uint32 x);
*/
bool fuzzyEq(double a, double b);
-/** True if a is definitely not equal to b.
- Guaranteed false if a == b.
+/** True if a is definitely not equal to b.
+ Guaranteed false if a == b.
Possibly false when a != b.*/
bool fuzzyNe(double a, double b);
@@ -393,30 +361,30 @@ inline float rsq(float x) {
}
/**
- Uses SSE to implement rsq.
- @cite Nick nicolas@capens.net
- */
-inline float SSErsq(float x) {
-
- #if defined(SSE) && defined(G3D_WIN32) && !defined(_WIN64)
- __asm {
- movss xmm0, x
- rsqrtss xmm0, xmm0
- movss x, xmm0
- }
- return x;
- #else
- return 1.0f / sqrt(x);
- #endif
-}
-
-/**
Return the next power of 2 higher than the input
- If the input is already a power of 2, the output will be the same
+ If the input is already a power of 2, the output will be the same
as the input.
*/
int ceilPow2(unsigned int in);
+/** Returns 2^x */
+inline int pow2(unsigned int x) {
+ return 1 << x;
+}
+
+inline double log2(double x) {
+ return ::log(x) * 1.442695;
+}
+
+inline float log2(float x) {
+ return ::logf(x) * 1.442695f;
+}
+
+inline double log2(int x) {
+ return log2((double)x);
+}
+
+
/**
* True if num is a power of two.
*/
@@ -456,6 +424,7 @@ inline float dot(float a, float b) {
return a * b;
}
+
/**
a * b (for DirectX/Cg support)
*/
@@ -470,10 +439,21 @@ inline double exp2(double x) {
return pow(2.0, x);
}
+inline float exp2(float x) {
+ return powf(2.0f, x);
+}
+
+/** @deprecated Use rsq */
inline double rsqrt(double x) {
return 1.0 / sqrt(x);
}
+/** @deprecated Use rsq */
+inline float rsqrt(float x) {
+ // TODO: default this to using the SSE2 instruction
+ return 1.0 / sqrtf(x);
+}
+
/**
sin(x)/x
*/
@@ -490,6 +470,19 @@ inline double sinc(double x) {
/**
Computes a floating point modulo; the result is t wrapped to the range [lo, hi).
*/
+inline float wrap(float t, float lo, float hi) {
+ if ((t >= lo) && (t < hi)) {
+ return t;
+ }
+
+ debugAssert(hi > lo);
+
+ float interval = hi - lo;
+
+ return t - interval * iFloor((t - lo) / interval);
+}
+
+
inline double wrap(double t, double lo, double hi) {
if ((t >= lo) && (t < hi)) {
return t;
@@ -500,21 +493,353 @@ inline double wrap(double t, double lo, double hi) {
double interval = hi - lo;
return t - interval * iFloor((t - lo) / interval);
-
}
inline double wrap(double t, double hi) {
- return wrap(t, 0, hi);
+ return wrap(t, 0.0, hi);
+}
+
+
+inline bool isFinite(double x) {
+ return ! isNaN(x) && (x < G3D::inf()) && (x > -G3D::inf());
+}
+
+inline bool isFinite(float x) {
+ return ! isNaN(x) && (x < G3D::finf()) && (x > -G3D::finf());
+}
+
+//----------------------------------------------------------------------------
+inline int iAbs (int iValue) {
+ return ( iValue >= 0 ? iValue : -iValue );
+}
+
+//----------------------------------------------------------------------------
+inline int iCeil (double fValue) {
+ return int(::ceil(fValue));
+}
+
+//----------------------------------------------------------------------------
+
+inline int iClamp(int val, int low, int hi) {
+ debugAssert(low <= hi);
+ if (val <= low) {
+ return low;
+ } else if (val >= hi) {
+ return hi;
+ } else {
+ return val;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+inline int16 iClamp(int16 val, int16 low, int16 hi) {
+ debugAssert(low <= hi);
+ if (val <= low) {
+ return low;
+ } else if (val >= hi) {
+ return hi;
+ } else {
+ return val;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+inline double clamp(double val, double low, double hi) {
+ debugAssert(low <= hi);
+ if (val <= low) {
+ return low;
+ } else if (val >= hi) {
+ return hi;
+ } else {
+ return val;
+ }
+}
+
+inline float clamp(float val, float low, float hi) {
+ debugAssert(low <= hi);
+ if (val <= low) {
+ return low;
+ } else if (val >= hi) {
+ return hi;
+ } else {
+ return val;
+ }
+}
+//----------------------------------------------------------------------------
+
+inline int iWrap(int val, int hi) {
+ if (val < 0) {
+ return ((val % hi) + hi) % hi;
+ } else {
+ return val % hi;
+ }
+}
+
+//----------------------------------------------------------------------------
+inline int iFloor (double fValue) {
+ return int(::floor(fValue));
+}
+
+//----------------------------------------------------------------------------
+inline int iSign (int iValue) {
+ return ( iValue > 0 ? + 1 : ( iValue < 0 ? -1 : 0 ) );
}
+inline int iSign (double fValue) {
+ return ( fValue > 0.0 ? + 1 : ( fValue < 0.0 ? -1 : 0 ) );
+}
+
+//----------------------------------------------------------------------------
+inline double abs (double fValue) {
+ return double(::fabs(fValue));
+}
+
+//----------------------------------------------------------------------------
+inline double aCos (double fValue) {
+ if ( -1.0 < fValue ) {
+ if ( fValue < 1.0 )
+ return double(::acos(fValue));
+ else
+ return 0.0;
+ } else {
+ return pi();
+ }
+}
+
+//----------------------------------------------------------------------------
+inline double aSin (double fValue) {
+ if ( -1.0 < fValue ) {
+ if ( fValue < 1.0 ) {
+ return double(::asin(fValue));
+ } else {
+ return -halfPi();
+ }
+ } else {
+ return halfPi();
+ }
+}
+
+//----------------------------------------------------------------------------
+inline double aTan (double fValue) {
+ return double(::atan(fValue));
+}
+
+//----------------------------------------------------------------------------
+inline double aTan2 (double fY, double fX) {
+ return double(::atan2(fY, fX));
+}
+
+//----------------------------------------------------------------------------
+inline double sign (double fValue) {
+ if (fValue > 0.0) {
+ return 1.0;
+ }
+
+ if (fValue < 0.0) {
+ return -1.0;
+ }
+
+ return 0.0;
+}
+
+inline float sign (float fValue) {
+ if (fValue > 0.0f) {
+ return 1.0f;
+ }
+
+ if (fValue < 0.0f) {
+ return -1.0f;
+ }
+
+ return 0.0f;
+}
+
+
+inline float uniformRandom(float low, float hi) {
+ return (hi - low) * float(::rand()) / float(RAND_MAX) + low;
+}
+
+inline double square(double x) {
+ return x * x;
+}
+
+inline float square(float x) {
+ return x * x;
+}
+
+inline int square(int x) {
+ return x * x;
+}
+
+//----------------------------------------------------------------------------
+inline double sumSquares(double x, double y) {
+ return x*x + y*y;
+}
+
+//----------------------------------------------------------------------------
+inline float sumSquares(float x, float y) {
+ return x*x + y*y;
+}
+
+//----------------------------------------------------------------------------
+inline double sumSquares(double x, double y, double z) {
+ return x*x + y*y + z*z;
+}
+
+//----------------------------------------------------------------------------
+inline float sumSquares(float x, float y, float z) {
+ return x*x + y*y + z*z;
+}
+
+//----------------------------------------------------------------------------
+inline double distance(double x, double y) {
+ return sqrt(sumSquares(x, y));
+}
+
+//----------------------------------------------------------------------------
+inline float distance(float x, float y) {
+ return sqrt(sumSquares(x, y));
+}
+
+//----------------------------------------------------------------------------
+inline double distance(double x, double y, double z) {
+ return sqrt(sumSquares(x, y, z));
+}
+
+//----------------------------------------------------------------------------
+inline float distance(float x, float y, float z) {
+ return sqrt(sumSquares(x, y, z));
+}
+
+//----------------------------------------------------------------------------
+
+/** @deprecated use G3D::min */
+inline int iMin(int x, int y) {
+ return (x >= y) ? y : x;
+}
+
+//----------------------------------------------------------------------------
+/** @deprecated use G3D::min */
+inline int iMax(int x, int y) {
+ return (x >= y) ? x : y;
+}
+
+//----------------------------------------------------------------------------
+inline int ceilPow2(unsigned int in) {
+ in -= 1;
+
+ in |= in >> 16;
+ in |= in >> 8;
+ in |= in >> 4;
+ in |= in >> 2;
+ in |= in >> 1;
+
+ return in + 1;
+}
+
+inline bool isPow2(int num) {
+ return ((num & -num) == num);
+}
+
+inline bool isOdd(int num) {
+ return (num & 1) == 1;
+}
+
+inline bool isEven(int num) {
+ return (num & 1) == 0;
+}
+
+inline double toRadians(double deg) {
+ return deg * pi() / 180.0;
+}
+
+inline double toDegrees(double rad) {
+ return rad * 180.0 / pi();
+}
+
+inline float toRadians(float deg) {
+ return deg * (float)pi() / 180.0f;
+}
+
+inline float toDegrees(float rad) {
+ return rad * 180.0f / (float)pi();
+}
+
+inline float toRadians(int deg) {
+ return deg * (float)pi() / 180.0f;
+}
+
+inline float toDegrees(int rad) {
+ return rad * 180.0f / (float)pi();
+}
+/**
+ Computes an appropriate epsilon for comparing a and b.
+ */
+inline double eps(double a, double b) {
+ // For a and b to be nearly equal, they must have nearly
+ // the same magnitude. This means that we can ignore b
+ // since it either has the same magnitude or the comparison
+ // will fail anyway.
+ (void)b;
+ const double aa = abs(a) + 1.0;
+ if (aa == inf()) {
+ return fuzzyEpsilon;
+ } else {
+ return fuzzyEpsilon * aa;
+ }
+}
+
+inline bool fuzzyEq(double a, double b) {
+ return (a == b) || (abs(a - b) <= eps(a, b));
+}
+
+inline bool fuzzyNe(double a, double b) {
+ return ! fuzzyEq(a, b);
+}
+
+inline bool fuzzyGt(double a, double b) {
+ return a > b + eps(a, b);
+}
+
+inline bool fuzzyGe(double a, double b) {
+ return a > b - eps(a, b);
+}
+
+inline bool fuzzyLt(double a, double b) {
+ return a < b - eps(a, b);
+}
+
+inline bool fuzzyLe(double a, double b) {
+ return a < b + eps(a, b);
+}
+
+inline int iMod3(int x) {
+ return x % 3;
+}
+
+/**
+ Given a 32-bit integer, returns the integer with the bytes in the opposite order.
+ */
+inline uint32 flipEndian32(const uint32 x) {
+ return (x << 24) | ((x & 0xFF00) << 8) |
+ ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24);
+}
+
+/**
+ Given a 16-bit integer, returns the integer with the bytes in the opposite order.
+ */
+inline uint16 flipEndian16(const uint16 x) {
+ return (x << 8) | ((x & 0xFF00) >> 8);
+}
+
+
} // namespace
#ifdef _MSC_VER
# pragma warning (pop)
#endif
-#include "g3dmath.inl"
-
#endif
-
diff --git a/dep/include/g3dlite/G3D/platform.h b/dep/include/g3dlite/G3D/platform.h
index 136413d1d9d..11ba0127a16 100644
--- a/dep/include/g3dlite/G3D/platform.h
+++ b/dep/include/g3dlite/G3D/platform.h
@@ -1,22 +1,27 @@
/**
@file platform.h
- #defines for platform specific issues.
+ \#defines for platform specific issues.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-06-09
- @edited 2006-01-16
+ @edited 2010-01-11
*/
-#ifndef G3D_PLATFORM_H
-#define G3D_PLATFORM_H
+#ifndef G3D_platform_h
+#define G3D_platform_h
/**
The version number of G3D in the form: MmmBB ->
version M.mm [beta BB]
*/
-#define G3D_VER 61000
+#define G3D_VER 80004
+
+// fatal error for unsupported architectures
+#if defined(__powerpc__)
+# error PowerPC is not supported by G3D!
+#endif
#if defined(G3D_RELEASEDEBUG)
# define G3D_DEBUGRELEASE
@@ -26,51 +31,50 @@
# undef _DEBUG
#endif
+/** @def G3D_DEBUG()
+ Defined if G3D is built in debug mode. */
#if !defined(G3D_DEBUG) && (defined(_DEBUG) || defined(G3D_DEBUGRELEASE))
# define G3D_DEBUG
#endif
+#ifndef _MSC_VER
+/// Fast call is a register-based optimized calling convention supported only by Visual C++
+#define __fastcall
+
+#endif
+
#ifdef _MSC_VER
#define G3D_WIN32
-#elif defined(__MINGW32__)
- #define G3D_WIN32
- #define G3D_MINGW32
-#elif defined(__linux__)
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
+ #define G3D_FREEBSD
#define G3D_LINUX
-#elif defined(__OpenBSD__)
- #define G3D_LINUX
-#elif defined(__FreeBSD__)
- #define G3D_LINUX
-#elif defined(__NetBSD__)
+#elif defined(__linux__)
#define G3D_LINUX
#elif defined(__APPLE__)
#define G3D_OSX
+
+ // Prevent OS X fp.h header from being included; it defines
+ // pi as a constant, which creates a conflict with G3D
+#define __FP__
#else
#error Unknown platform
#endif
-// Default to compiling with SSE, but if you want to compile
-// without installing SP5.0 and the Processor Pack on Windows, compile with NO_SSE
-// defined (can be passed to the compiler command line with /D "NO_SSE")
-#if !defined(NO_SSE)
- #define SSE
-#endif
-
-#ifdef G3D_WIN32
-// Turn off warnings about deprecated C routines (TODO: revisit)
-# pragma warning (disable : 4996)
+// Detect 64-bit under various compilers
+#if (defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(_LP64))
+# define G3D_64BIT
+ #if defined(WIN32)
+ #include <intrin.h>
+ #endif
+#else
+# define G3D_32BIT
#endif
-// On g++, recognize cases where the -msse2 flag was not specified
-#if defined(SSE) && defined(__GNUC__) && ! defined (__SSE__)
-# undef SSE
+// Strongly encourage inlining on gcc
+#ifdef __GNUC__
+#define inline __inline__
#endif
-#if defined(__GNUC__)
-# if __STDC_VERSION__ < 199901
-# define restrict __restrict__
-# endif
-#endif
// Verify that the supported compilers are being used and that this is a known
// processor.
@@ -79,81 +83,46 @@
# ifndef __GNUC__
# error G3D only supports the gcc compiler on Linux.
# endif
-
-//# ifndef __i386__
-//# error G3D only supports x86 machines on Linux.
-//# endif
-
-# define G3D_DEPRECATED __attribute__((__deprecated__))
-
-# ifndef __cdecl
-# define __cdecl __attribute__((cdecl))
-# endif
-
-# ifndef __stdcall
-# define __stdcall __attribute__((stdcall))
-# endif
-
-# define G3D_CHECK_PRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 3)))
-# define G3D_CHECK_VPRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 0)))
-# define G3D_CHECK_PRINTF_ARGS __attribute__((__format__(__printf__, 1, 2)))
-# define G3D_CHECK_VPRINTF_ARGS __attribute__((__format__(__printf__, 1, 0)))
#endif
#ifdef G3D_OSX
- #ifndef __GNUC__
- #error G3D only supports the gcc compiler on OS X.
- #endif
+# ifndef __GNUC__
+# error G3D only supports the gcc compiler on OS X.
+# endif
- #if defined(__i386__)
- #define G3D_OSX_INTEL
- #elif defined(__PPC__)
- #define G3D_OSX_PPC
- #else
- #define G3D_OSX_UNKNOWN
- #endif
+# if defined(__i386__)
+# define G3D_OSX_INTEL
+# elif defined(__PPC__)
+# define G3D_OSX_PPC
+# else
+# define G3D_OSX_UNKNOWN
+# endif
-# ifndef __cdecl
-# define __cdecl __attribute__((cdecl))
-# endif
+#endif
-# ifndef __stdcall
-# define __stdcall __attribute__((stdcall))
-# endif
-# define G3D_DEPRECATED __attribute__((__deprecated__))
+#ifdef _MSC_VER
+// Microsoft Visual C++ 8.0 ("Express") = 1400
+// Microsoft Visual C++ 7.1 ("2003") _MSC_VER = 1310
+// Microsoft Visual C++ 7.0 ("2002") _MSC_VER = 1300
+// Microsoft Visual C++ 6.0 _MSC_VER = 1200
+// Microsoft Visual C++ 5.0 _MSC_VER = 1100
-# define G3D_CHECK_PRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 3)))
-# define G3D_CHECK_VPRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 0)))
-# define G3D_CHECK_PRINTF_ARGS __attribute__((__format__(__printf__, 1, 2)))
-# define G3D_CHECK_VPRINTF_ARGS __attribute__((__format__(__printf__, 1, 0)))
-#endif
+// Turn off warnings about deprecated C routines
+# pragma warning (disable : 4996)
-#ifdef G3D_WIN32
-// Microsoft Visual C++ 7.1 _MSC_VER = 1310
-// Microsoft Visual C++ 7.0 _MSC_VER = 1300
-// Microsoft Visual C++ 6.0 _MSC_VER = 1200
-// Microsoft Visual C++ 5.0 _MSC_VER = 1100
-
- // Old versions of MSVC (6.0 and previous) don't
- // support C99 for loop scoping rules. This fixes them.
-# if (_MSC_VER <= 1200)
- // This trick will generate a warning; disable the warning
-# pragma warning (disable : 4127)
-# define for if (false) {} else for
-# endif
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
-# if (_MSC_VER <= 1200)
-// Nothing we can do on VC6 for deprecated functions
-# define G3D_DEPRECATED
-# else
-# define G3D_DEPRECATED __declspec(deprecated)
-# endif
+/** @def G3D_DEPRECATED()
+ Creates deprecated warning. */
+# define G3D_DEPRECATED __declspec(deprecated)
// Prevent Winsock conflicts by hiding the winsock API
-#ifndef _WINSOCKAPI_
-# define _G3D_INTERNAL_HIDE_WINSOCK_
-# define _WINSOCKAPI_
+# ifndef _WINSOCKAPI_
+# define _G3D_INTERNAL_HIDE_WINSOCK_
+# define _WINSOCKAPI_
# endif
// Disable 'name too long for browse information' warning
@@ -161,21 +130,22 @@
// TODO: remove
# pragma warning (disable : 4244)
-# if defined(_MSC_VER) && (_MSC_VER <= 1200)
- // VC6 std:: has signed problems in it
-# pragma warning (disable : 4018)
-# endif
-
-# define ZLIB_WINAPI
-
-// Mingw32 defines restrict
-# ifndef G3D_MINGW32
-# define restrict
-# endif
+# define restrict
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_PRINTF_ARGS
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_VPRINTF_ARGS
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_PRINTF_METHOD_ARGS
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_VPRINTF_METHOD_ARGS
// On MSVC, we need to link against the multithreaded DLL version of
@@ -188,78 +158,174 @@
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_Compiler_Reference.asp
//
-#if 0 //ignore that for Trinity
// DLL runtime
#ifndef _DLL
- #define _DLL
+ #define _DLL
#endif
// Multithreaded runtime
#ifndef _MT
- #define _MT 1
+ #define _MT 1
#endif
+
// Ensure that we aren't forced into the static lib
#ifdef _STATIC_CPPLIB
- #undef _STATIC_CPPLIB
+ #undef _STATIC_CPPLIB
#endif
-#endif
#ifdef _DEBUG
- #pragma comment (linker, "/NODEFAULTLIB:libc.lib")
- #pragma comment (linker, "/NODEFAULTLIB:libcmt.lib")
- #pragma comment (linker, "/NODEFAULTLIB:msvcrt.lib")
- #pragma comment (linker, "/NODEFAULTLIB:libcd.lib")
- #pragma comment (linker, "/NODEFAULTLIB:msvcrtd.lib")
+ #pragma comment (linker, "/NODEFAULTLIB:LIBCMTD.LIB")
+ #pragma comment (linker, "/NODEFAULTLIB:LIBCPMTD.LIB")
+ #pragma comment (linker, "/NODEFAULTLIB:LIBCPD.LIB")
+ #pragma comment (linker, "/DEFAULTLIB:MSVCPRTD.LIB")
+ #pragma comment(linker, "/NODEFAULTLIB:LIBCD.LIB")
+ #pragma comment(linker, "/DEFAULTLIB:MSVCRTD.LIB")
#else
#pragma comment(linker, "/NODEFAULTLIB:LIBC.LIB")
- #pragma comment(linker, "/NODEFAULTLIB:msvcrt.lib")
- #pragma comment(linker, "/NODEFAULTLIB:libcd.lib")
- #pragma comment(linker, "/NODEFAULTLIB:libcmtd.lib")
- #pragma comment(linker, "/NODEFAULTLIB:msvcrtd.lib")
+ #pragma comment(linker, "/DEFAULTLIB:MSVCRT.LIB")
+ #pragma comment (linker, "/NODEFAULTLIB:LIBCMT.LIB")
+ #pragma comment (linker, "/NODEFAULTLIB:LIBCPMT.LIB")
+ #pragma comment(linker, "/NODEFAULTLIB:LIBCP.LIB")
+ #pragma comment (linker, "/DEFAULTLIB:MSVCPRT.LIB")
#endif
// Now set up external linking
- #ifdef _DEBUG
- // zlib and SDL were linked against the release MSVCRT; force
+# ifdef _DEBUG
+ // zlib was linked against the release MSVCRT; force
// the debug version.
- #pragma comment(linker, "/NODEFAULTLIB:MSVCRT.LIB")
-# endif
+# pragma comment(linker, "/NODEFAULTLIB:MSVCRT.LIB")
+# endif
+
-# ifndef WIN32_LEAN_AND_MEAN
+# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN 1
-# endif
+# endif
+
# define NOMINMAX 1
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0500
+# endif
# include <windows.h>
# undef WIN32_LEAN_AND_MEAN
# undef NOMINMAX
-#ifdef _G3D_INTERNAL_HIDE_WINSOCK_
-# undef _G3D_INTERNAL_HIDE_WINSOCK_
-# undef _WINSOCKAPI_
-#endif
+# ifdef _G3D_INTERNAL_HIDE_WINSOCK_
+# undef _G3D_INTERNAL_HIDE_WINSOCK_
+# undef _WINSOCKAPI_
+# endif
-#endif
-# if defined(_MSC_VER) && (_MSC_VER <= 1200)
- // VC6 std:: has signed/unsigned problems
-# pragma warning (disable : 4018)
+/** @def G3D_START_AT_MAIN()
+ Defines necessary wrapper around WinMain on Windows to allow transfer of execution to main(). */
+# define G3D_START_AT_MAIN()\
+int WINAPI G3D_WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw);\
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
+ return G3D_WinMain(hInst, hPrev, szCmdLine, sw);\
+}
+
+#else
+
+/** @def G3D_START_AT_MAIN()
+ Defines necessary wrapper around WinMain on Windows to allow transfer of execution to main(). */
+# define G3D_START_AT_MAIN()
+
+#endif // win32
+
+#ifdef __GNUC__
+
+# include <stdint.h>
+
+# if __STDC_VERSION__ < 199901
+# define restrict __restrict__
# endif
+/** @def G3D_DEPRECATED()
+ Creates deprecated warning. */
+# define G3D_DEPRECATED __attribute__((__deprecated__))
+
+// setup function calling conventions
+# if defined(__i386__) && ! defined(__x86_64__)
+
+# ifndef __cdecl
+# define __cdecl __attribute__((cdecl))
+# endif
+
+# ifndef __stdcall
+# define __stdcall __attribute__((stdcall))
+# endif
+
+# elif defined(__x86_64__)
+
+# ifndef __cdecl
+# define __cdecl
+# endif
+
+# ifndef __stdcall
+# define __stdcall
+# endif
+# endif // calling conventions
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
+# define G3D_CHECK_PRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 3)))
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
+# define G3D_CHECK_VPRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 0)))
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
+# define G3D_CHECK_PRINTF_ARGS __attribute__((__format__(__printf__, 1, 2)))
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
+# define G3D_CHECK_VPRINTF_ARGS __attribute__((__format__(__printf__, 1, 0)))
+#endif
+
+
/**
@def STR(expression)
Creates a string from the expression. Frequently used with G3D::Shader
to express shading programs inline.
- <CODE>STR(this becomes a string)<PRE> evaluates the same as <CODE>"this becomes a string"</CODE>
+ <CODE>STR(this becomes a string)\verbatim<PRE>\endverbatim evaluates the same as \verbatim<CODE>\endverbatim"this becomes a string"</CODE>
*/
#define STR(x) #x
-#undef G3D_DEPRECATED
-#define G3D_DEPRECATED
+/** @def PRAGMA(expression)
+ \#pragma may not appear inside a macro, so this uses the pragma operator
+ to create an equivalent statement.*/
+#ifdef _MSC_VER
+// Microsoft's version http://msdn.microsoft.com/en-us/library/d9x1s805.aspx
+# define PRAGMA(x) __pragma(x)
+#else
+// C99 standard http://www.delorie.com/gnu/docs/gcc/cpp_45.html
+# define PRAGMA(x) _Pragma(#x)
+#endif
-// Header guard
+/** @def G3D_BEGIN_PACKED_CLASS(byteAlign)
+ Switch to tight alignment
+ See G3D::Color3uint8 for an example.*/
+#ifdef _MSC_VER
+# define G3D_BEGIN_PACKED_CLASS(byteAlign) PRAGMA( pack(push, byteAlign) )
+#else
+# define G3D_BEGIN_PACKED_CLASS(byteAlign)
#endif
+/** @def G3D_END_PACKED_CLASS(byteAlign)
+ End switch to tight alignment
+ See G3D::Color3uint8 for an example.*/
+#ifdef _MSC_VER
+# define G3D_END_PACKED_CLASS(byteAlign) ; PRAGMA( pack(pop) )
+#elif defined(__GNUC__)
+# define G3D_END_PACKED_CLASS(byteAlign) __attribute((aligned(byteAlign))) ;
+#else
+# define G3D_END_PACKED_CLASS(byteAlign) ;
+#endif
+
+
+// Header guard
+#endif
diff --git a/dep/include/g3dlite/G3D/prompt.h b/dep/include/g3dlite/G3D/prompt.h
new file mode 100644
index 00000000000..c6df628099e
--- /dev/null
+++ b/dep/include/g3dlite/G3D/prompt.h
@@ -0,0 +1,67 @@
+/**
+ @file prompt.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Windows GUI code by Max McGuire
+
+ @created 2001-08-26
+ @edited 2006-08-13
+ */
+
+#ifndef G3D_PROMPT_H
+#define G3D_PROMPT_H
+
+#include "platform.h"
+#include <string>
+
+namespace G3D {
+
+/**
+ Prints a prompt to stdout and waits for user input. The return value is
+ the number of the user's choice (the first is 0, if there are no
+ choices, returns 0).
+
+ @param useGui Under Win32, use a GUI, not stdout prompt.
+ @param windowTitle The title for the prompt window
+ @param promptx The text string to prompt the user with
+ @param choice An array of strings that are the choices the user may make
+ @param numChoices The length of choice.
+
+ @cite Windows dialog interface by Max McGuire, mmcguire@ironlore.com
+ @cite Font setting code by Kurt Miller, kurt@flipcode.com
+ */
+int prompt(
+ const char* windowTitle,
+ const char* promptx,
+ const char** choice,
+ int numChoices,
+ bool useGui);
+
+/**
+ Prints a prompt and waits for user input. The return value is
+ the number of the user's choice (the first is 0, if there are no
+ choices, returns 0).
+ <P>Uses GUI under Win32, stdout prompt otherwise.
+ */
+inline int prompt(
+ const char* windowTitle,
+ const char* promptx,
+ const char** choice,
+ int numChoices) {
+
+ return prompt(windowTitle, promptx, choice, numChoices, true);
+}
+
+
+/**
+ Displays a GUI prompt with "Ok" as the only choice.
+ */
+void msgBox(
+ const std::string& message,
+ const std::string& title = "Message");
+
+
+}; // namespace
+
+#endif
+
diff --git a/dep/include/g3dlite/G3D/serialize.h b/dep/include/g3dlite/G3D/serialize.h
new file mode 100644
index 00000000000..2382c0ee0fd
--- /dev/null
+++ b/dep/include/g3dlite/G3D/serialize.h
@@ -0,0 +1,30 @@
+#ifndef G3D_SERIALIZE_H
+#define G3D_SERIALIZE_H
+
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Array.h"
+
+namespace G3D {
+
+
+template<typename T>
+void serialize(const Array<T>& array, BinaryOutput& b) {
+ b.writeInt32(array.size());
+ for (int i = 0; i < array.size(); ++i) {
+ serialize(array[i], b);
+ }
+}
+
+template<typename T>
+void deserialize(Array<T>& array, BinaryInput& b) {
+ int N = b.readInt32();
+ array.resize(N);
+ for (int i = 0; i < array.size(); ++i) {
+ deserialize(array[i], b);
+ }
+}
+
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/splinefunc.h b/dep/include/g3dlite/G3D/splinefunc.h
new file mode 100644
index 00000000000..3f3a018c292
--- /dev/null
+++ b/dep/include/g3dlite/G3D/splinefunc.h
@@ -0,0 +1,118 @@
+/**
+ @file spline.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2004-07-25
+ @edited 2007-05-05
+ */
+
+#ifndef G3D_SPLINEFUNC_H
+#define G3D_SPLINEFUNC_H
+
+#include "G3D/platform.h"
+#include "G3D/debug.h"
+#include "G3D/Array.h"
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+/**
+ Interpolates a property according to a piecewise linear spline. This provides
+ C0 continuity but the derivatives are not smooth.
+ <P>
+ Example:
+ <CODE>
+ const double times[] = {MIDNIGHT, SUNRISE - HOUR, SUNRISE, SUNRISE + sunRiseAndSetTime / 4, SUNRISE + sunRiseAndSetTime, SUNSET - sunRiseAndSetTime, SUNSET - sunRiseAndSetTime / 2, SUNSET, SUNSET + HOUR/2, DAY};
+ const Color3 color[] = {Color3(0, .0, .1), Color3(0, .0, .1), Color3::black(), Color3::black(), Color3::white() * .25, Color3::white() * .25, Color3(.5, .2, .2), Color3(.05, .05, .1), Color3(0, .0, .1), Color3(0, .0, .1)};
+ ambient = linearSpline(time, times, color, 10);
+ </CODE>
+
+ See also G3D::Spline
+
+ @param x The spline is a function of x; this is the sample to choose.
+ @param controlX controlX[i], controlY[i] is a control points. It is assumed
+ that controlX are strictly increasing. XType must support
+ the "<" operator and a subtraction operator that returns
+ a number.
+ @param controlY YType must support multiplication and addition.
+ @param numControl The number of control points.
+ */
+template<class XType, class YType>
+YType linearSpline(double x, const XType* controlX, const YType* controlY, int numControl) {
+ debugAssert(numControl >= 1);
+
+ // Off the beginning
+ if ((numControl == 1) || (x < controlX[0])) {
+ return controlY[0];
+ }
+
+ for (int i = 1; i < numControl; ++i) {
+ if (x < controlX[i]) {
+ const double alpha = (double)(controlX[i] - x) / (controlX[i] - controlX[i - 1]);
+ return controlY[i] * (1 - alpha) + controlY[i - 1] * alpha;
+ }
+ }
+
+ // Off the end
+ return controlY[numControl - 1];
+}
+
+
+ /** See also G3D::Spline*/
+template<class YType> YType cyclicCatmullRomSpline(
+ double t,
+ const YType* controlY,
+ int numPoints) {
+
+ debugAssert(numPoints >= 3);
+
+ t = wrap(t, numPoints);
+
+ // Find the indices of adjacent control points
+ int i = iFloor(t);
+
+ // Compute the distance from the control point
+ t = t - i;
+
+ // Shift back one point for correct indexing
+ i += numPoints - 1;
+
+ // Pick up four control points
+ const YType& P0 = controlY[(i + 0) % numPoints];
+ const YType& P1 = controlY[(i + 1) % numPoints];
+ const YType& P2 = controlY[(i + 2) % numPoints];
+ const YType& P3 = controlY[(i + 3) % numPoints];
+
+ return 0.5 * ((2 * P1) +
+ (-P0 + P2) * t +
+ (2*P0 - 5*P1 + 4*P2 - P3) * t*t +
+ (-P0 + 3*P1- 3*P2 + P3) * t*t*t);
+}
+
+/**
+ A cubic spline with regularly spaced
+ control points. The spline interpolates
+ the control points. The spline
+ will wrap from the last point back to the first.
+
+ The t parameter is on the range [0, controlY.size()],
+ where integers correspond to control points exactly.
+
+ See also G3D::Spline
+
+ @cite http://www.mvps.org/directx/articles/catmull/
+*/
+template<class YType> YType cyclicCatmullRomSpline(
+ double t,
+ const Array<YType>& controlY) {
+
+ int numPoints = controlY.size();
+ return cyclicCatmullRomSpline(t, controlY.getCArray(), numPoints);
+}
+
+}
+
+#endif
+
+
diff --git a/dep/include/g3dlite/G3D/stringutils.h b/dep/include/g3dlite/G3D/stringutils.h
index 59449313bf5..e15a757a7a6 100644
--- a/dep/include/g3dlite/G3D/stringutils.h
+++ b/dep/include/g3dlite/G3D/stringutils.h
@@ -1,10 +1,10 @@
/**
@file stringutils.h
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@author 2000-09-09
- @edited 2002-11-30
+ @edited 2008-08-05
*/
#ifndef G3D_STRINGUTILS_H
@@ -12,12 +12,22 @@
#include "G3D/platform.h"
#include "G3D/Array.h"
-#include <string>
+#include <cstring>
namespace G3D {
extern const char* NEWLINE;
+/** Separates a comma-separated line, properly escaping commas within
+ double quotes (") and super quotes ("""). This matches Microsoft Excel's
+ CSV output.
+
+ \param stripQuotes If true, strips leading and trailing " and """
+
+ \sa G3D::stringSplit, G3D::TextInput, G3D::readWholeFile
+*/
+void parseCommaSeparated(const std::string s, Array<std::string>& array, bool stripQuotes = true);
+
/**
Returns true if the test string begins with the pattern string.
*/
@@ -91,36 +101,36 @@ std::string trimWhitespace(
/** These standard C functions are renamed for clarity/naming
conventions and to return bool, not int.
*/
-inline bool isWhiteSpace(const char c) {
+inline bool isWhiteSpace(const unsigned char c) {
return isspace(c) != 0;
}
/** These standard C functions are renamed for clarity/naming
conventions and to return bool, not int.
*/
-inline bool isNewline(const char c) {
+inline bool isNewline(const unsigned char c) {
return (c == '\n') || (c == '\r');
}
/** These standard C functions are renamed for clarity/naming
conventions and to return bool, not int.
*/
-inline bool isDigit(const char c) {
+inline bool isDigit(const unsigned char c) {
return isdigit(c) != 0;
}
/** These standard C functions are renamed for clarity/naming
conventions and to return bool, not int.
*/
-inline bool isLetter(const char c) {
+inline bool isLetter(const unsigned char c) {
return isalpha(c) != 0;
}
-inline bool isSlash(const char c) {
+inline bool isSlash(const unsigned char c) {
return (c == '\\') || (c == '/');
}
-inline bool isQuote(const char c) {
+inline bool isQuote(const unsigned char c) {
return (c == '\'') || (c == '\"');
}
@@ -128,4 +138,3 @@ inline bool isQuote(const char c) {
#endif
-
diff --git a/dep/include/g3dlite/G3D/uint128.h b/dep/include/g3dlite/G3D/uint128.h
new file mode 100644
index 00000000000..da1af3ec272
--- /dev/null
+++ b/dep/include/g3dlite/G3D/uint128.h
@@ -0,0 +1,51 @@
+/**
+ @file uint128.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @author Kyle Whitson
+
+ @created 2008-07-17
+ @edited 2008-07-17
+ */
+
+#ifndef G3D_UINT128_H
+#define G3D_UINT128_H
+
+#include "G3D/g3dmath.h"
+
+namespace G3D {
+
+/** Limited functionality 128-bit unsigned integer. This is primarily to support FNV hashing and other
+ cryptography applications. See the GMP library for high-precision C++ math support. */
+class uint128 {
+public:
+
+ G3D::uint64 hi;
+ G3D::uint64 lo;
+
+ uint128(const uint64& lo);
+
+ uint128(const uint64& hi, const uint64& lo);
+
+ uint128& operator+=(const uint128& x);
+
+ uint128& operator*=(const uint128& x);
+
+ uint128& operator^=(const uint128& x);
+
+ uint128& operator&=(const uint128& x);
+
+ uint128& operator|=(const uint128& x);
+
+ bool operator==(const uint128& x);
+
+ uint128& operator>>=(const int x);
+
+ uint128& operator<<=(const int x);
+
+ uint128 operator&(const uint128& x);
+
+};
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/units.h b/dep/include/g3dlite/G3D/units.h
new file mode 100644
index 00000000000..2e30304dc62
--- /dev/null
+++ b/dep/include/g3dlite/G3D/units.h
@@ -0,0 +1,126 @@
+/**
+ @file units.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-08-21
+ @edited 2009-08-21
+ */
+#ifndef G3D_units_h
+#define G3D_units_h
+
+#include "G3D/platform.h"
+
+namespace G3D {
+/** Use <code>using namespace G3D::units;</code> to include all units
+ into your program. The units system is specifically designed not to
+ be general but to support commonly used units efficiently and
+ clearly. See http://en.wikipedia.org/wiki/SI_prefix for interesting facts
+ about SI/metric units and full definitions.*/
+namespace units {
+
+/** 1e-9 m */
+inline float nanometers() {
+ return 1e-9f;
+}
+
+/** 1e-6 m */
+inline float micrometers() {
+ return 1e-6f;
+}
+
+/** 0.001 m */
+inline float millimeters() {
+ return 0.001f;
+}
+
+/** 0.01 m */
+inline float centimeters() {
+ return 0.01f;
+}
+
+/** SI base unit of distance measure. */
+inline float meters() {
+ return 1.0f;
+}
+
+/** 1000 m */
+inline float kilometers() {
+ return 100.0f;
+}
+
+/** 0.0254 m */
+inline float inches() {
+ return 0.0254f;
+}
+
+/** 0.3048 m */
+inline float feet() {
+ return 0.3048f;
+}
+
+/** 0.9144 m */
+inline float yards() {
+ return 0.9144f;
+}
+
+/** 1609.344 m */
+inline float miles() {
+ return 1609.344f;
+}
+
+/////////////////////////////////////////////////////////////
+
+/** SI base unit of angular measure. */
+inline float radians() {
+ return 1.0f;
+}
+
+/** pi/180 */
+inline float degrees() {
+ return 0.0174532925f;
+}
+
+//////////////////////////////////////////////////////////////
+
+/** 1e-9 s */
+inline float nanoseconds() {
+ return 1e-9f;
+}
+
+/** 1e-3 s */
+inline float milliseconds() {
+ return 1e-3f;
+}
+
+/** Base unit of time */
+inline float seconds() {
+ return 1.0;
+}
+
+/** 60 s */
+inline float minutes() {
+ return 60.0f;
+}
+
+/** 3600 s */
+inline float hours() {
+ return 3600.0f;
+}
+
+/** 86400 s */
+inline float days() {
+ return 86400.0f;
+}
+
+/** 31556926 s */
+inline float years() {
+ return 31556926.0f;
+}
+
+///////////////////////////////////////////
+
+}
+}
+
+#endif
diff --git a/dep/include/g3dlite/G3D/vectorMath.h b/dep/include/g3dlite/G3D/vectorMath.h
new file mode 100644
index 00000000000..ac6d2b32e9d
--- /dev/null
+++ b/dep/include/g3dlite/G3D/vectorMath.h
@@ -0,0 +1,235 @@
+/**
+ @file vectorMath.h
+
+ Function aliases for popular vector methods.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created: 2001-06-02
+ @edited: 2004-02-02
+ Copyright 2000-2004, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_VECTORMATH_H
+#define G3D_VECTORMATH_H
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Vector2.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector4.h"
+#include "G3D/Matrix3.h"
+#include "G3D/Matrix4.h"
+#include "G3D/Color1.h"
+#include "G3D/Color3.h"
+#include "G3D/Color4.h"
+
+
+namespace G3D {
+
+
+inline Matrix4 mul(const Matrix4& a, const Matrix4& b) {
+ return a * b;
+}
+
+inline Vector4 mul(const Matrix4& m, const Vector4& v) {
+ return m * v;
+}
+
+inline Vector3 mul(const Matrix3& m, const Vector3& v) {
+ return m * v;
+}
+
+inline Matrix3 mul(const Matrix3& a, const Matrix3& b) {
+ return a * b;
+}
+
+inline float dot(const Vector2& a, const Vector2& b) {
+ return a.dot(b);
+}
+
+inline float dot(const Vector3& a, const Vector3& b) {
+ return a.dot(b);
+}
+
+inline float dot(const Vector4& a, const Vector4& b) {
+ return a.dot(b);
+}
+
+inline Vector2 normalize(const Vector2& v) {
+ return v / v.length();
+}
+
+inline Vector3 normalize(const Vector3& v) {
+ return v / v.magnitude();
+}
+
+inline Vector4 normalize(const Vector4& v) {
+ return v / v.length();
+}
+
+inline Vector2 abs(const Vector2& v) {
+ return Vector2(::fabsf(v.x), ::fabsf(v.y));
+}
+
+inline Vector3 abs(const Vector3& v) {
+ return Vector3(::fabsf(v.x), ::fabsf(v.y), ::fabsf(v.z));
+}
+
+inline Vector4 abs(const Vector4& v) {
+ return Vector4(::fabsf(v.x), ::fabsf(v.y), ::fabsf(v.z), ::fabsf(v.w));
+}
+
+inline bool all(const Vector2& v) {
+ return (v.x != 0) && (v.y != 0);
+}
+
+inline bool all(const Vector3& v) {
+ return (v.x != 0) && (v.y != 0) && (v.z != 0);
+}
+
+inline bool all(const Vector4& v) {
+ return (v.x != 0) && (v.y != 0) && (v.z != 0) && (v.w != 0);
+}
+
+inline bool any(const Vector2& v) {
+ return (v.x != 0) || (v.y != 0);
+}
+
+inline bool any(const Vector3& v) {
+ return (v.x != 0) || (v.y != 0) || (v.z != 0);
+}
+
+inline bool any(const Vector4& v) {
+ return (v.x != 0) || (v.y != 0) || (v.z != 0) || (v.w != 0);
+}
+
+inline Vector2 clamp(const Vector2& v, const Vector2& a, const Vector2& b) {
+ return v.clamp(a, b);
+}
+
+inline Vector3 clamp(const Vector3& v, const Vector3& a, const Vector3& b) {
+ return v.clamp(a, b);
+}
+
+inline Vector4 clamp(const Vector4& v, const Vector4& a, const Vector4& b) {
+ return v.clamp(a, b);
+}
+
+inline Vector2 lerp(const Vector2& v1, const Vector2& v2, float f) {
+ return v1.lerp(v2, f);
+}
+
+inline Vector3 lerp(const Vector3& v1, const Vector3& v2, float f) {
+ return v1.lerp(v2, f);
+}
+
+inline Vector4 lerp(const Vector4& v1, const Vector4& v2, float f) {
+ return v1.lerp(v2, f);
+}
+
+inline Color1 lerp(const Color1& v1, const Color1& v2, float f) {
+ return v1.lerp(v2, f);
+}
+
+inline Color3 lerp(const Color3& v1, const Color3& v2, float f) {
+ return v1.lerp(v2, f);
+}
+
+inline Color4 lerp(const Color4& v1, const Color4& v2, float f) {
+ return v1.lerp(v2, f);
+}
+
+inline Vector3 cross(const Vector3& v1, const Vector3& v2) {
+ return v1.cross(v2);
+}
+
+inline double determinant(const Matrix3& m) {
+ return m.determinant();
+}
+
+inline double determinant(const Matrix4& m) {
+ return m.determinant();
+}
+
+inline Vector2 min(const Vector2& v1, const Vector2& v2) {
+ return v1.min(v2);
+}
+
+inline Vector3 min(const Vector3& v1, const Vector3& v2) {
+ return v1.min(v2);
+}
+
+inline Vector4 min(const Vector4& v1, const Vector4& v2) {
+ return v1.min(v2);
+}
+
+inline Color3 min(const Color3& v1, const Color3& v2) {
+ return v1.min(v2);
+}
+
+inline Color4 min(const Color4& v1, const Color4& v2) {
+ return v1.min(v2);
+}
+
+inline Vector2 max(const Vector2& v1, const Vector2& v2) {
+ return v1.max(v2);
+}
+
+inline Vector3 max(const Vector3& v1, const Vector3& v2) {
+ return v1.max(v2);
+}
+
+inline Vector4 max(const Vector4& v1, const Vector4& v2) {
+ return v1.max(v2);
+}
+
+inline Color3 max(const Color3& v1, const Color3& v2) {
+ return v1.max(v2);
+}
+
+inline Color4 max(const Color4& v1, const Color4& v2) {
+ return v1.max(v2);
+}
+
+inline Vector2 sign(const Vector2& v) {
+ return Vector2((float)sign(v.x), (float)sign(v.y));
+}
+
+inline Vector3 sign(const Vector3& v) {
+ return Vector3((float)sign(v.x), (float)sign(v.y), (float)sign(v.z));
+}
+
+inline Vector4 sign(const Vector4& v) {
+ return Vector4((float)sign(v.x), (float)sign(v.y), (float)sign(v.z), (float)sign(v.w));
+}
+
+inline float length(float v) {
+ return ::fabsf(v);
+}
+
+inline float length(const Vector2& v) {
+ return v.length();
+}
+
+inline float length(const Vector3& v) {
+ return v.magnitude();
+}
+
+inline float length(const Vector4& v) {
+ return v.length();
+}
+
+/**
+ Computes the log of each component. Useful for
+ inverting the monitor gamma function or simulating
+ perceptual response.
+ */
+inline Color3 log(const Color3& c) {
+ return Color3(::logf(c.r), ::logf(c.g), ::logf(c.b));
+}
+
+}
+
+#endif
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/blocksort.c b/dep/src/bzip2/blocksort.c
index 906124b97e6..bd2dec157fa 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/blocksort.c
+++ b/dep/src/bzip2/blocksort.c
@@ -4,66 +4,19 @@
/*--- blocksort.c ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
-
- To get some idea how the block sorting algorithms in this file
- work, read my paper
- On the Performance of BWT Sorting Algorithms
- in Proceedings of the IEEE Data Compression Conference 2000,
- Snowbird, Utah, USA, 27-30 March 2000. The main sort in this
- file implements the algorithm called cache in the paper.
---*/
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
#include "bzlib_private.h"
@@ -155,7 +108,7 @@ void fallbackQSort3 ( UInt32* fmap,
while (sp > 0) {
- AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
+ AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
fpop ( lo, hi );
if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
@@ -321,7 +274,7 @@ void fallbackSort ( UInt32* fmap,
r = -1;
while (1) {
- /*-- find the next non-singleton bucket --*/
+ /*-- find the next non-singleton bucket --*/
k = r + 1;
while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
if (ISSET_BH(k)) {
@@ -690,7 +643,7 @@ void mainQSort3 ( UInt32* ptr,
while (sp > 0) {
- AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
+ AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
mpop ( lo, hi, d );
if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.c b/dep/src/bzip2/bzlib.c
index 3d405f9322a..ef86c91e695 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib.c
+++ b/dep/src/bzip2/bzlib.c
@@ -4,76 +4,30 @@
/*--- bzlib.c ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
-/*--
- CHANGES
- ~~~~~~~
- 0.9.0 -- original version.
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
- 0.9.0a/b -- no changes in this file.
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
- 0.9.0c
- * made zero-length BZ_FLUSH work correctly in bzCompress().
- * fixed bzWrite/bzRead to ignore zero-length requests.
- * fixed bzread to correctly handle read requests after EOF.
- * wrong parameter order in call to bzDecompressInit in
- bzBuffToBuffDecompress. Fixed.
---*/
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+/* CHANGES
+ 0.9.0 -- original version.
+ 0.9.0a/b -- no changes in this file.
+ 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress().
+ fixed bzWrite/bzRead to ignore zero-length requests.
+ fixed bzread to correctly handle read requests after EOF.
+ wrong parameter order in call to bzDecompressInit in
+ bzBuffToBuffDecompress. Fixed.
+*/
-#define _CRT_SECURE_NO_DEPRECATE
#include "bzlib_private.h"
@@ -94,7 +48,7 @@ void BZ2_bz__AssertH__fail ( int errcode )
"component, you should also report this bug to the author(s)\n"
"of that program. Please make an effort to report this bug;\n"
"timely and accurate bug reports eventually lead to higher\n"
- "quality software. Thanks. Julian Seward, 15 February 2005.\n\n",
+ "quality software. Thanks. Julian Seward, 10 December 2007.\n\n",
errcode,
BZ2_bzlibVersion()
);
@@ -471,7 +425,7 @@ int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
}
else
- if (action == BZ_FLUSH) {
+ if (action == BZ_FLUSH) {
s->avail_in_expect = strm->avail_in;
s->mode = BZ_M_FLUSHING;
goto preswitch;
@@ -644,6 +598,7 @@ Bool unRLE_obuf_to_output_FAST ( DState* s )
UInt32 c_tPos = s->tPos;
char* cs_next_out = s->strm->next_out;
unsigned int cs_avail_out = s->strm->avail_out;
+ Int32 ro_blockSize100k = s->blockSize100k;
/* end restore */
UInt32 avail_out_INIT = cs_avail_out;
@@ -1395,8 +1350,7 @@ int BZ_API(BZ2_bzBuffToBuffDecompress)
/*---------------------------------------------------*/
/*--
- Code contributed by Yoshioka Tsuneo
- (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
@@ -1407,7 +1361,7 @@ int BZ_API(BZ2_bzBuffToBuffDecompress)
/*---------------------------------------------------*/
/*--
- return version like "0.9.0c".
+ return version like "0.9.5d, 4-Sept-1999".
--*/
const char * BZ_API(BZ2_bzlibVersion)(void)
{
@@ -1421,7 +1375,7 @@ const char * BZ_API(BZ2_bzlibVersion)(void)
#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
# include <fcntl.h>
# include <io.h>
-# define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY)
+# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
@@ -1474,7 +1428,7 @@ BZFILE * bzopen_or_bzdopen
#ifdef BZ_STRICT_ANSI
fp = NULL;
#else
- fp = _fdopen(fd,mode2);
+ fp = fdopen(fd,mode2);
#endif
}
if (fp == NULL) return NULL;
@@ -1560,9 +1514,10 @@ int BZ_API(BZ2_bzflush) (BZFILE *b)
void BZ_API(BZ2_bzclose) (BZFILE* b)
{
int bzerr;
- FILE *fp = ((bzFile *)b)->handle;
+ FILE *fp;
if (b==NULL) {return;}
+ fp = ((bzFile *)b)->handle;
if(((bzFile*)b)->writing){
BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
if(bzerr != BZ_OK){
@@ -1581,7 +1536,7 @@ void BZ_API(BZ2_bzclose) (BZFILE* b)
/*--
return last error code
--*/
-static char *bzerrorstrings[] = {
+static const char *bzerrorstrings[] = {
"OK"
,"SEQUENCE_ERROR"
,"PARAM_ERROR"
diff --git a/dep/src/bzip2/bzlib.h b/dep/src/bzip2/bzlib.h
new file mode 100644
index 00000000000..c5b75d6d8ff
--- /dev/null
+++ b/dep/src/bzip2/bzlib.h
@@ -0,0 +1,282 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library. ---*/
+/*--- bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN 0
+#define BZ_FLUSH 1
+#define BZ_FINISH 2
+
+#define BZ_OK 0
+#define BZ_RUN_OK 1
+#define BZ_FLUSH_OK 2
+#define BZ_FINISH_OK 3
+#define BZ_STREAM_END 4
+#define BZ_SEQUENCE_ERROR (-1)
+#define BZ_PARAM_ERROR (-2)
+#define BZ_MEM_ERROR (-3)
+#define BZ_DATA_ERROR (-4)
+#define BZ_DATA_ERROR_MAGIC (-5)
+#define BZ_IO_ERROR (-6)
+#define BZ_UNEXPECTED_EOF (-7)
+#define BZ_OUTBUFF_FULL (-8)
+#define BZ_CONFIG_ERROR (-9)
+
+typedef
+ struct {
+ char *next_in;
+ unsigned int avail_in;
+ unsigned int total_in_lo32;
+ unsigned int total_in_hi32;
+
+ char *next_out;
+ unsigned int avail_out;
+ unsigned int total_out_lo32;
+ unsigned int total_out_hi32;
+
+ void *state;
+
+ void *(*bzalloc)(void *,int,int);
+ void (*bzfree)(void *,void *);
+ void *opaque;
+ }
+ bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include <stdio.h>
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# ifdef small
+ /* windows.h define small to char */
+# undef small
+# endif
+# ifdef BZ_EXPORT
+# define BZ_API(func) WINAPI func
+# define BZ_EXTERN extern
+# else
+ /* import windows dll dynamically */
+# define BZ_API(func) (WINAPI * func)
+# define BZ_EXTERN
+# endif
+#else
+# define BZ_API(func) func
+# define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
+ bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) (
+ bz_stream* strm,
+ int action
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
+ bz_stream *strm,
+ int verbosity,
+ int small
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
+ bz_stream *strm
+ );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
+ int* bzerror,
+ FILE* f,
+ int verbosity,
+ int small,
+ void* unused,
+ int nUnused
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
+ int* bzerror,
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
+ int* bzerror,
+ BZFILE* b,
+ void** unused,
+ int* nUnused
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
+ int* bzerror,
+ FILE* f,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32
+ );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity
+ );
+
+
+/*--
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+ to support better zlib compatibility.
+ This code is not _officially_ part of libbzip2 (yet);
+ I haven't tested it, documented it, or considered the
+ threading-safeness of it.
+ If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+ void
+ );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+ const char *path,
+ const char *mode
+ );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+ int fd,
+ const char *mode
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+ BZFILE* b
+ );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+ BZFILE *b,
+ int *errnum
+ );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib_private.h b/dep/src/bzip2/bzlib_private.h
index ca76fe62b3b..23427879b18 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/bzlib_private.h
+++ b/dep/src/bzip2/bzlib_private.h
@@ -4,59 +4,19 @@
/*--- bzlib_private.h ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
#ifndef _BZLIB_PRIVATE_H
@@ -76,7 +36,7 @@
/*-- General stuff. --*/
-#define BZ_VERSION "1.0.3, 15-Feb-2005"
+#define BZ_VERSION "1.0.5, 10-Dec-2007"
typedef char Char;
typedef unsigned char Bool;
@@ -94,9 +54,11 @@ typedef unsigned short UInt16;
#endif
#ifndef BZ_NO_STDIO
+
extern void BZ2_bz__AssertH__fail ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
#if BZ_DEBUG
#define AssertD(cond,msg) \
{ if (!(cond)) { \
@@ -107,6 +69,7 @@ extern void BZ2_bz__AssertH__fail ( int errcode );
#else
#define AssertD(cond,msg) /* */
#endif
+
#define VPrintf0(zf) \
fprintf(stderr,zf)
#define VPrintf1(zf,za1) \
@@ -119,17 +82,20 @@ extern void BZ2_bz__AssertH__fail ( int errcode );
fprintf(stderr,zf,za1,za2,za3,za4)
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
#else
+
extern void bz_internal_error ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) bz_internal_error ( errcode ); }
-#define AssertD(cond,msg) /* */
-#define VPrintf0(zf) /* */
-#define VPrintf1(zf,za1) /* */
-#define VPrintf2(zf,za1,za2) /* */
-#define VPrintf3(zf,za1,za2,za3) /* */
-#define VPrintf4(zf,za1,za2,za3,za4) /* */
-#define VPrintf5(zf,za1,za2,za3,za4,za5) /* */
+#define AssertD(cond,msg) do { } while (0)
+#define VPrintf0(zf) do { } while (0)
+#define VPrintf1(zf,za1) do { } while (0)
+#define VPrintf2(zf,za1,za2) do { } while (0)
+#define VPrintf3(zf,za1,za2,za3) do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
#endif
@@ -476,11 +442,15 @@ typedef
/*-- Macros for decompression. --*/
#define BZ_GET_FAST(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
s->tPos = s->tt[s->tPos]; \
cccc = (UChar)(s->tPos & 0xff); \
s->tPos >>= 8;
#define BZ_GET_FAST_C(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
c_tPos = c_tt[c_tPos]; \
cccc = (UChar)(c_tPos & 0xff); \
c_tPos >>= 8;
@@ -503,8 +473,10 @@ typedef
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
#define BZ_GET_SMALL(cccc) \
- cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
- s->tPos = GET_LL(s->tPos);
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+ cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
+ s->tPos = GET_LL(s->tPos);
/*-- externs for decompression. --*/
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/compress.c b/dep/src/bzip2/compress.c
index 156056fb376..8c80a079700 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/compress.c
+++ b/dep/src/bzip2/compress.c
@@ -4,71 +4,27 @@
/*--- compress.c ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-/*--
- CHANGES
- ~~~~~~~
- 0.9.0 -- original version.
-
- 0.9.0a/b -- no changes in this file.
-
- 0.9.0c
- * changed setting of nGroups in sendMTFValues() so as to
- do a bit better on small files
---*/
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+/* CHANGES
+ 0.9.0 -- original version.
+ 0.9.0a/b -- no changes in this file.
+ 0.9.0c -- changed setting of nGroups in sendMTFValues()
+ so as to do a bit better on small files
+*/
#include "bzlib_private.h"
@@ -373,14 +329,14 @@ void sendMTFValues ( EState* s )
/*---
Set up an auxiliary length table which is used to fast-track
- the common case (nGroups == 6).
+ the common case (nGroups == 6).
---*/
if (nGroups == 6) {
for (v = 0; v < alphaSize; v++) {
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
- }
+ }
}
nSelectors = 0;
@@ -429,14 +385,14 @@ void sendMTFValues ( EState* s )
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
} else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++) {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++) {
UInt16 icv = mtfv[i];
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
}
}
-
- /*--
+
+ /*--
Find the coding table which is best for this group,
and record its identity in the selector table.
--*/
@@ -470,7 +426,7 @@ void sendMTFValues ( EState* s )
# undef BZ_ITUR
} else {
- /*--- slow version which correctly handles all situations ---*/
+ /*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++)
s->rfreq[bt][ mtfv[i] ]++;
}
@@ -623,14 +579,15 @@ void sendMTFValues ( EState* s )
# undef BZ_ITAH
} else {
- /*--- slow version which correctly handles all situations ---*/
+ /*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
- bsW ( s,
+ bsW ( s,
s->len [s->selector[selCtr]] [mtfv[i]],
s->code [s->selector[selCtr]] [mtfv[i]] );
}
}
+
gs = ge+1;
selCtr++;
}
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/crctable.c b/dep/src/bzip2/crctable.c
index b6dadfc62f2..215687b2c05 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/crctable.c
+++ b/dep/src/bzip2/crctable.c
@@ -4,59 +4,19 @@
/*--- crctable.c ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
#include "bzlib_private.h"
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/decompress.c b/dep/src/bzip2/decompress.c
index 81c3d2cc3f4..bba5e0fa36d 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/decompress.c
+++ b/dep/src/bzip2/decompress.c
@@ -4,59 +4,19 @@
/*--- decompress.c ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
#include "bzlib_private.h"
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/huffman.c b/dep/src/bzip2/huffman.c
index 5bf190be9a1..87e79e38af0 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/huffman.c
+++ b/dep/src/bzip2/huffman.c
@@ -4,59 +4,19 @@
/*--- huffman.c ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2005 Julian R Seward. 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. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
#include "bzlib_private.h"
diff --git a/contrib/vmap_extractor_v2/stormlib/bzip2/randtable.c b/dep/src/bzip2/randtable.c
index 940462d693d..068b76367bc 100644
--- a/contrib/vmap_extractor_v2/stormlib/bzip2/randtable.c
+++ b/dep/src/bzip2/randtable.c
@@ -4,59 +4,19 @@
/*--- randtable.c ---*/
/*-------------------------------------------------------------*/
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
- Copyright (C) 1996-2005 Julian R Seward. All rights reserved.
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. 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.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
-
- Julian Seward, Cambridge, UK.
- jseward@bzip.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
#include "bzlib_private.h"
diff --git a/dep/src/g3dlite/AABox.cpp b/dep/src/g3dlite/AABox.cpp
index 2279e9a51f0..035497aa3c4 100644
--- a/dep/src/g3dlite/AABox.cpp
+++ b/dep/src/g3dlite/AABox.cpp
@@ -1,30 +1,61 @@
/**
@file AABox.cpp
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2004-01-10
@edited 2006-01-11
*/
#include "G3D/platform.h"
-# if defined(_MSC_VER) && (_MSC_VER <= 1200)
- // VC6 std:: has signed/unsigned problems
-# pragma warning (disable : 4018)
-# endif
-
-#include <assert.h>
#include "G3D/AABox.h"
#include "G3D/Box.h"
#include "G3D/Plane.h"
#include "G3D/Sphere.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
namespace G3D {
-Box AABox::toBox() const {
- return Box(lo, hi);
+const AABox& AABox::maxFinite() {
+ static const AABox b = AABox(Vector3::minFinite(),
+ Vector3::maxFinite());
+ return b;
+}
+
+
+const AABox& AABox::large() {
+ static const AABox b = AABox(Vector3::minFinite() * 0.5f,
+ Vector3::maxFinite() * 0.5f);
+ return b;
+}
+
+
+const AABox& AABox::inf() {
+ static const AABox b = AABox(-Vector3::inf(), Vector3::inf());
+ return b;
+}
+
+
+const AABox& AABox::zero() {
+ static const AABox b = AABox(Vector3::zero(), Vector3::zero());
+ return b;
+}
+
+
+void AABox::serialize(class BinaryOutput& b) const {
+ b.writeVector3(lo);
+ b.writeVector3(hi);
+}
+
+
+void AABox::deserialize(class BinaryInput& b) {
+ lo = b.readVector3();
+ hi = b.readVector3();
}
+
void AABox::split(const Vector3::Axis& axis, float location, AABox& low, AABox& high) const {
// Low, medium, and high along the chosen axis
float L = G3D::min(location, lo[axis]);
@@ -41,51 +72,52 @@ void AABox::split(const Vector3::Axis& axis, float location, AABox& low, AABox&
high.hi[axis] = H;
}
-#if 0
+
Vector3 AABox::randomSurfacePoint() const {
Vector3 extent = hi - lo;
float aXY = extent.x * extent.y;
float aYZ = extent.y * extent.z;
float aZX = extent.z * extent.x;
- float r = (float)random(0, aXY + aYZ + aZX);
+ float r = (float)uniformRandom(0.0f, aXY + aYZ + aZX);
// Choose evenly between positive and negative face planes
- float d = ((float)random(0, 1) < 0.5f) ? 0.0f : 1.0f;
+ float d = ((float)uniformRandom(0, 1) < 0.5f) ? 0.0f : 1.0f;
// The probability of choosing a given face is proportional to
// its area.
if (r < aXY) {
- return
- lo +
+ return
+ lo +
Vector3(
- (float)random(0, extent.x),
- (float)random(0, extent.y),
+ (float)uniformRandom(0.0f, extent.x),
+ (float)uniformRandom(0.0f, extent.y),
d * extent.z);
} else if (r < aYZ) {
- return
- lo +
+ return
+ lo +
Vector3(
d * extent.x,
- (float)random(0, extent.y),
- (float)random(0, extent.z));
+ (float)uniformRandom(0, extent.y),
+ (float)uniformRandom(0, extent.z));
} else {
- return
- lo +
+ return
+ lo +
Vector3(
- (float)random(0, extent.x),
+ (float)uniformRandom(0, extent.x),
d * extent.y,
- (float)random(0, extent.z));
+ (float)uniformRandom(0, extent.z));
}
}
+
Vector3 AABox::randomInteriorPoint() const {
return Vector3(
- (float)random(lo.x, hi.x),
- (float)random(lo.y, hi.y),
- (float)random(lo.z, hi.z));
+ (float)uniformRandom(lo.x, hi.x),
+ (float)uniformRandom(lo.y, hi.y),
+ (float)uniformRandom(lo.z, hi.z));
}
-#endif
+
bool AABox::intersects(const AABox& other) const {
// Must be overlap along all three axes.
@@ -105,53 +137,35 @@ bool AABox::intersects(const AABox& other) const {
return true;
}
-bool AABox::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask,
- uint32& outMask) const {
-
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask);
-}
-
-bool AABox::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask) const {
-
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask);
-}
-
int AABox::dummy = 0;
bool AABox::culledBy(
- const class Plane* plane,
- int numPlanes,
- int& cullingPlane,
- const uint32 _inMask,
+ const Array<Plane>& plane,
+ int& cullingPlane,
+ const uint32 _inMask,
uint32& childMask) const {
uint32 inMask = _inMask;
- assert(numPlanes < 31);
+ assert(plane.size() < 31);
childMask = 0;
- const bool finite =
- (abs(lo.x) < G3D::inf()) &&
- (abs(hi.x) < G3D::inf()) &&
- (abs(lo.y) < G3D::inf()) &&
- (abs(hi.y) < G3D::inf()) &&
- (abs(lo.z) < G3D::inf()) &&
- (abs(hi.z) < G3D::inf());
+ const bool finite =
+ (abs(lo.x) < G3D::finf()) &&
+ (abs(hi.x) < G3D::finf()) &&
+ (abs(lo.y) < G3D::finf()) &&
+ (abs(hi.y) < G3D::finf()) &&
+ (abs(lo.z) < G3D::finf()) &&
+ (abs(hi.z) < G3D::finf());
// See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
+ // vertices are in the negative half space.
+ for (int p = 0; p < plane.size(); ++p) {
- Vector3 corner;
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
+ Vector3 corner;
int numContained = 0;
int v = 0;
@@ -159,13 +173,13 @@ bool AABox::culledBy(
// We can early-out only if we have found one point on each
// side of the plane (i.e. if we are straddling). That
// occurs when (numContained < v) && (numContained > 0)
- for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
+ for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
// Unrolling these 3 if's into a switch decreases performance
// by about 2x
- corner.x = (v & 1) ? hi.x : lo.x;
- corner.y = (v & 2) ? hi.y : lo.y;
- corner.z = (v & 4) ? hi.z : lo.z;
-
+ corner.x = (v & 1) ? hi.x : lo.x;
+ corner.y = (v & 2) ? hi.y : lo.y;
+ corner.z = (v & 4) ? hi.z : lo.z;
+
if (finite) { // this branch is highly predictable
if (plane[p].halfSpaceContainsFinite(corner)) {
++numContained;
@@ -175,101 +189,102 @@ bool AABox::culledBy(
++numContained;
}
}
- }
+ }
- if (numContained == 0) {
- // Plane p culled the box
- cullingPlane = p;
+ if (numContained == 0) {
+ // Plane p culled the box
+ cullingPlane = p;
// The caller should not recurse into the children,
// since the parent is culled. If they do recurse,
// make them only test against this one plane, which
// will immediately cull the volume.
childMask = 1 << p;
- return true;
+ return true;
} else if (numContained < v) {
// The bounding volume straddled the plane; we have
// to keep testing against this plane
childMask |= (1 << p);
}
- }
+ }
// Move on to the next bit.
- inMask = inMask >> 1;
+ inMask = inMask >> 1;
}
// None of the planes could cull this box
- cullingPlane = -1;
+ cullingPlane = -1;
return false;
}
-bool AABox::culledBy(
- const class Plane* plane,
- int numPlanes,
- int& cullingPlane,
- const uint32 _inMask) const {
-
- uint32 inMask = _inMask;
- assert(numPlanes < 31);
- const bool finite =
- (abs(lo.x) < G3D::inf()) &&
- (abs(hi.x) < G3D::inf()) &&
- (abs(lo.y) < G3D::inf()) &&
- (abs(hi.y) < G3D::inf()) &&
- (abs(lo.z) < G3D::inf()) &&
- (abs(hi.z) < G3D::inf());
+bool AABox::culledBy(
+ const Array<Plane>& plane,
+ int& cullingPlane,
+ const uint32 _inMask) const {
+
+ uint32 inMask = _inMask;
+ assert(plane.size() < 31);
+
+ const bool finite =
+ (abs(lo.x) < G3D::finf()) &&
+ (abs(hi.x) < G3D::finf()) &&
+ (abs(lo.y) < G3D::finf()) &&
+ (abs(hi.y) < G3D::finf()) &&
+ (abs(lo.z) < G3D::finf()) &&
+ (abs(hi.z) < G3D::finf());
// See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
+ // vertices are in the negative half space.
+ for (int p = 0; p < plane.size(); ++p) {
- bool culled = true;
- Vector3 corner;
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
+ bool culled = true;
+ Vector3 corner;
int v;
- // Assume this plane culls all points. See if there is a point
- // not culled by the plane... early out when at least one point
+ // Assume this plane culls all points. See if there is a point
+ // not culled by the plane... early out when at least one point
// is in the positive half space.
- for (v = 0; (v < 8) && culled; ++v) {
+ for (v = 0; (v < 8) && culled; ++v) {
// Unrolling these 3 if's into a switch decreases performance
// by about 2x
- corner.x = (v & 1) ? hi.x : lo.x;
- corner.y = (v & 2) ? hi.y : lo.y;
- corner.z = (v & 4) ? hi.z : lo.z;
-
+ corner.x = (v & 1) ? hi.x : lo.x;
+ corner.y = (v & 2) ? hi.y : lo.y;
+ corner.z = (v & 4) ? hi.z : lo.z;
+
if (finite) { // this branch is highly predictable
culled = ! plane[p].halfSpaceContainsFinite(corner);
} else {
culled = ! plane[p].halfSpaceContains(corner);
}
- }
+ }
- if (culled) {
- // Plane p culled the box
- cullingPlane = p;
+ if (culled) {
+ // Plane p culled the box
+ cullingPlane = p;
- return true;
+ return true;
}
- }
+ }
// Move on to the next bit.
- inMask = inMask >> 1;
+ inMask = inMask >> 1;
}
// None of the planes could cull this box
- cullingPlane = -1;
+ cullingPlane = -1;
return false;
}
+
bool AABox::intersects(const class Sphere& sphere) const {
- double d = 0;
+ double d = 0;
//find the square of the distance
//from the sphere to the box
@@ -284,5 +299,68 @@ bool AABox::intersects(const class Sphere& sphere) const {
return d <= square(sphere.radius);
}
-} // namespace
+Vector3 AABox::corner(int index) const {
+
+ // default constructor inits all components to 0
+ Vector3 v;
+
+ switch (index)
+ {
+ case 0:
+ v.x = lo.x;
+ v.y = lo.y;
+ v.z = hi.z;
+ break;
+
+ case 1:
+ v.x = hi.x;
+ v.y = lo.y;
+ v.z = hi.z;
+ break;
+
+ case 2:
+ v.x = hi.x;
+ v.y = hi.y;
+ v.z = hi.z;
+ break;
+
+ case 3:
+ v.x = lo.x;
+ v.y = hi.y;
+ v.z = hi.z;
+ break;
+
+ case 4:
+ v.x = lo.x;
+ v.y = lo.y;
+ v.z = lo.z;
+ break;
+
+ case 5:
+ v.x = hi.x;
+ v.y = lo.y;
+ v.z = lo.z;
+ break;
+
+ case 6:
+ v.x = hi.x;
+ v.y = hi.y;
+ v.z = lo.z;
+ break;
+
+ case 7:
+ v.x = lo.x;
+ v.y = hi.y;
+ v.z = lo.z;
+ break;
+
+ default:
+ debugAssertM(false, "Invalid corner index");
+ break;
+ }
+
+ return v;
+}
+
+}
diff --git a/dep/src/g3dlite/Any.cpp b/dep/src/g3dlite/Any.cpp
new file mode 100644
index 00000000000..de4d32e83ea
--- /dev/null
+++ b/dep/src/g3dlite/Any.cpp
@@ -0,0 +1,1237 @@
+/**
+ @file Any.cpp
+
+ @author Morgan McGuire
+ @author Shawn Yarbrough
+
+ @created 2006-06-11
+ @edited 2009-11-15
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/Any.h"
+#include "G3D/TextOutput.h"
+#include "G3D/TextInput.h"
+#include "G3D/stringutils.h"
+#include <deque>
+#include <iostream>
+
+namespace G3D {
+
+void Any::beforeRead() const {
+ if (isPlaceholder()) {
+ // Tried to read from a placeholder--throw an exception as if
+ // the original operator[] had failed.
+ KeyNotFound e;
+ alwaysAssertM(m_data, "Corrupt placeholder");
+
+ e.filename = m_data->source.filename;
+ e.line = m_data->source.line;
+ e.character = m_data->source.character;
+ e.key = m_placeholderName;
+ e.message =
+ "This exception may have been thrown later than "
+ "the actual operator[] invocation.";
+
+ throw e;
+ }
+}
+
+
+Any::Data* Any::Data::create(const Data* d) {
+ Data* p = create(d->type);
+
+ p->comment = d->comment;
+ p->name = d->name;
+
+ switch (d->type) {
+ case NONE:
+ case BOOLEAN:
+ case NUMBER:
+ // No clone needed
+ break;
+
+ case STRING:
+ *(p->value.s) = *(d->value.s);
+ break;
+
+ case ARRAY:
+ *(p->value.a) = *(d->value.a);
+ break;
+
+ case TABLE:
+ *(p->value.t) = *(d->value.t);
+ // Note that placeholders may be copied; that is ok--they are still
+ // just placeholders.
+ break;
+ }
+
+ return p;
+}
+
+
+Any::Data* Any::Data::create(Any::Type t) {
+ size_t s = sizeof(Data);
+
+ switch (t) {
+ case NONE:
+ case BOOLEAN:
+ case NUMBER:
+ // No extra space needed
+ break;
+
+ case STRING:
+ s += sizeof(std::string);
+ break;
+
+ case ARRAY:
+ s += sizeof(AnyArray);
+ break;
+
+ case TABLE:
+ s += sizeof(AnyTable);
+ break;
+ }
+
+ // Allocate the data object
+ Data* p = new (MemoryManager::create()->alloc(s)) Data(t);
+
+ // Create the (empyt) value object at the end of the Data object
+ switch (t) {
+ case NONE:
+ case BOOLEAN:
+ case NUMBER:
+ // No value
+ break;
+
+ case STRING:
+ p->value.s = new (p + 1) std::string();
+ break;
+
+ case ARRAY:
+ p->value.a = new (p + 1) AnyArray();
+ break;
+
+ case TABLE:
+ p->value.t = new (p + 1) AnyTable();
+ break;
+ }
+
+ return p;
+}
+
+
+void Any::Data::destroy(Data* d) {
+ if (d != NULL) {
+ d->~Data();
+ MemoryManager::create()->free(d);
+ }
+}
+
+
+Any::Data::~Data() {
+ debugAssertM(referenceCount.value() <= 0, "Deleted while still referenced.");
+
+ // Destruct but do not deallocate children
+ switch (type) {
+ case STRING:
+ debugAssert(value.s != NULL);
+ value.s->~basic_string();
+ break;
+
+ case ARRAY:
+ debugAssert(value.a != NULL);
+ value.a->~Array();
+ break;
+
+ case TABLE:
+ debugAssert(value.t != NULL);
+ value.t->~Table();
+ break;
+
+ default:
+ // All other types should have a NULL value pointer (i.e., they were used just for name and comment fields)
+ debugAssertM(value.s == NULL, "Corrupt Any::Data::Value");
+ }
+
+ value.s = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////
+
+bool Any::containsKey(const std::string& x) const {
+ beforeRead();
+ verifyType(TABLE);
+
+ Any* a = m_data->value.t->getPointer(x);
+
+ // Don't return true for placeholder objects
+ return (a != NULL) && (! a->isPlaceholder());
+}
+
+
+void Any::dropReference() {
+ if (m_data && m_data->referenceCount.decrement() <= 0) {
+ // This was the last reference to the shared data
+ Data::destroy(m_data);
+ }
+ m_data = NULL;
+}
+
+
+void Any::ensureMutable() {
+ if (m_data && (m_data->referenceCount.value() >= 1)) {
+ // Copy the data. We must do this before dropping the reference
+ // to avoid a race condition
+ Data* d = Data::create(m_data);
+ dropReference();
+ m_data = d;
+ }
+}
+
+
+Any::Any() : m_type(NONE), m_data(NULL) {
+}
+
+
+Any::Any(TextInput& t) : m_type(NONE), m_data(NULL) {
+ deserialize(t);
+}
+
+
+Any::Any(const Any& x) : m_type(NONE), m_data(NULL) {
+ x.beforeRead();
+ *this = x;
+}
+
+
+Any::Any(double x) : m_type(NUMBER), m_simpleValue(x), m_data(NULL) {
+}
+
+
+#ifdef G3D_32BIT
+Any::Any(int64 x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
+}
+#endif // G3D_32BIT
+
+
+Any::Any(long x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
+}
+
+
+Any::Any(int x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
+}
+
+
+Any::Any(short x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) {
+}
+
+
+Any::Any(bool x) : m_type(BOOLEAN), m_simpleValue(x), m_data(NULL) {
+}
+
+
+Any::Any(const std::string& s) : m_type(STRING), m_data(Data::create(STRING)) {
+ *(m_data->value.s) = s;
+}
+
+
+Any::Any(const char* s) : m_type(STRING), m_data(NULL) {
+ if (s == NULL) {
+ m_type = NONE;
+ } else {
+ ensureData();
+ *(m_data->value.s) = s;
+ }
+}
+
+
+Any::Any(Type t, const std::string& name) : m_type(t), m_data(NULL) {
+ alwaysAssertM(t == ARRAY || t == TABLE, "Can only create ARRAY or TABLE from Type enum.");
+
+ ensureData();
+ if (name != "") {
+ m_data->name = name;
+ }
+}
+
+
+Any::~Any() {
+ dropReference();
+}
+
+
+void Any::beforeWrite() {
+ if (isPlaceholder()) {
+ // This is no longer a placeholder
+ m_placeholderName = "";
+ }
+}
+
+Any& Any::operator=(const Any& x) {
+ x.beforeRead();
+
+ if (this == &x) {
+ return *this;
+ }
+
+ beforeWrite();
+
+ dropReference();
+
+ m_type = x.m_type;
+ m_simpleValue = x.m_simpleValue;
+
+ if (x.m_data != NULL) {
+ x.m_data->referenceCount.increment();
+ m_data = x.m_data;
+ }
+
+ return *this;
+}
+
+
+Any& Any::operator=(double x) {
+ *this = Any(x);
+ return *this;
+}
+
+
+Any& Any::operator=(int x) {
+ return (*this = Any(x));
+}
+
+
+Any& Any::operator=(bool x) {
+ *this = Any(x);
+ return *this;
+}
+
+
+Any& Any::operator=(const std::string& x) {
+ *this = Any(x);
+ return *this;
+}
+
+
+Any& Any::operator=(const char* x) {
+ *this = Any(x);
+ return *this;
+}
+
+
+Any& Any::operator=(Type t) {
+ switch (t) {
+ case NONE:
+ *this = Any();
+ break;
+
+ case TABLE:
+ case ARRAY:
+ *this = Any(t);
+ break;
+
+ default:
+ alwaysAssertM(false, "Can only assign NONE, TABLE, or ARRAY Type enum.");
+ }
+
+ return *this;
+}
+
+
+Any::Type Any::type() const {
+ beforeRead();
+ return m_type;
+}
+
+
+const std::string& Any::comment() const {
+ beforeRead();
+
+ static const std::string blank;
+ if (m_data != NULL) {
+ return m_data->comment;
+ } else {
+ return blank;
+ }
+}
+
+
+void Any::setComment(const std::string& c) {
+ beforeRead();
+ ensureData();
+ m_data->comment = c;
+}
+
+
+bool Any::isNone() const {
+ beforeRead();
+ return (m_type == NONE);
+}
+
+
+double Any::number() const {
+ beforeRead();
+ verifyType(NUMBER);
+ return m_simpleValue.n;
+}
+
+
+const std::string& Any::string() const {
+ beforeRead();
+ verifyType(STRING);
+ return *(m_data->value.s);
+}
+
+
+bool Any::boolean() const {
+ beforeRead();
+ verifyType(BOOLEAN);
+ return m_simpleValue.b;
+}
+
+
+const std::string& Any::name() const {
+ beforeRead();
+ static const std::string blank;
+ if (m_data != NULL) {
+ return m_data->name;
+ } else {
+ return blank;
+ }
+}
+
+
+void Any::setName(const std::string& n) {
+ beforeRead();
+ ensureData();
+ m_data->name = n;
+}
+
+
+int Any::size() const {
+ beforeRead();
+ verifyType(ARRAY, TABLE);
+ switch (m_type) {
+ case TABLE:
+ return m_data->value.t->size();
+
+ case ARRAY:
+ return m_data->value.a->size();
+
+ default:;
+ return 0;
+ } // switch (m_type)
+}
+
+
+int Any::length() const {
+ beforeRead();
+ return size();
+}
+
+
+void Any::resize(int n) {
+ beforeRead();
+ alwaysAssertM(n >= 0, "Cannot resize less than 0.");
+ verifyType(ARRAY);
+ m_data->value.a->resize(n);
+}
+
+
+void Any::clear() {
+ beforeRead();
+ verifyType(ARRAY, TABLE);
+ switch (m_type) {
+ case ARRAY:
+ m_data->value.a->clear();
+ break;
+
+ case TABLE:
+ m_data->value.t->clear();
+ break;
+
+ default:;
+ }
+}
+
+
+const Any& Any::operator[](int i) const {
+ beforeRead();
+ verifyType(ARRAY);
+ debugAssert(m_data != NULL);
+ Array<Any>& array = *(m_data->value.a);
+ return array[i];
+}
+
+
+Any& Any::next() {
+ beforeRead();
+ verifyType(ARRAY);
+ int n = size();
+ resize(n + 1);
+ return (*this)[n];
+}
+
+
+Any& Any::operator[](int i) {
+ beforeRead();
+ verifyType(ARRAY);
+ debugAssert(m_data != NULL);
+ Array<Any>& array = *(m_data->value.a);
+ return array[i];
+}
+
+
+const Array<Any>& Any::array() const {
+ beforeRead();
+ verifyType(ARRAY);
+ debugAssert(m_data != NULL);
+ return *(m_data->value.a);
+}
+
+
+void Any::append(const Any& x0) {
+ beforeRead();
+ verifyType(ARRAY);
+ debugAssert(m_data != NULL);
+ m_data->value.a->append(x0);
+}
+
+
+void Any::append(const Any& x0, const Any& x1) {
+ beforeRead();
+ append(x0);
+ append(x1);
+}
+
+
+void Any::append(const Any& x0, const Any& x1, const Any& x2) {
+ beforeRead();
+ append(x0);
+ append(x1);
+ append(x2);
+}
+
+
+void Any::append(const Any& x0, const Any& x1, const Any& x2, const Any& x3) {
+ beforeRead();
+ append(x0);
+ append(x1);
+ append(x2);
+ append(x3);
+}
+
+
+const Table<std::string, Any>& Any::table() const {
+ beforeRead();
+ verifyType(TABLE);
+ debugAssert(m_data != NULL);
+ return *(m_data->value.t);
+}
+
+
+const Any& Any::operator[](const std::string& x) const {
+ beforeRead();
+ verifyType(TABLE);
+ debugAssert(m_data != NULL);
+ const Table<std::string, Any>& table = *(m_data->value.t);
+ Any* value = table.getPointer(x);
+ if (value == NULL) {
+ KeyNotFound e;
+ if (m_data) {
+ e.filename = m_data->source.filename;
+ e.line = m_data->source.line;
+ e.character = m_data->source.character;
+ }
+ e.key = x;
+ throw e;
+ }
+ return *value;
+}
+
+
+Any& Any::operator[](const std::string& key) {
+ beforeRead();
+ verifyType(TABLE);
+
+ bool created = false;
+ Any& value = m_data->value.t->getCreate(key, created);
+
+ if (created) {
+ // The entry was created by this method; do not allow it to be
+ // read before it is written.
+ value.m_placeholderName = key;
+
+ // Write source data for the value
+ value.ensureData();
+ value.m_data->source = source();
+ }
+
+ return value;
+}
+
+
+void Any::set(const std::string& k, const Any& v) {
+ beforeRead();
+ v.beforeRead();
+ verifyType(TABLE);
+ debugAssert(m_data != NULL);
+ Table<std::string, Any>& table = *(m_data->value.t);
+ table.set(k, v);
+}
+
+
+const Any& Any::get(const std::string& x, const Any& defaultVal) const {
+ beforeRead();
+ defaultVal.beforeRead();
+ try {
+ return operator[](x);
+ } catch(KeyNotFound) {
+ return defaultVal;
+ }
+}
+
+
+bool Any::operator==(const Any& x) const {
+ beforeRead();
+ x.beforeRead();
+ if (m_type != x.m_type) {
+ return false;
+ }
+
+ switch (m_type) {
+ case NONE:
+ return true;
+
+ case BOOLEAN:
+ return (m_simpleValue.b == x.m_simpleValue.b);
+
+ case NUMBER:
+ return (m_simpleValue.n == x.m_simpleValue.n);
+
+ case STRING:
+ debugAssert(m_data != NULL);
+ return (*(m_data->value.s) == *(x.m_data->value.s));
+
+ case TABLE: {
+ if (size() != x.size()) {
+ return false;
+ }
+ debugAssert(m_data != NULL);
+ if (m_data->name != x.m_data->name) {
+ return false;
+ }
+ Table<std::string, Any>& cmptable = *( m_data->value.t);
+ Table<std::string, Any>& xcmptable = *(x.m_data->value.t);
+ for (Table<std::string,Any>::Iterator it1 = cmptable.begin(), it2 = xcmptable.begin();
+ it1 != cmptable.end() && it2 != xcmptable.end();
+ ++it1, ++it2) {
+ if (*it1 != *it2) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ case ARRAY: {
+ if (size() != x.size()) {
+ return false;
+ }
+ debugAssert(m_data != NULL);
+ if (m_data->name != x.m_data->name) {
+ return false;
+ }
+
+ Array<Any>& cmparray = *( m_data->value.a);
+ Array<Any>& xcmparray = *(x.m_data->value.a);
+
+ for (int ii = 0; ii < size(); ++ii) {
+ if (cmparray[ii] != xcmparray[ii]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ default:
+ alwaysAssertM(false, "Unknown type.");
+ return false;
+ } // switch (m_type)
+
+}
+
+
+bool Any::operator!=(const Any& x) const {
+ beforeRead();
+ x.beforeRead();
+ return !operator==(x);
+}
+
+
+static void getDeserializeSettings(TextInput::Settings& settings) {
+ settings.cppBlockComments = true;
+ settings.cppLineComments = true;
+ settings.otherLineComments = true;
+ settings.otherCommentCharacter = '#';
+ settings.generateCommentTokens = true;
+ settings.singleQuotedStrings = false;
+ settings.msvcSpecials = false;
+ settings.caseSensitive = false;
+}
+
+
+std::string Any::unparse() const {
+ beforeRead();
+ TextOutput::Settings settings;
+ TextOutput to(settings);
+ serialize(to);
+ return to.commitString();
+}
+
+
+void Any::parse(const std::string& src) {
+ beforeRead();
+ TextInput::Settings settings;
+ getDeserializeSettings(settings);
+
+ TextInput ti(TextInput::FROM_STRING, src, settings);
+ deserialize(ti);
+}
+
+
+void Any::load(const std::string& filename) {
+ beforeRead();
+ TextInput::Settings settings;
+ getDeserializeSettings(settings);
+
+ TextInput ti(filename, settings);
+ deserialize(ti);
+}
+
+
+void Any::save(const std::string& filename) const {
+ beforeRead();
+ TextOutput::Settings settings;
+ settings.wordWrap = TextOutput::Settings::WRAP_NONE;
+
+ TextOutput to(filename,settings);
+ serialize(to);
+ to.commit();
+}
+
+
+static bool needsQuotes(const std::string& s) {
+ if (! isLetter(s[0]) && (s[0] != '_')) {
+ return true;
+ }
+
+ for (int i = 0; i < (int)s.length(); ++i) {
+ char c = s[i];
+
+ // peek character
+ char p = (i == (int)s.length() - 1) ? '_' : s[i + 1];
+
+ // Identify separators
+ if ((c == '-' && p == '>') ||
+ (c == ':' && p == ':')) {
+ // Skip over this symbol
+ ++i;
+ continue;
+ }
+
+ if (! isDigit(c) && ! isLetter(c) & (c != '.')) {
+ // This is an illegal character for an identifier, so we need quotes
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+// TODO: if the output will fit on one line, compress tables and arrays into a single line
+void Any::serialize(TextOutput& to) const {
+ beforeRead();
+ if (m_data && ! m_data->comment.empty()) {
+ to.printf("\n/* %s */\n", m_data->comment.c_str());
+ }
+
+ switch (m_type) {
+ case NONE:
+ to.writeSymbol("NONE");
+ break;
+
+ case BOOLEAN:
+ to.writeBoolean(m_simpleValue.b);
+ break;
+
+ case NUMBER:
+ to.writeNumber(m_simpleValue.n);
+ break;
+
+ case STRING:
+ debugAssert(m_data != NULL);
+ to.writeString(*(m_data->value.s));
+ break;
+
+ case TABLE: {
+ debugAssert(m_data != NULL);
+ if (! m_data->name.empty()) {
+ if (needsQuotes(m_data->name)) {
+ to.writeString(m_data->name);
+ } else {
+ to.writeSymbol(m_data->name);
+ }
+ }
+ to.writeSymbol("{");
+ to.writeNewline();
+ to.pushIndent();
+ AnyTable& table = *(m_data->value.t);
+ Array<std::string> keys;
+ table.getKeys(keys);
+ keys.sort();
+
+ for (int i = 0; i < keys.size(); ++i) {
+
+ to.writeSymbol(keys[i]);
+ to.writeSymbol("=");
+ table[keys[i]].serialize(to);
+
+ if (i < keys.size() - 1) {
+ to.writeSymbol(",");
+ }
+ to.writeNewline();
+
+ // Skip a line between table entries
+ to.writeNewline();
+ }
+
+ to.popIndent();
+ to.writeSymbol("}");
+ break;
+ }
+
+ case ARRAY: {
+ debugAssert(m_data != NULL);
+ if (! m_data->name.empty()) {
+ // For arrays, leave no trailing space between the name and the paren
+ to.writeSymbol(format("%s(", m_data->name.c_str()));
+ } else {
+ to.writeSymbol("(");
+ }
+ to.writeNewline();
+ to.pushIndent();
+ Array<Any>& array = *(m_data->value.a);
+ for (int ii = 0; ii < size(); ++ii) {
+ array[ii].serialize(to);
+ if (ii < size() - 1) {
+ to.writeSymbol(",");
+ to.writeNewline();
+ }
+
+ // Put the close paren on an array right behind the last element
+ }
+ to.popIndent();
+ to.writeSymbol(")");
+ break;
+ }
+ }
+}
+
+
+void Any::deserializeComment(TextInput& ti, Token& token, std::string& comment) {
+ // Parse comments
+ while (token.type() == Token::COMMENT) {
+ comment += trimWhitespace(token.string()) + "\n";
+
+ // Allow comments to contain newlines.
+ do {
+ token = ti.read();
+ comment += "\n";
+ } while (token.type() == Token::NEWLINE);
+ }
+
+ comment = trimWhitespace(comment);
+}
+
+/** True if \a c is an open paren of some form */
+static bool isOpen(const char c) {
+ return c == '(' || c == '[' || c == '{';
+}
+
+
+/** True if \a c is an open paren of some form */
+static bool isClose(const char c) {
+ return c == ')' || c == ']' || c == '}';
+}
+
+
+/** True if \a s is a C++ name operator */
+static bool isNameOperator(const std::string& s) {
+ return s == "." || s == "::" || s == "->";
+}
+
+
+void Any::deserializeName(TextInput& ti, Token& token, std::string& name) {
+ debugAssert(token.type() == Token::SYMBOL);
+ std::string s = token.string();
+ while (! isOpen(s[0])) {
+ name += s;
+
+ // Skip newlines and comments
+ token = ti.readSignificant();
+
+ if (token.type() != Token::SYMBOL) {
+ throw ParseError(ti.filename(), token.line(), token.character(),
+ "Expected symbol while parsing Any");
+ }
+ s = token.string();
+ }
+}
+
+
+void Any::deserialize(TextInput& ti) {
+ beforeRead();
+ Token token = ti.read();
+ deserialize(ti, token);
+ // Restore the last token
+ ti.push(token);
+}
+
+
+void Any::deserialize(TextInput& ti, Token& token) {
+ // Deallocate old data
+ dropReference();
+ m_type = NONE;
+ m_simpleValue.b = false;
+
+ // Skip leading newlines
+ while (token.type() == Token::NEWLINE) {
+ token = ti.read();
+ }
+
+ std::string comment;
+ if (token.type() == Token::COMMENT) {
+ deserializeComment(ti, token, comment);
+ }
+
+ if (token.type() == Token::END) {
+ // There should never be a comment without an Any following it; even
+ // if the file ends with some commented out stuff,
+ // that should not happen after a comma, so we'd never read that
+ // far in a proper file.
+ throw ParseError(ti.filename(), token.line(), token.character(),
+ "File ended without a properly formed Any");
+ }
+
+ switch (token.type()) {
+ case Token::STRING:
+ m_type = STRING;
+ ensureData();
+ *(m_data->value.s) = token.string();
+ m_data->source.set(ti, token);
+ break;
+
+ case Token::NUMBER:
+ m_type = NUMBER;
+ m_simpleValue.n = token.number();
+ ensureData();
+ m_data->source.set(ti, token);
+ break;
+
+ case Token::BOOLEAN:
+ m_type = BOOLEAN;
+ m_simpleValue.b = token.boolean();
+ ensureData();
+ m_data->source.set(ti, token);
+ break;
+
+ case Token::SYMBOL:
+ // Named Array, Named Table, Array, Table, or NONE
+ if (toUpper(token.string()) == "NONE") {
+ // Nothing left to do; we initialized to NONE originally
+ ensureData();
+ m_data->source.set(ti, token);
+ } else {
+ // Array or Table
+
+ // Parse the name
+
+ // s must have at least one element or this would not have
+ // been parsed as a symbol
+ std::string name;
+ deserializeName(ti, token, name);
+ if (token.type() != Token::SYMBOL) {
+ throw ParseError(ti.filename(), token.line(), token.character(),
+ "Malformed Any TABLE or ARRAY; must start with [, (, or {");
+ }
+
+ if (isOpen(token.string()[0])) {
+ // Array or table
+ deserializeBody(ti, token);
+ } else {
+ throw ParseError(ti.filename(), token.line(), token.character(),
+ "Malformed Any TABLE or ARRAY; must start with [, (, or {");
+ }
+
+ if (! name.empty()) {
+ ensureData();
+ m_data->name = name;
+ }
+ } // if NONE
+ break;
+
+ default:
+ throw ParseError(ti.filename(), token.line(), token.character(),
+ "Unexpected token");
+
+ } // switch
+
+ if (! comment.empty()) {
+ ensureData();
+ m_data->comment = comment;
+ }
+
+ if (m_type != ARRAY && m_type != TABLE) {
+ // Array and table already consumed their last token
+ token = ti.read();
+ }
+}
+
+
+void Any::ensureData() {
+ if (m_data == NULL) {
+ m_data = Data::create(m_type);
+ }
+}
+
+
+static bool isSeparator(char c) {
+ return c == ',' || c == ';';
+}
+
+
+void Any::readUntilCommaOrClose(TextInput& ti, Token& token) {
+ while (! ((token.type() == Token::SYMBOL) &&
+ (isClose(token.string()[0])) ||
+ isSeparator(token.string()[0]))) {
+ switch (token.type()) {
+ case Token::NEWLINE:
+ case Token::COMMENT:
+ // Consume
+ token = ti.read();
+ break;
+
+ default:
+ throw ParseError(ti.filename(), token.line(), token.character(),
+ "Expected a comma or close paren");
+ }
+ }
+}
+
+
+void Any::deserializeBody(TextInput& ti, Token& token) {
+ char closeSymbol = '}';
+ m_type = TABLE;
+
+ const char c = token.string()[0];
+
+ if (c != '{') {
+ m_type = ARRAY;
+ // Chose the appropriate close symbol
+ closeSymbol = (c == '(') ? ')' : ']';
+ }
+
+ // Allocate the underlying data structure
+ ensureData();
+ m_data->source.set(ti, token);
+
+ // Consume the open token
+ token = ti.read();
+
+ while (! ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol))) {
+
+ // Read any leading comment. This must be done here (and not in the recursive deserialize
+ // call) in case the body contains only a comment.
+ std::string comment;
+ deserializeComment(ti, token, comment);
+
+ if ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol)) {
+ // We're done; this catches the case where the array is empty
+ break;
+ }
+
+ // Pointer the value being read
+ Any a = NULL;
+ std::string key;
+
+ if (m_type == TABLE) {
+ // Read the key
+ if (token.type() != Token::SYMBOL && token.type() != Token::STRING) {
+ throw ParseError(ti.filename(), token.line(), token.character(), "Expected a name");
+ }
+
+ key = token.string();
+ // Consume everything up to the = sign
+ token = ti.readSignificant();
+
+ if ((token.type() != Token::SYMBOL) || (token.string() != "=")) {
+ throw ParseError(ti.filename(), token.line(), token.character(), "Expected =");
+ } else {
+ // Consume (don't consume comments--we want the value pointed to by a to get those).
+ token = ti.read();
+ }
+ }
+ a.deserialize(ti, token);
+
+ if (! comment.empty()) {
+ // Prepend the comment we read earlier
+ a.ensureData();
+ a.m_data->comment = trimWhitespace(comment + "\n" + a.m_data->comment);
+ }
+
+ if (m_type == TABLE) {
+ set(key, a);
+ } else {
+ append(a);
+ }
+
+ // Read until the comma or close paren, discarding trailing comments and newlines
+ readUntilCommaOrClose(ti, token);
+
+ // Consume the comma
+ if (isSeparator(token.string()[0])) {
+ token = ti.read();
+ }
+ }
+
+ // Consume the close paren (to match other deserialize methods)
+ token = ti.read();
+}
+
+
+Any::operator int() const {
+ beforeRead();
+ return iRound(number());
+}
+
+
+Any::operator float() const {
+ beforeRead();
+ return float(number());
+}
+
+
+Any::operator double() const {
+ beforeRead();
+ return number();
+}
+
+
+Any::operator bool() const {
+ beforeRead();
+ return boolean();
+}
+
+
+Any::operator std::string() const {
+ beforeRead();
+ return string();
+}
+
+
+const Any::Source& Any::source() const {
+ static Source s;
+ if (m_data) {
+ return m_data->source;
+ } else {
+ return s;
+ }
+}
+
+
+void Any::verify(bool value, const std::string& message) const {
+ beforeRead();
+ if (! value) {
+ ParseError p;
+ if (m_data) {
+ p.filename = m_data->source.filename;
+ p.line = m_data->source.line;
+ p.character = m_data->source.character;
+ }
+
+ if (name().empty()) {
+ p.message = "Parse error";
+ } else {
+ p.message = "Parse error while reading the contents of " + name();
+ }
+
+ if (! message.empty()) {
+ p.message = p.message + ": " + message;
+ }
+
+ throw p;
+ }
+}
+
+
+void Any::verifyName(const std::string& n) const {
+ beforeRead();
+ verify(beginsWith(toUpper(name()), toUpper(n)), "Name must begin with " + n);
+}
+
+
+void Any::verifyType(Type t) const {
+ beforeRead();
+ if (type() != t) {
+ verify(false, "Must have type " + toString(t));
+ }
+}
+
+
+void Any::verifyType(Type t0, Type t1) const {
+ beforeRead();
+ if (type() != t0 && type() != t1) {
+ verify(false, "Must have type " + toString(t0) + " or " + toString(t1));
+ }
+}
+
+
+void Any::verifySize(int low, int high) const {
+ beforeRead();
+ verifyType(ARRAY, TABLE);
+ if (size() < low || size() > high) {
+ verify(false, format("Size must be between %d and %d", low, high));
+ }
+}
+
+
+void Any::verifySize(int s) const {
+ beforeRead();
+ verifyType(ARRAY, TABLE);
+ if (size() != s) {
+ verify(false, format("Size must be %d", s));
+ }
+}
+
+
+std::string Any::toString(Type t) {
+ switch(t) {
+ case NONE: return "NONE";
+ case BOOLEAN: return "BOOLEAN";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case ARRAY: return "ARRAY";
+ case TABLE: return "TABLE";
+ default:
+ alwaysAssertM(false, "Illegal Any::Type");
+ return "";
+ }
+}
+
+} // namespace G3D
+
diff --git a/dep/src/g3dlite/AnyVal.cpp b/dep/src/g3dlite/AnyVal.cpp
new file mode 100644
index 00000000000..7b98486523a
--- /dev/null
+++ b/dep/src/g3dlite/AnyVal.cpp
@@ -0,0 +1,1379 @@
+/**
+ @file AnyVal.cpp
+ @author Morgan McGuire
+ @maintainer Morgan McGuire
+ @created 2006-06-11
+ @edited 2008-07-14
+ */
+
+#include "G3D/AnyVal.h"
+#include "G3D/Array.h"
+#include "G3D/stringutils.h"
+#include "G3D/Table.h"
+#include "G3D/Vector2.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector4.h"
+#include "G3D/Color1.h"
+#include "G3D/Color3.h"
+#include "G3D/Color4.h"
+#include "G3D/Matrix2.h"
+#include "G3D/Matrix3.h"
+#include "G3D/Matrix4.h"
+#include "G3D/Rect2D.h"
+#include "G3D/AABox.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Quat.h"
+#include "G3D/TextInput.h"
+#include "G3D/TextOutput.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+AnyVal AnyVal::fromFile(const std::string& filename) {
+ TextInput t(filename);
+ return AnyVal(t);
+}
+
+
+void AnyVal::load(const std::string& filename) {
+ *this = fromFile(filename);
+}
+
+
+void AnyVal::save(const std::string& filename) const {
+ TextOutput t(filename);
+ serialize(t);
+ t.commit();
+}
+
+
+AnyVal::AnyVal() : m_type(NIL), m_value(NULL), m_referenceCount(NULL) {
+}
+
+
+AnyVal::AnyVal(bool b) : m_type(BOOLEAN), m_value(new bool(b)), m_referenceCount(NULL) {
+}
+
+
+AnyVal::AnyVal(G3D::TextInput& t) : m_type(NIL), m_value(NULL), m_referenceCount(NULL) {
+ deserialize(t);
+}
+
+
+/*AnyVal::AnyVal(G3D::BinaryInput& b) {
+ deserialize(b);
+}
+*/
+
+AnyVal::AnyVal(double v) : m_type(NUMBER), m_referenceCount(NULL) {
+ m_value = new double(v);
+}
+
+
+AnyVal::AnyVal(int v) : m_type(NUMBER), m_referenceCount(NULL) {
+ m_value = new double(v);
+}
+
+
+AnyVal::AnyVal(const Rect2D& v) : m_type(RECT2D), m_referenceCount(NULL) {
+ m_value = new Rect2D(v);
+}
+
+
+AnyVal::AnyVal(const AABox& v) : m_type(AABOX), m_referenceCount(NULL) {
+ m_value = new AABox(v);
+}
+
+
+AnyVal::AnyVal(const Vector2& v) : m_type(VECTOR2), m_referenceCount(NULL) {
+ m_value = new Vector2(v);
+}
+
+
+AnyVal::AnyVal(const Vector3& v) : m_type(VECTOR3), m_referenceCount(NULL) {
+ m_value = new Vector3(v);
+}
+
+
+AnyVal::AnyVal(const Vector4& v) : m_type(VECTOR4), m_referenceCount(NULL) {
+ m_value = new Vector4(v);
+}
+
+
+AnyVal::AnyVal(const Color1& v) : m_type(COLOR1), m_referenceCount(NULL) {
+ m_value = new Color1(v);
+}
+
+
+AnyVal::AnyVal(const Color3& v) : m_type(COLOR3), m_referenceCount(NULL) {
+ m_value = new Color3(v);
+}
+
+
+AnyVal::AnyVal(const Color4& v) : m_type(COLOR4), m_referenceCount(NULL) {
+ m_value = new Color4(v);
+}
+
+
+AnyVal::AnyVal(const std::string& v) : m_type(STRING), m_referenceCount(NULL) {
+ m_value = new std::string(v);
+}
+
+
+AnyVal::AnyVal(const char* v) : m_type(STRING), m_referenceCount(NULL) {
+ m_value = new std::string(v);
+}
+
+
+AnyVal::AnyVal(const Quat& v) : m_type(QUAT), m_referenceCount(NULL) {
+ m_value = new Quat(v);
+}
+
+
+AnyVal::AnyVal(const CoordinateFrame& v) : m_type(COORDINATEFRAME), m_referenceCount(NULL) {
+ m_value = new CoordinateFrame(v);
+}
+
+
+AnyVal::AnyVal(const Matrix2& v) : m_type(MATRIX2), m_referenceCount(NULL) {
+ m_value = new Matrix2(v);
+}
+
+AnyVal::AnyVal(const Matrix3& v) : m_type(MATRIX3), m_referenceCount(NULL) {
+ m_value = new Matrix3(v);
+}
+
+
+AnyVal::AnyVal(const Matrix4& v) : m_type(MATRIX4), m_referenceCount(NULL) {
+ m_value = new Matrix4(v);
+}
+
+
+AnyVal::AnyVal(const AnyVal& c) : m_type(NIL), m_value(NULL), m_referenceCount(NULL) {
+ *this = c;
+}
+
+
+AnyVal::AnyVal(Type arrayOrTable) : m_type(NIL), m_value(NULL), m_referenceCount(new int(1)) {
+ // TODO: make AnyVal::createArray()
+ switch (arrayOrTable) {
+ case ARRAY:
+ m_type = ARRAY;
+ m_value = new Array<AnyVal>();
+ break;
+
+ case TABLE:
+ m_type = TABLE;
+ m_value = new Table<std::string, AnyVal>();
+ break;
+
+ default:
+ debugAssertM(false, "Cannot construct AnyVal from constants except ARRAY or TABLE.");
+ }
+}
+
+
+AnyVal::~AnyVal() {
+ deleteValue();
+}
+
+
+void AnyVal::deleteValue() {
+ if (m_referenceCount) {
+ --(*m_referenceCount);
+ if (*m_referenceCount <= 0) {
+ delete m_referenceCount;
+ m_referenceCount = NULL;
+ // Pass through and delete the real object now
+ } else {
+ // Someone else is holding a reference, so we can't delete
+ // the object.
+ m_referenceCount = NULL;
+ return;
+ }
+ }
+
+ switch (m_type) {
+ case NIL:
+ // Nothing to do
+ break;
+
+ case NUMBER:
+ delete (double*)m_value;
+ break;
+
+ case BOOLEAN:
+ delete (bool*)m_value;
+ break;
+
+ case STRING:
+ delete (std::string*)m_value;
+ break;
+
+ case RECT2D:
+ delete (Rect2D*)m_value;
+ break;
+
+ case AABOX:
+ delete (AABox*)m_value;
+ break;
+
+ case VECTOR2:
+ delete (Vector2*)m_value;
+ break;
+
+ case VECTOR3:
+ delete (Vector3*)m_value;
+ break;
+
+ case VECTOR4:
+ delete (Vector4*)m_value;
+ break;
+
+ case MATRIX2:
+ delete (Matrix2*)m_value;
+ break;
+
+ case MATRIX3:
+ delete (Matrix3*)m_value;
+ break;
+
+ case MATRIX4:
+ delete (Matrix4*)m_value;
+ break;
+
+ case QUAT:
+ delete (Quat*)m_value;
+ break;
+
+ case COORDINATEFRAME:
+ delete (CoordinateFrame*)m_value;
+ break;
+
+ case COLOR1:
+ delete (Color1*)m_value;
+ break;
+
+ case COLOR3:
+ delete (Color3*)m_value;
+ break;
+
+ case COLOR4:
+ delete (Color4*)m_value;
+ break;
+
+ case ARRAY:
+ delete (Array<AnyVal>*)m_value;
+ break;
+
+ case TABLE:
+ delete (Table<std::string, AnyVal>*)m_value;
+ break;
+
+ default:
+ debugAssertM(false, "Internal error: no destructor for this type.");
+ }
+
+ m_value = NULL;
+}
+
+
+AnyVal& AnyVal::operator=(const AnyVal& v) {
+ deleteValue();
+
+ m_type = v.m_type;
+
+ m_referenceCount = v.m_referenceCount;
+
+ if (isSharedType()) {
+ ++(*m_referenceCount);
+ m_value = v.m_value;
+ } else {
+ m_value = v.copyValue();
+ }
+
+ return *this;
+}
+
+
+void* AnyVal::copyValue() const {
+ switch (m_type) {
+ case NIL:
+ return NULL;
+
+ case NUMBER:
+ return new double(*(double*)m_value);
+
+ case BOOLEAN:
+ return new bool(*(bool*)m_value);
+
+ case STRING:
+ return new std::string(*(std::string*)m_value);
+
+ case RECT2D:
+ return new Rect2D(*(Rect2D*)m_value);
+
+ case AABOX:
+ return new AABox(*(AABox*)m_value);
+
+ case VECTOR2:
+ return new Vector2(*(Vector2*)m_value);
+
+ case VECTOR3:
+ return new Vector3(*(Vector3*)m_value);
+
+ case VECTOR4:
+ return new Vector4(*(Vector4*)m_value);
+
+ case MATRIX2:
+ return new Matrix2(*(Matrix2*)m_value);
+
+ case MATRIX3:
+ return new Matrix3(*(Matrix3*)m_value);
+
+ case MATRIX4:
+ return new Matrix4(*(Matrix4*)m_value);
+
+ case QUAT:
+ return new Quat(*(Quat*)m_value);
+
+ case COORDINATEFRAME:
+ return new CoordinateFrame(*(CoordinateFrame*)m_value);
+
+ case COLOR1:
+ return new Color1(*(Color1*)m_value);
+
+ case COLOR3:
+ return new Color3(*(Color3*)m_value);
+
+ case COLOR4:
+ return new Color4(*(Color4*)m_value);
+
+ case ARRAY:
+ return new Array<AnyVal>(*(Array<AnyVal>*)m_value);
+
+ case TABLE:
+ return new Table<std::string, AnyVal>(*(Table<std::string, AnyVal>*)m_value);
+
+ default:
+ debugAssertM(false, "Internal error: no assignment operator for this type.");
+ return NULL;
+ }
+}
+
+AnyVal::Type AnyVal::type() const {
+ return m_type;
+}
+
+
+static bool legalIdentifier(const std::string& s) {
+ if (s.size() == 0) {
+ return false;
+ }
+
+ if (! isLetter(s[0]) || (s[0] == '_')) {
+ return false;
+ }
+
+ bool ok = true;
+
+ for (unsigned int i = 1; i < s.size(); ++i) {
+ ok &= isDigit(s[i]) || isLetter(s[i]) || (s[i] == '_');
+ }
+
+ return ok;
+}
+
+
+void AnyVal::serialize(G3D::TextOutput& t) const {
+ switch (m_type) {
+ case NIL:
+ t.writeSymbol("Nil");
+ break;
+
+ case NUMBER:
+ t.printf("%g", *(double*)m_value);
+ break;
+
+ case BOOLEAN:
+ t.writeBoolean(*(bool*)m_value);
+ break;
+
+ case STRING:
+ t.writeString(*(std::string*)m_value);
+ break;
+
+ case RECT2D:
+ t.printf("R(%g, %g, %g, %g)", ((Rect2D*)m_value)->x0(), ((Rect2D*)m_value)->y0(),
+ ((Rect2D*)m_value)->width(), ((Rect2D*)m_value)->height());
+ break;
+
+ case AABOX:
+ t.printf("AAB(V3(%g, %g, %g), V3(%g, %g, %g))",
+ aabox().low().x,
+ aabox().low().y,
+ aabox().low().z,
+ aabox().high().x,
+ aabox().high().y,
+ aabox().high().z);
+ break;
+
+ case VECTOR2:
+ t.printf("V2(%g, %g)", ((Vector2*)m_value)->x, ((Vector2*)m_value)->y);
+ break;
+
+ case VECTOR3:
+ t.printf("V3(%g, %g, %g)", ((Vector3*)m_value)->x, ((Vector3*)m_value)->y, ((Vector3*)m_value)->z);
+ break;
+
+ case VECTOR4:
+ t.printf("V4(%g, %g, %g, %g)", ((Vector4*)m_value)->x, ((Vector4*)m_value)->y, ((Vector4*)m_value)->z, ((Vector4*)m_value)->w);
+ break;
+
+ case MATRIX2:
+ {
+ const Matrix2& m = *(Matrix2*)m_value;
+ t.printf("M2(\n");
+ t.pushIndent();
+ t.printf("%10.5f, %10.5f,\n%10.5f, %10.5f)",
+ m[0][0], m[0][1],
+ m[1][0], m[1][1]);
+ t.popIndent();
+ }
+ break;
+
+ case MATRIX3:
+ {
+ const Matrix3& m = *(Matrix3*)m_value;
+ t.printf("M3(\n");
+ t.pushIndent();
+ t.printf("%10.5f, %10.5f, %10.5f,\n%10.5f, %10.5f, %10.5f,\n%10.5f, %10.5f, %10.5f)",
+ m[0][0], m[0][1], m[0][2],
+ m[1][0], m[1][1], m[1][2],
+ m[2][0], m[2][1], m[2][2]);
+ t.popIndent();
+ }
+ break;
+
+ case MATRIX4:
+ {
+ const Matrix4& m = *(Matrix4*)m_value;
+ t.printf("M4(\n");
+ t.pushIndent();
+ t.printf(
+ "%10.5f, %10.5f, %10.5f, %10.5f,\n"
+ "%10.5f, %10.5f, %10.5f, %10.5f,\n"
+ "%10.5f, %10.5f, %10.5f, %10.5f,\n"
+ "%10.5f, %10.5f, %10.5f, %10.5f)",
+ m[0][0], m[0][1], m[0][2], m[0][3],
+ m[1][0], m[1][1], m[1][2], m[1][3],
+ m[2][0], m[2][1], m[2][2], m[2][3],
+ m[3][0], m[3][1], m[3][2], m[3][3]);
+ t.popIndent();
+ }
+ break;
+
+ case QUAT:
+ t.printf("Q(%g, %g, %g, %g)", ((Quat*)m_value)->x, ((Quat*)m_value)->y, ((Quat*)m_value)->z, ((Quat*)m_value)->w);
+ break;
+
+ case COORDINATEFRAME:
+ {
+ const CoordinateFrame& c = *(CoordinateFrame*)m_value;
+ float x,y,z,yaw,pitch,roll;
+ c.getXYZYPRDegrees(x,y,z,yaw,pitch,roll);
+ t.printf("CF(V3(%g,%g,%g), %g, %g, %g)", x, y, z, yaw, pitch, roll);
+ /*
+ t.pushIndent();
+ t.printf(
+ "CF(\n%10.5f, %10.5f, %10.5f, %10.5f,\n"
+ "%10.5f, %10.5f, %10.5f, %10.5f,\n"
+ "%10.5f, %10.5f, %10.5f, %10.5f)",
+ c.rotation[0][0], c.rotation[0][1], c.rotation[0][2], c.translation.x,
+ c.rotation[1][0], c.rotation[1][1], c.rotation[1][2], c.translation.y,
+ c.rotation[2][0], c.rotation[2][1], c.rotation[2][2], c.translation.z);
+ t.popIndent();
+ */
+ }
+ break;
+
+ case COLOR1:
+ t.printf("C1(%g)", ((Color1*)m_value)->value);
+ break;
+
+ case COLOR3:
+ t.printf("C3(%g, %g, %g)", ((Color3*)m_value)->r, ((Color3*)m_value)->g, ((Color3*)m_value)->b);
+ break;
+
+ case COLOR4:
+ t.printf("C4(%g, %g, %g, %g)", ((Color4*)m_value)->r, ((Color4*)m_value)->g, ((Color4*)m_value)->b, ((Color4*)m_value)->a);
+ break;
+
+ case ARRAY:
+ {
+ const Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
+ t.printf("[\n");
+ t.pushIndent();
+ for (int i = 0; i < a.size(); ++i) {
+ a[i].serialize(t);
+ if (i != a.size() - 1) {
+ t.printf(", \n");
+ }
+ }
+ t.printf("]");
+ t.popIndent();
+ }
+ break;
+
+ case TABLE:
+ {
+ const Table<std::string, AnyVal>& a = *(Table<std::string, AnyVal>*)m_value;
+ t.printf("{\n");
+ t.pushIndent();
+ Table<std::string, AnyVal>::Iterator i = a.begin();
+ const Table<std::string, AnyVal>::Iterator end = a.end();
+ while (i != end) {
+ // Quote names that are not legal C++ identifiers
+ if (! legalIdentifier(i->key)) {
+ t.printf("'%s' ", i->key.c_str());
+ } else {
+ t.writeSymbol(i->key);
+ }
+ t.printf("= ");
+
+ i->value.serialize(t);
+
+ if (i != end) {
+ t.printf("\n");
+ }
+ ++i;
+ }
+ t.popIndent();
+ t.printf("}");
+ }
+ break;
+
+ default:
+ debugAssertM(false, "Internal error: no serialize method for this type.");
+ }
+}
+
+
+std::string AnyVal::toString() const {
+ TextOutput t;
+ serialize(t);
+ std::string s;
+ t.commitString(s);
+ return s;
+}
+
+void AnyVal::deserialize(G3D::TextInput& t) {
+ deleteValue();
+ m_type = NIL;
+ m_value = NULL;
+
+ if (! t.hasMore()) {
+ return;
+ }
+
+ switch (t.peek().type()) {
+ case Token::END:
+ // should never get here because of the hasMore check above
+ return;
+ break;
+
+ case Token::NUMBER:
+ m_type = NUMBER;
+ m_value = new double(t.readNumber());
+ break;
+
+ case Token::STRING:
+ m_type = STRING;
+ m_value = new std::string(t.readString());
+ break;
+
+ case Token::NEWLINE:
+ m_type = STRING;
+ m_value = new std::string(t.readNewline());
+ break;
+
+ case Token::COMMENT:
+ m_type = STRING;
+ m_value = new std::string(t.readComment());
+ break;
+
+ case Token::BOOLEAN:
+ m_type = BOOLEAN;
+ m_value = new bool(t.readBoolean());
+ break;
+
+ case Token::SYMBOL:
+ {
+ std::string s = t.readSymbol();
+ if (s == "NIL") {
+ break;
+
+ } else if (s == "true") {
+
+ m_type = BOOLEAN;
+ m_value = new bool(true);
+
+ } else if (s == "false") {
+
+ m_type = BOOLEAN;
+ m_value = new bool(false);
+
+ } else if (s == "R") {
+
+ m_type = RECT2D;
+ t.readSymbol("(");
+ float x,y,w,h;
+ x = (float)t.readNumber();
+ t.readSymbol(",");
+ y = (float)t.readNumber();
+ t.readSymbol(",");
+ w = (float)t.readNumber();
+ t.readSymbol(",");
+ h = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Rect2D(Rect2D::xywh(x, y, w, h));
+
+ } else if (s == "AAB") {
+
+ m_type = AABOX;
+ Vector3 v[2];
+ t.readSymbol("(");
+ for (int i = 0; i < 2; ++i) {
+ t.readSymbols("V3", "(");
+ v[i].x = (float)t.readNumber();
+ t.readSymbol(",");
+ v[i].y = (float)t.readNumber();
+ t.readSymbol(",");
+ v[i].z = (float)t.readNumber();
+ t.readSymbol(",");
+ if (i == 0) {
+ t.readSymbol(",");
+ }
+ }
+ t.readSymbol(")");
+ m_value = new AABox(v[0], v[1]);
+
+ } else if (s == "V2") {
+
+ t.readSymbol("(");
+ Vector2 v;
+ v.x = (float)t.readNumber();
+ t.readSymbol(",");
+ v.y = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Vector2(v);
+ m_type = VECTOR2;
+
+ } else if (s == "V3") {
+
+ t.readSymbol("(");
+ Vector3 v;
+ v.x = (float)t.readNumber();
+ t.readSymbol(",");
+ v.y = (float)t.readNumber();
+ t.readSymbol(",");
+ v.z = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Vector3(v);
+ m_type = VECTOR3;
+
+ } else if (s == "V4") {
+
+ t.readSymbol("(");
+ Vector4 v;
+ v.x = (float)t.readNumber();
+ t.readSymbol(",");
+ v.y = (float)t.readNumber();
+ t.readSymbol(",");
+ v.z = (float)t.readNumber();
+ t.readSymbol(",");
+ v.w = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Vector4(v);
+ m_type = VECTOR4;
+
+ } else if (s == "M2") {
+
+ t.readSymbol("(");
+ Matrix2 m;
+ for (int r = 0; r < 2; ++r) {
+ for (int c = 0; c < 2; ++c) {
+ m[r][c] = (float)t.readNumber();
+ if ((c != 1) || (r != 1)) {
+ t.readSymbol(",");
+ }
+ }
+ }
+ t.readSymbol(")");
+ m_value = new Matrix2(m);
+ m_type = MATRIX2;
+
+ } else if (s == "M3") {
+
+ t.readSymbol("(");
+ Matrix3 m;
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ m[r][c] = (float)t.readNumber();
+ if ((c != 2) || (r != 2)) {
+ t.readSymbol(",");
+ }
+ }
+ }
+ t.readSymbol(")");
+ m_value = new Matrix3(m);
+ m_type = MATRIX3;
+
+ } else if (s == "M4") {
+
+ t.readSymbol("(");
+ Matrix4 m;
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ m[r][c] = (float)t.readNumber();
+ if ((c != 3) || (r != 3)) {
+ t.readSymbol(",");
+ }
+ }
+ }
+ t.readSymbol(")");
+ m_value = new Matrix4(m);
+ m_type = MATRIX4;
+
+ } else if (s == "Q") {
+
+ t.readSymbol("(");
+ Quat q;
+ q.x = (float)t.readNumber();
+ t.readSymbol(",");
+ q.y = (float)t.readNumber();
+ t.readSymbol(",");
+ q.z = (float)t.readNumber();
+ t.readSymbol(",");
+ q.w = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Quat(q);
+ m_type = QUAT;
+
+ } else if (s == "CF") {
+
+ t.readSymbol("(");
+ CoordinateFrame m;
+ if (t.peek().type() == Token::SYMBOL) {
+ // Angle format
+ float x, y, z, yaw, roll, pitch;
+ t.readSymbols("V3", "(");
+ x = (float)t.readNumber();
+ t.readSymbol(",");
+ y = (float)t.readNumber();
+ t.readSymbol(",");
+ z = (float)t.readNumber();
+ t.readSymbols(")", ",");
+ yaw = (float)t.readNumber();
+ t.readSymbol(",");
+ pitch = (float)t.readNumber();
+ roll = 0;
+ if (t.peek().string() == ",") {
+ t.readSymbol(",");
+ roll = (float)t.readNumber();
+ }
+ m = CoordinateFrame::fromXYZYPRDegrees(x, y, z, yaw, pitch, roll);
+ } else {
+ // Matrix format
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ m.rotation[r][c] = (float)t.readNumber();
+ }
+ m.translation[r] = (float)t.readNumber();
+ if (r != 2) {
+ t.readSymbol(",");
+ }
+ }
+ }
+ t.readSymbol(")");
+ m_value = new CoordinateFrame(m);
+ m_type = COORDINATEFRAME;
+
+ } else if (s == "C1") {
+
+ t.readSymbol("(");
+ float v = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Color1(v);
+ m_type = COLOR1;
+
+ } else if (s == "C3") {
+
+ t.readSymbol("(");
+ Color3 c;
+ c.r = (float)t.readNumber();
+ t.readSymbol(",");
+ c.g = (float)t.readNumber();
+ t.readSymbol(",");
+ c.b = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Color3(c);
+ m_type = COLOR3;
+
+ } else if (s == "C4") {
+
+ t.readSymbol("(");
+ Color4 c;
+ c.r = (float)t.readNumber();
+ t.readSymbol(",");
+ c.g = (float)t.readNumber();
+ t.readSymbol(",");
+ c.b = (float)t.readNumber();
+ t.readSymbol(",");
+ c.a = (float)t.readNumber();
+ t.readSymbol(")");
+ m_value = new Color4(c);
+ m_type = COLOR4;
+
+ } else if (s == "[") {
+
+ // Array
+ m_type = ARRAY;
+ m_value = new Array<AnyVal>();
+ m_referenceCount = new int(1);
+ Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
+
+ Token peek = t.peek();
+ while ((peek.type() != Token::SYMBOL) || (peek.string() != "]")) {
+ // Avoid copying large objects
+ a.next().deserialize(t);
+
+ peek = t.peek();
+ if (peek.type() != Token::SYMBOL) {
+ throw CorruptText("Expected ',' or ']'", peek);
+ } else if (peek.string() == ",") {
+ t.readSymbol(",");
+ } else if (peek.string() != "]") {
+ throw CorruptText("Missing ']'", peek);
+ }
+ }
+ t.readSymbol("]");
+
+ } else if (s == "{") {
+
+ // Table
+ m_type = TABLE;
+ m_value = new Table<std::string, AnyVal>();
+ m_referenceCount = new int(1);
+ Table<std::string, AnyVal>& a = *(Table<std::string, AnyVal>*)m_value;
+
+ Token peek = t.peek();
+ while ((peek.type() != Token::SYMBOL) || (peek.string() != "}")) {
+
+ std::string key;
+ // Get the name
+ if (peek.type() == Token::SYMBOL) {
+ key = t.readSymbol();
+ } else if (peek.extendedType() == Token::SINGLE_QUOTED_TYPE) {
+ key = t.readString();
+ } else {
+ throw CorruptText("Expected name inside table", peek);
+ }
+
+ t.readSymbol("=");
+
+ // Avoid copying large values
+ a.set(key, AnyVal());
+ a[key].deserialize(t);
+
+ peek = t.peek();
+ if ((peek.type() != Token::SYMBOL) && (peek.extendedType() != Token::SINGLE_QUOTED_TYPE)) {
+ throw CorruptText("Missing expected name or '}'", peek);
+ }
+ }
+ t.readSymbol("}");
+
+ } else {
+ throw CorruptText("Invalid value type.", t.peek());
+ } // dispatch on symbol type
+ } // scope
+ break;
+ }
+}
+
+
+AnyVal& AnyVal::operator[](const char* key) {
+ return this->operator[]((std::string)key);
+}
+
+
+const AnyVal& AnyVal::operator[](const char* key) const {
+ return this->operator[]((std::string)key);
+}
+
+
+AnyVal& AnyVal::operator[](const std::string& key) {
+ if (m_type != TABLE) {
+ throw WrongType(TABLE, m_type);
+ }
+
+ makeMutable();
+
+ Table<std::string, AnyVal>& t = *(Table<std::string, AnyVal>*)m_value;
+
+ if (! t.containsKey(key)) {
+ t.set(key, AnyVal());
+ }
+
+ return t[key];
+}
+
+
+const AnyVal& AnyVal::operator[](const std::string& key) const {
+ if (m_type != TABLE) {
+ throw WrongType(TABLE, m_type);
+ }
+
+ const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
+
+ if (! t.containsKey(key)) {
+ throw KeyNotFound(key);
+ }
+
+ return t[key];
+}
+
+
+void AnyVal::append(const AnyVal& v) {
+ if (m_type != ARRAY) {
+ throw WrongType(ARRAY, m_type);
+ }
+ makeMutable();
+
+ Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
+ a.append(v);
+}
+
+
+void AnyVal::getKeys(Array<std::string>& keys) const {
+ if (m_type != TABLE) {
+ throw WrongType(TABLE, m_type);
+ }
+
+ const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
+ t.getKeys(keys);
+}
+
+
+int AnyVal::size() const {
+ switch (m_type) {
+ case TABLE:
+ {
+ const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
+ return t.size();
+ }
+
+ case ARRAY:
+ {
+ const Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
+ return a.size();
+ }
+
+ default:
+ throw WrongType(ARRAY, m_type);
+ }
+}
+
+
+AnyVal& AnyVal::operator[](int i) {
+ if (m_type != ARRAY) {
+ throw WrongType(ARRAY, m_type);
+ }
+ makeMutable();
+
+ Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
+
+ if (i < 0) {
+ throw IndexOutOfBounds(i, a.size());
+ }
+
+ if (a.size() <= i) {
+ a.resize(i + 1);
+ }
+
+ return a[i];
+}
+
+
+const AnyVal& AnyVal::operator[](int i) const {
+ if (m_type != ARRAY) {
+ throw WrongType(ARRAY, m_type);
+ }
+
+ const Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
+
+ if (a.size() <= i || i < 0) {
+ throw IndexOutOfBounds(i, a.size());
+ }
+
+ return a[i];
+}
+
+
+void AnyVal::makeMutable() {
+ if (*m_referenceCount > 1) {
+ // This is a shared instance
+ --(*m_referenceCount);
+ m_referenceCount = new int(1);
+ m_value = copyValue();
+ }
+}
+
+bool AnyVal::boolean() const {
+ if (m_type != BOOLEAN) {
+ throw WrongType(BOOLEAN, m_type);
+ }
+
+ return *(bool*)m_value;
+}
+
+
+bool AnyVal::boolean(bool defaultVal) const {
+ if (m_type != BOOLEAN) {
+ return defaultVal;
+ }
+
+ return *(bool*)m_value;
+}
+
+
+const std::string& AnyVal::string() const {
+ if (m_type != STRING) {
+ throw WrongType(STRING, m_type);
+ }
+
+ return *(std::string*)m_value;
+}
+
+
+const std::string& AnyVal::string(const std::string& defaultVal) const {
+ if (m_type != STRING) {
+ return defaultVal;
+ } else {
+ return *(std::string*)m_value;
+ }
+}
+
+
+double AnyVal::number() const {
+ if (m_type != NUMBER) {
+ throw WrongType(NUMBER, m_type);
+ }
+
+ return *(double*)m_value;
+}
+
+
+double AnyVal::number(double defaultVal) const {
+ if (m_type != NUMBER) {
+ return defaultVal;
+ } else {
+ return *(double*)m_value;
+ }
+}
+
+
+const Rect2D& AnyVal::rect2D() const {
+ if (m_type != RECT2D) {
+ throw WrongType(RECT2D, m_type);
+ }
+
+ return *(Rect2D*)m_value;
+}
+
+
+const Rect2D& AnyVal::rect2D(const Rect2D& defaultVal) const {
+ if (m_type != RECT2D) {
+ return defaultVal;
+ } else {
+ return *(Rect2D*)m_value;
+ }
+}
+
+
+const AABox& AnyVal::aabox() const {
+ if (m_type != AABOX) {
+ throw WrongType(AABOX, m_type);
+ }
+
+ return *(AABox*)m_value;
+}
+
+
+const AABox& AnyVal::aabox(const AABox& defaultVal) const {
+ if (m_type != AABOX) {
+ return defaultVal;
+ } else {
+ return *(AABox*)m_value;
+ }
+}
+
+
+const Color1& AnyVal::color1() const {
+ if (m_type != COLOR1) {
+ throw WrongType(COLOR1, m_type);
+ }
+
+ return *(Color1*)m_value;
+}
+
+
+const Color1& AnyVal::color1(const Color1& defaultVal) const {
+ if (m_type != COLOR1) {
+ return defaultVal;
+ } else {
+ return *(Color1*)m_value;
+ }
+}
+
+
+const Color3& AnyVal::color3() const {
+ if (m_type != COLOR3) {
+ throw WrongType(COLOR3, m_type);
+ }
+
+ return *(Color3*)m_value;
+}
+
+
+const Color3& AnyVal::color3(const Color3& defaultVal) const {
+ if (m_type != COLOR3) {
+ return defaultVal;
+ } else {
+ return *(Color3*)m_value;
+ }
+}
+
+
+const Color4& AnyVal::color4() const {
+ if (m_type != COLOR4) {
+ throw WrongType(COLOR4, m_type);
+ }
+
+ return *(Color4*)m_value;
+}
+
+
+const Color4& AnyVal::color4(const Color4& defaultVal) const {
+ if (m_type != COLOR4) {
+ return defaultVal;
+ } else {
+ return *(Color4*)m_value;
+ }
+}
+
+
+const Vector2& AnyVal::vector2() const {
+ if (m_type != VECTOR2) {
+ throw WrongType(VECTOR2, m_type);
+ }
+
+ return *(Vector2*)m_value;
+}
+
+
+const Vector2& AnyVal::vector2(const Vector2& defaultVal) const {
+ if (m_type != VECTOR2) {
+ return defaultVal;
+ } else {
+ return *(Vector2*)m_value;
+ }
+}
+
+
+const Vector3& AnyVal::vector3() const {
+ if (m_type != VECTOR3) {
+ throw WrongType(VECTOR3, m_type);
+ }
+
+ return *(Vector3*)m_value;
+}
+
+
+const Vector3& AnyVal::vector3(const Vector3& defaultVal) const {
+ if (m_type != VECTOR3) {
+ return defaultVal;
+ } else {
+ return *(Vector3*)m_value;
+ }
+}
+
+
+const Vector4& AnyVal::vector4() const {
+ if (m_type != VECTOR4) {
+ throw WrongType(VECTOR4, m_type);
+ }
+
+ return *(Vector4*)m_value;
+}
+
+
+const Vector4& AnyVal::vector4(const Vector4& defaultVal) const {
+ if (m_type != VECTOR4) {
+ return defaultVal;
+ } else {
+ return *(Vector4*)m_value;
+ }
+}
+
+
+const CoordinateFrame& AnyVal::coordinateFrame() const {
+ if (m_type != COORDINATEFRAME) {
+ throw WrongType(COORDINATEFRAME, m_type);
+ }
+
+ return *(CoordinateFrame*)m_value;
+}
+
+
+const CoordinateFrame& AnyVal::coordinateFrame(const CoordinateFrame& defaultVal) const {
+ if (m_type != COORDINATEFRAME) {
+ return defaultVal;
+ } else {
+ return *(CoordinateFrame*)m_value;
+ }
+}
+
+const Matrix2& AnyVal::matrix2(const Matrix2& defaultVal) const {
+ if (m_type != MATRIX2) {
+ return defaultVal;
+ } else {
+ return *(Matrix2*)m_value;
+ }
+}
+
+
+const Matrix2& AnyVal::matrix2() const {
+ if (m_type != MATRIX2) {
+ throw WrongType(MATRIX2, m_type);
+ }
+
+ return *(Matrix2*)m_value;
+}
+
+
+const Matrix3& AnyVal::matrix3(const Matrix3& defaultVal) const {
+ if (m_type != MATRIX3) {
+ return defaultVal;
+ } else {
+ return *(Matrix3*)m_value;
+ }
+}
+
+
+const Matrix3& AnyVal::matrix3() const {
+ if (m_type != MATRIX3) {
+ throw WrongType(MATRIX3, m_type);
+ }
+
+ return *(Matrix3*)m_value;
+}
+
+
+const Matrix4& AnyVal::matrix4(const Matrix4& defaultVal) const {
+ if (m_type != MATRIX4) {
+ return defaultVal;
+ } else {
+ return *(Matrix4*)m_value;
+ }
+}
+
+
+const Matrix4& AnyVal::matrix4() const {
+ if (m_type != MATRIX4) {
+ throw WrongType(MATRIX4, m_type);
+ }
+
+ return *(Matrix4*)m_value;
+}
+
+
+const Quat& AnyVal::quat(const Quat& defaultVal) const {
+ if (m_type != QUAT) {
+ return defaultVal;
+ } else {
+ return *(Quat*)m_value;
+ }
+}
+
+
+const Quat& AnyVal::quat() const {
+ if (m_type != QUAT) {
+ throw WrongType(QUAT, m_type);
+ }
+
+ return *(Quat*)m_value;
+}
+
+
+const AnyVal& AnyVal::get(const std::string& key, const AnyVal& defaultVal) const {
+ if (m_type != TABLE) {
+ return defaultVal;
+ }
+
+ const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
+
+ if (t.containsKey(key)) {
+ return t[key];
+ } else {
+ return defaultVal;
+ }
+}
+
+
+const AnyVal& AnyVal::get(const std::string& key) const {
+ if (m_type != TABLE) {
+ throw WrongType(TABLE, m_type);
+ }
+
+ const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
+
+ if (t.containsKey(key)) {
+ return t[key];
+ } else {
+ throw KeyNotFound(key);
+ }
+}
+
+
+const AnyVal& AnyVal::get(int i, const AnyVal& defaultVal) const {
+ if (m_type != ARRAY) {
+ return defaultVal;
+ }
+
+ const Array<AnyVal>& a = *(const Array<AnyVal>*)m_value;
+
+ if ((i >= 0) && (i < a.size())) {
+ return a[i];
+ } else {
+ return defaultVal;
+ }
+}
+
+
+const AnyVal& AnyVal::get(int i) const {
+ if (m_type != ARRAY) {
+ throw WrongType(ARRAY, m_type);
+ }
+
+ const Array<AnyVal>& a = *(const Array<AnyVal>*)m_value;
+
+ if ((i >= 0) && (i < a.size())) {
+ return a[i];
+ } else {
+ throw IndexOutOfBounds(i, a.size());
+ }
+}
+
+}
diff --git a/dep/src/g3dlite/AreaMemoryManager.cpp b/dep/src/g3dlite/AreaMemoryManager.cpp
new file mode 100644
index 00000000000..00cb33dc91f
--- /dev/null
+++ b/dep/src/g3dlite/AreaMemoryManager.cpp
@@ -0,0 +1,87 @@
+/**
+ @file AreaMemoryManager.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-01-20
+ @edited 2009-01-20
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/AreaMemoryManager.h"
+#include "G3D/System.h"
+
+namespace G3D {
+
+AreaMemoryManager::Buffer::Buffer(size_t size) : m_size(size), m_used(0) {
+ // Allocate space for a lot of buffers.
+ m_first = (uint8*)::malloc(m_size);
+}
+
+
+AreaMemoryManager::Buffer::~Buffer() {
+ ::free(m_first);
+}
+
+
+void* AreaMemoryManager::Buffer::alloc(size_t s) {
+ if (s + m_used > m_size) {
+ return NULL;
+ } else {
+ void* old = m_first + m_used;
+ m_used += s;
+ return old;
+ }
+}
+
+
+bool AreaMemoryManager::isThreadsafe() const {
+ return false;
+}
+
+
+AreaMemoryManager::Ref AreaMemoryManager::create(size_t sizeHint) {
+ return new AreaMemoryManager(sizeHint);
+}
+
+
+AreaMemoryManager::AreaMemoryManager(size_t sizeHint) : m_sizeHint(sizeHint) {
+ debugAssert(sizeHint > 0);
+}
+
+
+AreaMemoryManager::~AreaMemoryManager() {
+ deallocateAll();
+}
+
+
+size_t AreaMemoryManager::bytesAllocated() const {
+ return m_sizeHint * m_bufferArray.size();
+}
+
+
+void* AreaMemoryManager::alloc(size_t s) {
+ void* n = (m_bufferArray.size() > 0) ? m_bufferArray.last()->alloc(s) : NULL;
+ if (n == NULL) {
+ // This buffer is full
+ m_bufferArray.append(new Buffer(max(s, m_sizeHint)));
+ return m_bufferArray.last()->alloc(s);
+ } else {
+ return n;
+ }
+}
+
+
+void AreaMemoryManager::free(void* x) {
+ // Intentionally empty; we block deallocate
+}
+
+
+void AreaMemoryManager::deallocateAll() {
+ m_bufferArray.deleteAll();
+ m_bufferArray.clear();
+}
+
+}
diff --git a/dep/src/g3dlite/BinaryFormat.cpp b/dep/src/g3dlite/BinaryFormat.cpp
new file mode 100644
index 00000000000..d3991378f45
--- /dev/null
+++ b/dep/src/g3dlite/BinaryFormat.cpp
@@ -0,0 +1,81 @@
+/**
+ @file BinaryFormat.cpp
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2005-06-10
+ @edited 2005-06-10
+ */
+
+#include "G3D/BinaryFormat.h"
+
+namespace G3D {
+
+int32 byteSize(BinaryFormat f) {
+ switch (f) {
+ case BOOL8_BINFMT:
+ case UINT8_BINFMT:
+ case INT8_BINFMT:
+ return 1;
+
+ case UINT16_BINFMT:
+ case INT16_BINFMT:
+ return 2;
+
+ case FLOAT16_BINFMT:
+ return 2;
+
+ case UINT32_BINFMT:
+ case INT32_BINFMT:
+ case FLOAT32_BINFMT:
+ return 4;
+
+ case FLOAT64_BINFMT:
+ case UINT64_BINFMT:
+ case INT64_BINFMT:
+ return 8;
+
+ case INT128_BINFMT:
+ case UINT128_BINFMT:
+ return 16;
+
+ case VECTOR2_BINFMT:
+ return 2 * 4;
+
+ case VECTOR2INT16_BINFMT:
+ return 2 * 2;
+
+ case VECTOR3_BINFMT:
+ return 3 * 4;
+
+ case VECTOR3INT16_BINFMT:
+ return 3 * 2;
+
+ case VECTOR4_BINFMT:
+ return 4 * 4;
+
+ case VECTOR4INT16_BINFMT:
+ return 4 * 4;
+
+ case COLOR3_BINFMT:
+ return 3 * 4;
+
+ case COLOR3UINT8_BINFMT:
+ return 3 * 1;
+
+ case COLOR3INT16_BINFMT:
+ return 3 * 2;
+
+ case COLOR4_BINFMT:
+ return 4 * 4;
+
+ case COLOR4UINT8_BINFMT:
+ return 4 * 1;
+
+ case COLOR4INT16_BINFMT:
+ return 4 * 2;
+
+ default:
+ return -1;
+ }
+}
+}
diff --git a/dep/src/g3dlite/BinaryInput.cpp b/dep/src/g3dlite/BinaryInput.cpp
new file mode 100644
index 00000000000..65a9976fe04
--- /dev/null
+++ b/dep/src/g3dlite/BinaryInput.cpp
@@ -0,0 +1,568 @@
+/**
+ @file BinaryInput.cpp
+
+ @author Morgan McGuire, graphics3d.com
+ Copyright 2001-2007, Morgan McGuire. All rights reserved.
+
+ @created 2001-08-09
+ @edited 2005-02-24
+
+
+ <PRE>
+ {
+ BinaryOutput b("c:/tmp/test.b", BinaryOutput::LITTLE_ENDIAN);
+
+ float f = 3.1415926;
+ int i = 1027221;
+ std::string s = "Hello World!";
+
+ b.writeFloat32(f);
+ b.writeInt32(i);
+ b.writeString(s);
+ b.commit();
+
+
+ BinaryInput in("c:/tmp/test.b", BinaryInput::LITTLE_ENDIAN);
+
+ debugAssert(f == in.readFloat32());
+ int ii = in.readInt32();
+ debugAssert(i == ii);
+ debugAssert(s == in.readString());
+ }
+ </PRE>
+ */
+
+#include "G3D/platform.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/Array.h"
+#include "G3D/fileutils.h"
+#include "G3D/Log.h"
+#include <zlib.h>
+
+#include <cstring>
+
+namespace G3D {
+
+void BinaryInput::readBool8(std::vector<bool>& out, int64 n) {
+ out.resize((int)n);
+ // std::vector optimizes bool in a way that prevents fast reading
+ for (int64 i = 0; i < n ; ++i) {
+ out[i] = readBool8();
+ }
+}
+
+
+void BinaryInput::readBool8(Array<bool>& out, int64 n) {
+ out.resize(n);
+ readBool8(out.begin(), n);
+}
+
+
+#define IMPLEMENT_READER(ucase, lcase)\
+void BinaryInput::read##ucase(std::vector<lcase>& out, int64 n) {\
+ out.resize(n);\
+ read##ucase(&out[0], n);\
+}\
+\
+\
+void BinaryInput::read##ucase(Array<lcase>& out, int64 n) {\
+ out.resize(n);\
+ read##ucase(out.begin(), n);\
+}
+
+
+IMPLEMENT_READER(UInt8, uint8)
+IMPLEMENT_READER(Int8, int8)
+IMPLEMENT_READER(UInt16, uint16)
+IMPLEMENT_READER(Int16, int16)
+IMPLEMENT_READER(UInt32, uint32)
+IMPLEMENT_READER(Int32, int32)
+IMPLEMENT_READER(UInt64, uint64)
+IMPLEMENT_READER(Int64, int64)
+IMPLEMENT_READER(Float32, float32)
+IMPLEMENT_READER(Float64, float64)
+
+#undef IMPLEMENT_READER
+
+// Data structures that are one byte per element can be
+// directly copied, regardles of endian-ness.
+#define IMPLEMENT_READER(ucase, lcase)\
+void BinaryInput::read##ucase(lcase* out, int64 n) {\
+ if (sizeof(lcase) == 1) {\
+ readBytes(out, n);\
+ } else {\
+ for (int64 i = 0; i < n ; ++i) {\
+ out[i] = read##ucase();\
+ }\
+ }\
+}
+
+IMPLEMENT_READER(Bool8, bool)
+IMPLEMENT_READER(UInt8, uint8)
+IMPLEMENT_READER(Int8, int8)
+
+#undef IMPLEMENT_READER
+
+
+#define IMPLEMENT_READER(ucase, lcase)\
+void BinaryInput::read##ucase(lcase* out, int64 n) {\
+ if (m_swapBytes) {\
+ for (int64 i = 0; i < n; ++i) {\
+ out[i] = read##ucase();\
+ }\
+ } else {\
+ readBytes(out, sizeof(lcase) * n);\
+ }\
+}
+
+
+IMPLEMENT_READER(UInt16, uint16)
+IMPLEMENT_READER(Int16, int16)
+IMPLEMENT_READER(UInt32, uint32)
+IMPLEMENT_READER(Int32, int32)
+IMPLEMENT_READER(UInt64, uint64)
+IMPLEMENT_READER(Int64, int64)
+IMPLEMENT_READER(Float32, float32)
+IMPLEMENT_READER(Float64, float64)
+
+#undef IMPLEMENT_READER
+
+void BinaryInput::loadIntoMemory(int64 startPosition, int64 minLength) {
+ // Load the next section of the file
+ debugAssertM(m_filename != "<memory>", "Read past end of file.");
+
+ int64 absPos = m_alreadyRead + m_pos;
+
+ if (m_bufferLength < minLength) {
+ // The current buffer isn't big enough to hold the chunk we want to read.
+ // This happens if there was little memory available during the initial constructor
+ // read but more memory has since been freed.
+ m_bufferLength = minLength;
+ debugAssert(m_freeBuffer);
+ m_buffer = (uint8*)System::realloc(m_buffer, m_bufferLength);
+ if (m_buffer == NULL) {
+ throw "Tried to read a larger memory chunk than could fit in memory. (2)";
+ }
+ }
+
+ m_alreadyRead = startPosition;
+
+# ifdef G3D_WIN32
+ FILE* file = fopen(m_filename.c_str(), "rb");
+ debugAssert(file);
+ int ret = fseek(file, (off_t)m_alreadyRead, SEEK_SET);
+ debugAssert(ret == 0);
+ size_t toRead = (size_t)G3D::min(m_bufferLength, m_length - m_alreadyRead);
+ ret = fread(m_buffer, 1, toRead, file);
+ debugAssert(ret == toRead);
+ fclose(file);
+ file = NULL;
+
+# else
+ FILE* file = fopen(m_filename.c_str(), "rb");
+ debugAssert(file);
+ int ret = fseeko(file, (off_t)m_alreadyRead, SEEK_SET);
+ debugAssert(ret == 0);
+ size_t toRead = (size_t)G3D::min<int64>(m_bufferLength, m_length - m_alreadyRead);
+ ret = fread(m_buffer, 1, toRead, file);
+ debugAssert((size_t)ret == (size_t)toRead);
+ fclose(file);
+ file = NULL;
+# endif
+
+ m_pos = absPos - m_alreadyRead;
+ debugAssert(m_pos >= 0);
+}
+
+
+
+const bool BinaryInput::NO_COPY = false;
+
+static bool needSwapBytes(G3DEndian fileEndian) {
+ return (fileEndian != System::machineEndian());
+}
+
+
+/** Helper used by the constructors for decompression */
+static uint32 readUInt32(const uint8* data, bool swapBytes) {
+ if (swapBytes) {
+ uint8 out[4];
+ out[0] = data[3];
+ out[1] = data[2];
+ out[2] = data[1];
+ out[3] = data[0];
+ return *((uint32*)out);
+ } else {
+ return *((uint32*)data);
+ }
+}
+
+
+void BinaryInput::setEndian(G3DEndian e) {
+ m_fileEndian = e;
+ m_swapBytes = needSwapBytes(m_fileEndian);
+}
+
+
+BinaryInput::BinaryInput(
+ const uint8* data,
+ int64 dataLen,
+ G3DEndian dataEndian,
+ bool compressed,
+ bool copyMemory) :
+ m_filename("<memory>"),
+ m_bitPos(0),
+ m_bitString(0),
+ m_beginEndBits(0),
+ m_alreadyRead(0),
+ m_bufferLength(0),
+ m_pos(0) {
+
+ m_freeBuffer = copyMemory || compressed;
+
+ setEndian(dataEndian);
+
+ if (compressed) {
+ // Read the decompressed size from the first 4 bytes
+ m_length = G3D::readUInt32(data, m_swapBytes);
+
+ debugAssert(m_freeBuffer);
+ m_buffer = (uint8*)System::alignedMalloc(m_length, 16);
+
+ unsigned long L = m_length;
+ // Decompress with zlib
+ int64 result = uncompress(m_buffer, (unsigned long*)&L, data + 4, dataLen - 4);
+ m_length = L;
+ m_bufferLength = L;
+ debugAssert(result == Z_OK); (void)result;
+
+ } else {
+ m_length = dataLen;
+ m_bufferLength = m_length;
+ if (! copyMemory) {
+ debugAssert(!m_freeBuffer);
+ m_buffer = const_cast<uint8*>(data);
+ } else {
+ debugAssert(m_freeBuffer);
+ m_buffer = (uint8*)System::alignedMalloc(m_length, 16);
+ System::memcpy(m_buffer, data, dataLen);
+ }
+ }
+}
+
+
+BinaryInput::BinaryInput(
+ const std::string& filename,
+ G3DEndian fileEndian,
+ bool compressed) :
+ m_filename(filename),
+ m_bitPos(0),
+ m_bitString(0),
+ m_beginEndBits(0),
+ m_alreadyRead(0),
+ m_length(0),
+ m_bufferLength(0),
+ m_buffer(NULL),
+ m_pos(0),
+ m_freeBuffer(true) {
+
+ setEndian(fileEndian);
+
+ // Update global file tracker
+ _internal::currentFilesUsed.insert(m_filename);
+
+
+ if (! fileExists(m_filename, false)) {
+ std::string zipfile;
+ std::string internalfile;
+ if (zipfileExists(m_filename, zipfile, internalfile)) {
+ // Load from zipfile
+ void* v;
+ size_t s;
+ zipRead(filename, v, s);
+ m_buffer = reinterpret_cast<uint8*>(v);
+ m_bufferLength = m_length = s;
+ if (compressed) {
+ decompress();
+ }
+ m_freeBuffer = true;
+ } else {
+ Log::common()->printf("Warning: File not found: %s\n", m_filename.c_str());
+ }
+ return;
+ }
+
+ // Figure out how big the file is and verify that it exists.
+ m_length = fileLength(m_filename);
+
+ // Read the file into memory
+ FILE* file = fopen(m_filename.c_str(), "rb");
+
+ if (! file || (m_length == -1)) {
+ throw format("File not found: \"%s\"", m_filename.c_str());
+ return;
+ }
+
+ if (! compressed && (m_length > INITIAL_BUFFER_LENGTH)) {
+ // Read only a subset of the file so we don't consume
+ // all available memory.
+ m_bufferLength = INITIAL_BUFFER_LENGTH;
+ } else {
+ // Either the length is fine or the file is compressed
+ // and requires us to read the whole thing for zlib.
+ m_bufferLength = m_length;
+ }
+
+ debugAssert(m_freeBuffer);
+ m_buffer = (uint8*)System::alignedMalloc(m_bufferLength, 16);
+ if (m_buffer == NULL) {
+ if (compressed) {
+ throw "Not enough memory to load compressed file. (1)";
+ }
+
+ // Try to allocate a small array; not much memory is available.
+ // Give up if we can't allocate even 1k.
+ while ((m_buffer == NULL) && (m_bufferLength > 1024)) {
+ m_bufferLength /= 2;
+ m_buffer = (uint8*)System::alignedMalloc(m_bufferLength, 16);
+ }
+ }
+ debugAssert(m_buffer);
+
+ fread(m_buffer, m_bufferLength, sizeof(int8), file);
+ fclose(file);
+ file = NULL;
+
+ if (compressed) {
+ if (m_bufferLength != m_length) {
+ throw "Not enough memory to load compressed file. (2)";
+ }
+
+ decompress();
+ }
+}
+
+void BinaryInput::decompress() {
+ // Decompress
+ // Use the existing buffer as the source, allocate
+ // a new buffer to use as the destination.
+
+ int64 tempLength = m_length;
+ m_length = G3D::readUInt32(m_buffer, m_swapBytes);
+
+ // The file couldn't have better than 500:1 compression
+ alwaysAssertM(m_length < m_bufferLength * 500, "Compressed file header is corrupted");
+
+ uint8* tempBuffer = m_buffer;
+ m_buffer = (uint8*)System::alignedMalloc(m_length, 16);
+
+ debugAssert(m_buffer);
+ debugAssert(isValidHeapPointer(tempBuffer));
+ debugAssert(isValidHeapPointer(m_buffer));
+
+ unsigned long L = m_length;
+ int64 result = uncompress(m_buffer, &L, tempBuffer + 4, tempLength - 4);
+ m_length = L;
+ m_bufferLength = m_length;
+
+ debugAssertM(result == Z_OK, "BinaryInput/zlib detected corruption in " + m_filename);
+ (void)result;
+
+ System::alignedFree(tempBuffer);
+}
+
+
+void BinaryInput::readBytes(void* bytes, int64 n) {
+ prepareToRead(n);
+ debugAssert(isValidPointer(bytes));
+
+ memcpy(bytes, m_buffer + m_pos, n);
+ m_pos += n;
+}
+
+
+BinaryInput::~BinaryInput() {
+
+ if (m_freeBuffer) {
+ System::alignedFree(m_buffer);
+ }
+ m_buffer = NULL;
+}
+
+
+uint64 BinaryInput::readUInt64() {
+ prepareToRead(8);
+ uint8 out[8];
+
+ if (m_swapBytes) {
+ out[0] = m_buffer[m_pos + 7];
+ out[1] = m_buffer[m_pos + 6];
+ out[2] = m_buffer[m_pos + 5];
+ out[3] = m_buffer[m_pos + 4];
+ out[4] = m_buffer[m_pos + 3];
+ out[5] = m_buffer[m_pos + 2];
+ out[6] = m_buffer[m_pos + 1];
+ out[7] = m_buffer[m_pos + 0];
+ } else {
+ *(uint64*)out = *(uint64*)(m_buffer + m_pos);
+ }
+
+ m_pos += 8;
+ return *(uint64*)out;
+}
+
+
+std::string BinaryInput::readString(int64 n) {
+ prepareToRead(n);
+ debugAssertM((m_pos + n) <= m_length, "Read past end of file");
+
+ char *s = (char*)System::alignedMalloc(n + 1, 16);
+ assert(s != NULL);
+
+ memcpy(s, m_buffer + m_pos, n);
+ // There may not be a null, so make sure
+ // we add one.
+ s[n] = '\0';
+
+ std::string out = s;
+ System::alignedFree(s);
+ s = NULL;
+
+ m_pos += n;
+
+ return out;
+
+}
+
+
+std::string BinaryInput::readString() {
+ int64 n = 0;
+
+ if ((m_pos + m_alreadyRead + n) < (m_length - 1)) {
+ prepareToRead(1);
+ }
+
+ if ( ((m_pos + m_alreadyRead + n) < (m_length - 1)) &&
+ (m_buffer[m_pos + n] != '\0')) {
+
+ ++n;
+ while ( ((m_pos + m_alreadyRead + n) < (m_length - 1)) &&
+ (m_buffer[m_pos + n] != '\0')) {
+
+ prepareToRead(1);
+ ++n;
+ }
+ }
+
+ // Consume NULL
+ ++n;
+
+ return readString(n);
+}
+
+
+std::string BinaryInput::readStringEven() {
+ std::string x = readString();
+ if (hasMore() && (G3D::isOdd(x.length() + 1))) {
+ skip(1);
+ }
+ return x;
+}
+
+
+std::string BinaryInput::readString32() {
+ int len = readUInt32();
+ return readString(len);
+}
+
+
+Vector4 BinaryInput::readVector4() {
+ float x = readFloat32();
+ float y = readFloat32();
+ float z = readFloat32();
+ float w = readFloat32();
+ return Vector4(x, y, z, w);
+}
+
+
+Vector3 BinaryInput::readVector3() {
+ float x = readFloat32();
+ float y = readFloat32();
+ float z = readFloat32();
+ return Vector3(x, y, z);
+}
+
+
+Vector2 BinaryInput::readVector2() {
+ float x = readFloat32();
+ float y = readFloat32();
+ return Vector2(x, y);
+}
+
+
+Color4 BinaryInput::readColor4() {
+ float r = readFloat32();
+ float g = readFloat32();
+ float b = readFloat32();
+ float a = readFloat32();
+ return Color4(r, g, b, a);
+}
+
+
+Color3 BinaryInput::readColor3() {
+ float r = readFloat32();
+ float g = readFloat32();
+ float b = readFloat32();
+ return Color3(r, g, b);
+}
+
+
+void BinaryInput::beginBits() {
+ debugAssert(m_beginEndBits == 0);
+ m_beginEndBits = 1;
+ m_bitPos = 0;
+
+ debugAssertM(hasMore(), "Can't call beginBits when at the end of a file");
+ m_bitString = readUInt8();
+}
+
+
+uint32 BinaryInput::readBits(int numBits) {
+ debugAssert(m_beginEndBits == 1);
+
+ uint32 out = 0;
+
+ const int total = numBits;
+ while (numBits > 0) {
+ if (m_bitPos > 7) {
+ // Consume a new byte for reading. We do this at the beginning
+ // of the loop so that we don't try to read past the end of the file.
+ m_bitPos = 0;
+ m_bitString = readUInt8();
+ }
+
+ // Slide the lowest bit of the bitString into
+ // the correct position.
+ out |= (m_bitString & 1) << (total - numBits);
+
+ // Shift over to the next bit
+ m_bitString = m_bitString >> 1;
+ ++m_bitPos;
+ --numBits;
+ }
+
+ return out;
+}
+
+
+void BinaryInput::endBits() {
+ debugAssert(m_beginEndBits == 1);
+ if (m_bitPos == 0) {
+ // Put back the last byte we read
+ --m_pos;
+ }
+ m_beginEndBits = 0;
+ m_bitPos = 0;
+}
+
+}
diff --git a/dep/src/g3dlite/BinaryOutput.cpp b/dep/src/g3dlite/BinaryOutput.cpp
new file mode 100644
index 00000000000..2de46c6d4bb
--- /dev/null
+++ b/dep/src/g3dlite/BinaryOutput.cpp
@@ -0,0 +1,522 @@
+/**
+ @file BinaryOutput.cpp
+
+ @author Morgan McGuire, graphics3d.com
+ Copyright 2002-2007, Morgan McGuire, All rights reserved.
+
+ @created 2002-02-20
+ @edited 2008-01-07
+ */
+
+#include "G3D/platform.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/fileutils.h"
+#include "G3D/stringutils.h"
+#include "G3D/Array.h"
+#include <zlib.h>
+
+#include <cstring>
+
+// Largest memory buffer that the system will use for writing to
+// disk. After this (or if the system runs out of memory)
+// chunks of the file will be dumped to disk.
+//
+// Currently 400 MB
+#define MAX_BINARYOUTPUT_BUFFER_SIZE 400000000
+
+namespace G3D {
+
+void BinaryOutput::writeBool8(const std::vector<bool>& out, int n) {
+ for (int i = 0; i < n; ++i) {
+ writeBool8(out[i]);
+ }
+}
+
+
+void BinaryOutput::writeBool8(const Array<bool>& out, int n) {
+ writeBool8(out.getCArray(), n);
+}
+
+#define IMPLEMENT_WRITER(ucase, lcase)\
+void BinaryOutput::write##ucase(const std::vector<lcase>& out, int n) {\
+ write##ucase(&out[0], n);\
+}\
+\
+\
+void BinaryOutput::write##ucase(const Array<lcase>& out, int n) {\
+ write##ucase(out.getCArray(), n);\
+}
+
+
+IMPLEMENT_WRITER(UInt8, uint8)
+IMPLEMENT_WRITER(Int8, int8)
+IMPLEMENT_WRITER(UInt16, uint16)
+IMPLEMENT_WRITER(Int16, int16)
+IMPLEMENT_WRITER(UInt32, uint32)
+IMPLEMENT_WRITER(Int32, int32)
+IMPLEMENT_WRITER(UInt64, uint64)
+IMPLEMENT_WRITER(Int64, int64)
+IMPLEMENT_WRITER(Float32, float32)
+IMPLEMENT_WRITER(Float64, float64)
+
+#undef IMPLEMENT_WRITER
+
+// Data structures that are one byte per element can be
+// directly copied, regardles of endian-ness.
+#define IMPLEMENT_WRITER(ucase, lcase)\
+void BinaryOutput::write##ucase(const lcase* out, int n) {\
+ if (sizeof(lcase) == 1) {\
+ writeBytes((void*)out, n);\
+ } else {\
+ for (int i = 0; i < n ; ++i) {\
+ write##ucase(out[i]);\
+ }\
+ }\
+}
+
+IMPLEMENT_WRITER(Bool8, bool)
+IMPLEMENT_WRITER(UInt8, uint8)
+IMPLEMENT_WRITER(Int8, int8)
+
+#undef IMPLEMENT_WRITER
+
+
+#define IMPLEMENT_WRITER(ucase, lcase)\
+void BinaryOutput::write##ucase(const lcase* out, int n) {\
+ if (m_swapBytes) {\
+ for (int i = 0; i < n; ++i) {\
+ write##ucase(out[i]);\
+ }\
+ } else {\
+ writeBytes((const void*)out, sizeof(lcase) * n);\
+ }\
+}
+
+
+IMPLEMENT_WRITER(UInt16, uint16)
+IMPLEMENT_WRITER(Int16, int16)
+IMPLEMENT_WRITER(UInt32, uint32)
+IMPLEMENT_WRITER(Int32, int32)
+IMPLEMENT_WRITER(UInt64, uint64)
+IMPLEMENT_WRITER(Int64, int64)
+IMPLEMENT_WRITER(Float32, float32)
+IMPLEMENT_WRITER(Float64, float64)
+
+#undef IMPLEMENT_WRITER
+
+
+void BinaryOutput::reallocBuffer(size_t bytes, size_t oldBufferLen) {
+ //debugPrintf("reallocBuffer(%d, %d)\n", bytes, oldBufferLen);
+
+ size_t newBufferLen = (int)(m_bufferLen * 1.5) + 100;
+ uint8* newBuffer = NULL;
+
+ if ((m_filename == "<memory>") || (newBufferLen < MAX_BINARYOUTPUT_BUFFER_SIZE)) {
+ // We're either writing to memory (in which case we *have* to try and allocate)
+ // or we've been asked to allocate a reasonable size buffer.
+
+ //debugPrintf(" realloc(%d)\n", newBufferLen);
+ newBuffer = (uint8*)System::realloc(m_buffer, newBufferLen);
+ if (newBuffer != NULL) {
+ m_maxBufferLen = newBufferLen;
+ }
+ }
+
+ if ((newBuffer == NULL) && (bytes > 0)) {
+ // Realloc failed; we're probably out of memory. Back out
+ // the entire call and try to dump some data to disk.
+ m_bufferLen = oldBufferLen;
+ reserveBytesWhenOutOfMemory(bytes);
+ } else {
+ m_buffer = newBuffer;
+ debugAssert(isValidHeapPointer(m_buffer));
+ }
+}
+
+
+void BinaryOutput::reserveBytesWhenOutOfMemory(size_t bytes) {
+ if (m_filename == "<memory>") {
+ throw "Out of memory while writing to memory in BinaryOutput (no RAM left).";
+ } else if ((int)bytes > (int)m_maxBufferLen) {
+ throw "Out of memory while writing to disk in BinaryOutput (could not create a large enough buffer).";
+ } else {
+
+ // Dump the contents to disk. In order to enable seeking backwards,
+ // we keep the last 10 MB in memory.
+ int writeBytes = m_bufferLen - 10 * 1024 * 1024;
+
+ if (writeBytes < m_bufferLen / 3) {
+ // We're going to write less than 1/3 of the file;
+ // give up and just write the whole thing.
+ writeBytes = m_bufferLen;
+ }
+ debugAssert(writeBytes > 0);
+
+ //debugPrintf("Writing %d bytes to disk\n", writeBytes);
+
+ const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
+ FILE* file = fopen(m_filename.c_str(), mode);
+ debugAssert(file);
+
+ size_t count = fwrite(m_buffer, 1, writeBytes, file);
+ debugAssert((int)count == writeBytes); (void)count;
+
+ fclose(file);
+ file = NULL;
+
+ // Record that we saved this data.
+ m_alreadyWritten += writeBytes;
+ m_bufferLen -= writeBytes;
+ m_pos -= writeBytes;
+
+ debugAssert(m_bufferLen < m_maxBufferLen);
+ debugAssert(m_bufferLen >= 0);
+ debugAssert(m_pos >= 0);
+ debugAssert(m_pos <= m_bufferLen);
+
+ // Shift the unwritten data back appropriately in the buffer.
+ debugAssert(isValidHeapPointer(m_buffer));
+ System::memcpy(m_buffer, m_buffer + writeBytes, m_bufferLen);
+ debugAssert(isValidHeapPointer(m_buffer));
+
+ // *now* we allocate bytes (there should presumably be enough
+ // space in the buffer; if not, we'll come back through this
+ // code and dump the last 10MB to disk as well. Note that the
+ // bytes > maxBufferLen case above would already have triggered
+ // if this call couldn't succeed.
+ reserveBytes(bytes);
+ }
+}
+
+
+BinaryOutput::BinaryOutput() {
+ m_alreadyWritten = 0;
+ m_swapBytes = false;
+ m_pos = 0;
+ m_filename = "<memory>";
+ m_buffer = NULL;
+ m_bufferLen = 0;
+ m_maxBufferLen = 0;
+ m_beginEndBits = 0;
+ m_bitString = 0;
+ m_bitPos = 0;
+ m_ok = true;
+ m_committed = false;
+}
+
+
+BinaryOutput::BinaryOutput(
+ const std::string& filename,
+ G3DEndian fileEndian) {
+
+ m_pos = 0;
+ m_alreadyWritten = 0;
+ setEndian(fileEndian);
+ m_filename = filename;
+ m_buffer = NULL;
+ m_bufferLen = 0;
+ m_maxBufferLen = 0;
+ m_beginEndBits = 0;
+ m_bitString = 0;
+ m_bitPos = 0;
+ m_committed = false;
+
+ m_ok = true;
+ /** Verify ability to write to disk */
+ commit(false);
+ m_committed = false;
+}
+
+
+void BinaryOutput::reset() {
+ debugAssert(m_beginEndBits == 0);
+ alwaysAssertM(m_filename == "<memory>",
+ "Can only reset a BinaryOutput that writes to memory.");
+
+ // Do not reallocate, just clear the size of the buffer.
+ m_pos = 0;
+ m_alreadyWritten = 0;
+ m_bufferLen = 0;
+ m_beginEndBits = 0;
+ m_bitString = 0;
+ m_bitPos = 0;
+ m_committed = false;
+}
+
+
+BinaryOutput::~BinaryOutput() {
+ debugAssert((m_buffer == NULL) || isValidHeapPointer(m_buffer));
+ System::free(m_buffer);
+ m_buffer = NULL;
+ m_bufferLen = 0;
+ m_maxBufferLen = 0;
+}
+
+
+void BinaryOutput::setEndian(G3DEndian fileEndian) {
+ m_fileEndian = fileEndian;
+ m_swapBytes = (fileEndian != System::machineEndian());
+}
+
+
+bool BinaryOutput::ok() const {
+ return m_ok;
+}
+
+
+void BinaryOutput::compress() {
+ if (m_alreadyWritten > 0) {
+ throw "Cannot compress huge files (part of this file has already been written to disk).";
+ }
+
+ // Old buffer size
+ int L = m_bufferLen;
+ uint8* convert = (uint8*)&L;
+
+ // Zlib requires the output buffer to be this big
+ unsigned long newSize = iCeil(m_bufferLen * 1.01) + 12;
+ uint8* temp = (uint8*)System::malloc(newSize);
+ int result = compress2(temp, &newSize, m_buffer, m_bufferLen, 9);
+
+ debugAssert(result == Z_OK); (void)result;
+
+ // Write the header
+ if (m_swapBytes) {
+ m_buffer[0] = convert[3];
+ m_buffer[1] = convert[2];
+ m_buffer[2] = convert[1];
+ m_buffer[3] = convert[0];
+ } else {
+ m_buffer[0] = convert[0];
+ m_buffer[1] = convert[1];
+ m_buffer[2] = convert[2];
+ m_buffer[3] = convert[3];
+ }
+
+ // Write the data
+ if ((int64)newSize + 4 > (int64)m_maxBufferLen) {
+ m_maxBufferLen = newSize + 4;
+ m_buffer = (uint8*)System::realloc(m_buffer, m_maxBufferLen);
+ }
+ m_bufferLen = newSize + 4;
+ System::memcpy(m_buffer + 4, temp, newSize);
+ m_pos = m_bufferLen;
+
+ System::free(temp);
+}
+
+
+void BinaryOutput::commit(bool flush) {
+ debugAssertM(! m_committed, "Cannot commit twice");
+ m_committed = true;
+ debugAssertM(m_beginEndBits == 0, "Missing endBits before commit");
+
+ // Make sure the directory exists.
+ std::string root, base, ext, path;
+ Array<std::string> pathArray;
+ parseFilename(m_filename, root, pathArray, base, ext);
+
+ path = root + stringJoin(pathArray, '/');
+ if (! fileExists(path, false)) {
+ createDirectory(path);
+ }
+
+ const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
+
+ FILE* file = fopen(m_filename.c_str(), mode);
+
+ m_ok = (file != NULL) && m_ok;
+
+ if (m_ok) {
+ debugAssertM(file, std::string("Could not open '") + m_filename + "'");
+
+ if (m_buffer != NULL) {
+ m_alreadyWritten += m_bufferLen;
+
+ int success = fwrite(m_buffer, m_bufferLen, 1, file);
+ (void)success;
+ debugAssertM(success == 1, std::string("Could not write to '") + m_filename + "'");
+ }
+ if (flush) {
+ fflush(file);
+ }
+ fclose(file);
+ file = NULL;
+ }
+}
+
+
+void BinaryOutput::commit(
+ uint8* out) {
+ debugAssertM(! m_committed, "Cannot commit twice");
+ m_committed = true;
+
+ System::memcpy(out, m_buffer, m_bufferLen);
+}
+
+
+void BinaryOutput::writeUInt16(uint16 u) {
+ reserveBytes(2);
+
+ uint8* convert = (uint8*)&u;
+
+ if (m_swapBytes) {
+ m_buffer[m_pos] = convert[1];
+ m_buffer[m_pos + 1] = convert[0];
+ } else {
+ *(uint16*)(m_buffer + m_pos) = u;
+ }
+
+ m_pos += 2;
+}
+
+
+void BinaryOutput::writeUInt32(uint32 u) {
+ reserveBytes(4);
+
+ uint8* convert = (uint8*)&u;
+
+ debugAssert(m_beginEndBits == 0);
+
+ if (m_swapBytes) {
+ m_buffer[m_pos] = convert[3];
+ m_buffer[m_pos + 1] = convert[2];
+ m_buffer[m_pos + 2] = convert[1];
+ m_buffer[m_pos + 3] = convert[0];
+ } else {
+ *(uint32*)(m_buffer + m_pos) = u;
+ }
+
+ m_pos += 4;
+}
+
+
+void BinaryOutput::writeUInt64(uint64 u) {
+ reserveBytes(8);
+
+ uint8* convert = (uint8*)&u;
+
+ if (m_swapBytes) {
+ m_buffer[m_pos] = convert[7];
+ m_buffer[m_pos + 1] = convert[6];
+ m_buffer[m_pos + 2] = convert[5];
+ m_buffer[m_pos + 3] = convert[4];
+ m_buffer[m_pos + 4] = convert[3];
+ m_buffer[m_pos + 5] = convert[2];
+ m_buffer[m_pos + 6] = convert[1];
+ m_buffer[m_pos + 7] = convert[0];
+ } else {
+ *(uint64*)(m_buffer + m_pos) = u;
+ }
+
+ m_pos += 8;
+}
+
+
+void BinaryOutput::writeString(const char* s) {
+ // +1 is because strlen doesn't count the null
+ int len = strlen(s) + 1;
+
+ debugAssert(m_beginEndBits == 0);
+ reserveBytes(len);
+ System::memcpy(m_buffer + m_pos, s, len);
+ m_pos += len;
+}
+
+
+void BinaryOutput::writeStringEven(const char* s) {
+ // +1 is because strlen doesn't count the null
+ int len = strlen(s) + 1;
+
+ reserveBytes(len);
+ System::memcpy(m_buffer + m_pos, s, len);
+ m_pos += len;
+
+ // Pad with another NULL
+ if ((len % 2) == 1) {
+ writeUInt8(0);
+ }
+}
+
+
+void BinaryOutput::writeString32(const char* s) {
+ writeUInt32(strlen(s) + 1);
+ writeString(s);
+}
+
+
+void BinaryOutput::writeVector4(const Vector4& v) {
+ writeFloat32(v.x);
+ writeFloat32(v.y);
+ writeFloat32(v.z);
+ writeFloat32(v.w);
+}
+
+
+void BinaryOutput::writeVector3(const Vector3& v) {
+ writeFloat32(v.x);
+ writeFloat32(v.y);
+ writeFloat32(v.z);
+}
+
+
+void BinaryOutput::writeVector2(const Vector2& v) {
+ writeFloat32(v.x);
+ writeFloat32(v.y);
+}
+
+
+void BinaryOutput::writeColor4(const Color4& v) {
+ writeFloat32(v.r);
+ writeFloat32(v.g);
+ writeFloat32(v.b);
+ writeFloat32(v.a);
+}
+
+
+void BinaryOutput::writeColor3(const Color3& v) {
+ writeFloat32(v.r);
+ writeFloat32(v.g);
+ writeFloat32(v.b);
+}
+
+
+void BinaryOutput::beginBits() {
+ debugAssertM(m_beginEndBits == 0, "Already in beginBits...endBits");
+ m_bitString = 0x00;
+ m_bitPos = 0;
+ m_beginEndBits = 1;
+}
+
+
+void BinaryOutput::writeBits(uint32 value, int numBits) {
+
+ while (numBits > 0) {
+ // Extract the current bit of value and
+ // insert it into the current byte
+ m_bitString |= (value & 1) << m_bitPos;
+ ++m_bitPos;
+ value = value >> 1;
+ --numBits;
+
+ if (m_bitPos > 7) {
+ // We've reached the end of this byte
+ writeUInt8(m_bitString);
+ m_bitString = 0x00;
+ m_bitPos = 0;
+ }
+ }
+}
+
+
+void BinaryOutput::endBits() {
+ debugAssertM(m_beginEndBits == 1, "Not in beginBits...endBits");
+ if (m_bitPos > 0) {
+ writeUInt8(m_bitString);
+ }
+ m_bitString = 0;
+ m_bitPos = 0;
+ m_beginEndBits = 0;
+}
+
+}
diff --git a/dep/src/g3dlite/Box.cpp b/dep/src/g3dlite/Box.cpp
index 725a7e95c3a..f7c112ae3a5 100644
--- a/dep/src/g3dlite/Box.cpp
+++ b/dep/src/g3dlite/Box.cpp
@@ -2,7 +2,7 @@
@file Box.cpp
Box class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
@edited 2006-02-05
@@ -27,10 +27,56 @@ namespace G3D {
Box::Box() {
}
+
Box::Box(const AABox& b) {
init(b.low(), b.high());
}
+Box::Box(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Box::serialize(class BinaryOutput& b) const {
+ int i;
+ for (i = 0; i < 8; ++i) {
+ _corner[i].serialize(b);
+ }
+
+ // Other state can be reconstructed
+}
+
+
+void Box::deserialize(class BinaryInput& b) {
+ int i;
+
+ _center = Vector3::zero();
+ for (i = 0; i < 8; ++i) {
+ _corner[i].deserialize(b);
+ _center += _corner[i];
+ }
+
+ _center = _center / 8;
+
+ // Reconstruct other state from the corners
+ _axis[0] = _corner[5] - _corner[4];
+ _axis[1] = _corner[7] - _corner[4];
+ _axis[2] = _corner[0] - _corner[4];
+
+ for (i = 0; i < 3; ++i) {
+ _extent[i] = _axis[i].magnitude();
+ _axis[i] /= _extent[i];
+ }
+
+ _volume = _extent.x * _extent.y * _extent.z;
+
+ _area = 2 *
+ (_extent.x * _extent.y +
+ _extent.y * _extent.z +
+ _extent.z * _extent.x);
+}
+
+
Box::Box(
const Vector3& min,
const Vector3& max) {
@@ -43,6 +89,11 @@ void Box::init(
const Vector3& min,
const Vector3& max) {
+ debugAssert(
+ (min.x <= max.x) &&
+ (min.y <= max.y) &&
+ (min.z <= max.z));
+
setMany(0, 1, 2, 3, z, max);
setMany(4, 5, 6, 7, z, min);
@@ -58,23 +109,40 @@ void Box::init(
_axis[1] = Vector3::unitY();
_axis[2] = Vector3::unitZ();
- _volume = _extent.x * _extent.y * _extent.z;
- _area = 2 *
+ if (_extent.isFinite()) {
+ _volume = _extent.x * _extent.y * _extent.z;
+ } else {
+ _volume = G3D::finf();
+ }
+
+ debugAssert(! isNaN(_extent.x));
+
+ _area = 2 *
(_extent.x * _extent.y +
_extent.y * _extent.z +
_extent.z * _extent.x);
- _center = (max + min) / 2;
+ _center = (max + min) * 0.5f;
+
+ // If the extent is infinite along an axis, make the center zero to avoid NaNs
+ for (int i = 0; i < 3; ++i) {
+ if (! G3D::isFinite(_extent[i])) {
+ _center[i] = 0.0f;
+ }
+ }
}
+
float Box::volume() const {
return _volume;
}
-float Box::surfaceArea() const {
+
+float Box::area() const {
return _area;
}
+
void Box::getLocalFrame(CoordinateFrame& frame) const {
frame.rotation = Matrix3(
@@ -85,12 +153,14 @@ void Box::getLocalFrame(CoordinateFrame& frame) const {
frame.translation = _center;
}
+
CoordinateFrame Box::localFrame() const {
CoordinateFrame out;
getLocalFrame(out);
return out;
}
+
void Box::getFaceCorners(int f, Vector3& v0, Vector3& v1, Vector3& v2, Vector3& v3) const {
switch (f) {
case 0:
@@ -122,45 +192,29 @@ void Box::getFaceCorners(int f, Vector3& v0, Vector3& v1, Vector3& v2, Vector3&
}
}
-bool Box::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask,
- uint32& outMask) const {
-
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask);
-}
-
-bool Box::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask) const {
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask);
-}
-int32 Box::dummy = 0;
+int Box::dummy = 0;
bool Box::culledBy(
- const class Plane* plane,
- int numPlanes,
+ const Array<Plane>& plane,
int& cullingPlane,
const uint32 _inMask,
uint32& childMask) const {
uint32 inMask = _inMask;
- assert(numPlanes < 31);
+ assert(plane.size() < 31);
childMask = 0;
// See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
+ // vertices are in the negative half space.
+ for (int p = 0; p < plane.size(); ++p) {
- Vector3 corner;
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
+ Vector3 corner;
int numContained = 0;
int v = 0;
@@ -168,83 +222,84 @@ bool Box::culledBy(
// We can early-out only if we have found one point on each
// side of the plane (i.e. if we are straddling). That
// occurs when (numContained < v) && (numContained > 0)
- for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
- if (plane[p].halfSpaceContains(getCorner(v))) {
+ for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
+ if (plane[p].halfSpaceContains(_corner[v])) {
++numContained;
}
- }
+ }
- if (numContained == 0) {
- // Plane p culled the box
- cullingPlane = p;
+ if (numContained == 0) {
+ // Plane p culled the box
+ cullingPlane = p;
// The caller should not recurse into the children,
// since the parent is culled. If they do recurse,
// make them only test against this one plane, which
// will immediately cull the volume.
childMask = 1 << p;
- return true;
+ return true;
} else if (numContained < v) {
// The bounding volume straddled the plane; we have
// to keep testing against this plane
childMask |= (1 << p);
}
- }
+ }
// Move on to the next bit.
- inMask = inMask >> 1;
+ inMask = inMask >> 1;
}
// None of the planes could cull this box
- cullingPlane = -1;
+ cullingPlane = -1;
return false;
}
+
bool Box::culledBy(
- const class Plane* plane,
- int numPlanes,
- int& cullingPlane,
- const uint32 _inMask) const {
+ const Array<Plane>& plane,
+ int& cullingPlane,
+ const uint32 _inMask) const {
- uint32 inMask = _inMask;
- assert(numPlanes < 31);
+ uint32 inMask = _inMask;
+ assert(plane.size() < 31);
// See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
+ // vertices are in the negative half space.
+ for (int p = 0; p < plane.size(); ++p) {
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
-
- bool culled = true;
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
+ bool culled = true;
int v;
- // Assume this plane culls all points. See if there is a point
- // not culled by the plane... early out when at least one point
+ // Assume this plane culls all points. See if there is a point
+ // not culled by the plane... early out when at least one point
// is in the positive half space.
- for (v = 0; (v < 8) && culled; ++v) {
- culled = ! plane[p].halfSpaceContains(getCorner(v));
- }
+ for (v = 0; (v < 8) && culled; ++v) {
+ culled = ! plane[p].halfSpaceContains(corner(v));
+ }
- if (culled) {
- // Plane p culled the box
- cullingPlane = p;
+ if (culled) {
+ // Plane p culled the box
+ cullingPlane = p;
- return true;
+ return true;
}
- }
+ }
// Move on to the next bit.
- inMask = inMask >> 1;
+ inMask = inMask >> 1;
}
// None of the planes could cull this box
- cullingPlane = -1;
+ cullingPlane = -1;
return false;
}
+
bool Box::contains(
const Vector3& point) const {
@@ -264,7 +319,7 @@ bool Box::contains(
Vector3 osPoint = M.inverse() * (point - _corner[0]);
return
- (osPoint.x >= 0) &&
+ (osPoint.x >= 0) &&
(osPoint.y >= 0) &&
(osPoint.z >= 0) &&
(osPoint.x <= 1) &&
@@ -274,47 +329,51 @@ bool Box::contains(
#undef setMany
-#if 0
+
void Box::getRandomSurfacePoint(Vector3& P, Vector3& N) const {
float aXY = _extent.x * _extent.y;
float aYZ = _extent.y * _extent.z;
float aZX = _extent.z * _extent.x;
- float r = (float)random(0, aXY + aYZ + aZX);
+ float r = (float)uniformRandom(0, aXY + aYZ + aZX);
// Choose evenly between positive and negative face planes
- float d = (random(0, 1) < 0.5f) ? -1.0f : 1.0f;
+ float d = (uniformRandom(0, 1) < 0.5f) ? -1.0f : 1.0f;
// The probability of choosing a given face is proportional to
// its area.
if (r < aXY) {
- P = _axis[0] * (float)random(-0.5, 0.5) * _extent.x +
- _axis[1] * (float)random(-0.5, 0.5) * _extent.y +
+ P = _axis[0] * (float)uniformRandom(-0.5, 0.5) * _extent.x +
+ _axis[1] * (float)uniformRandom(-0.5, 0.5) * _extent.y +
_center + _axis[2] * d * _extent.z * 0.5f;
N = _axis[2] * d;
} else if (r < aYZ) {
- P = _axis[1] * (float)random(-0.5, 0.5) * _extent.y +
- _axis[2] * (float)random(-0.5, 0.5) * _extent.z +
+ P = _axis[1] * (float)uniformRandom(-0.5, 0.5) * _extent.y +
+ _axis[2] * (float)uniformRandom(-0.5, 0.5) * _extent.z +
_center + _axis[0] * d * _extent.x * 0.5f;
N = _axis[0] * d;
} else {
- P = _axis[2] * (float)random(-0.5, 0.5) * _extent.z +
- _axis[0] *(float) random(-0.5, 0.5) * _extent.x +
+ P = _axis[2] * (float)uniformRandom(-0.5, 0.5) * _extent.z +
+ _axis[0] *(float) uniformRandom(-0.5, 0.5) * _extent.x +
_center + _axis[1] * d * _extent.y * 0.5f;
N = _axis[1] * d;
}
}
+
Vector3 Box::randomInteriorPoint() const {
Vector3 sum = _center;
for (int a = 0; a < 3; ++a) {
- sum += _axis[a] * (float)random(-0.5, 0.5) * _extent[a];
+ sum += _axis[a] * (float)uniformRandom(-0.5, 0.5) * _extent[a];
}
return sum;
}
-#endif
+
+Box Box::inf() {
+ return Box(-Vector3::inf(), Vector3::inf());
+}
void Box::getBounds(class AABox& aabb) const {
@@ -330,5 +389,5 @@ void Box::getBounds(class AABox& aabb) const {
aabb = AABox(lo, hi);
}
-} // namespace
+} // namespace
diff --git a/dep/src/g3dlite/Box2D.cpp b/dep/src/g3dlite/Box2D.cpp
new file mode 100644
index 00000000000..ea5a47af1a9
--- /dev/null
+++ b/dep/src/g3dlite/Box2D.cpp
@@ -0,0 +1,113 @@
+/**
+ @file Box.cpp
+ Box class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-06-02
+ @edited 2008-12-27
+*/
+
+#include "G3D/Box2D.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Rect2D.h"
+
+namespace G3D {
+
+bool Box2D::overlaps1Way(const Box2D& other) const {
+ for (int a = 0; a < 2; ++a) {
+
+ float t = other.m_corner[0].dot(m_axisin[a]);
+
+ // Find the extent of box 2 on m_axisin a
+ float tMin = t;
+ float tMax = t;
+
+ for (int c = 1; c < 4; ++c) {
+ t = other.m_corner[c].dot(m_axisin[a]);
+
+ if (t < tMin) {
+ tMin = t;
+ } else if (t > tMax) {
+ tMax = t;
+ }
+ }
+
+ // We have to subtract off the origin
+
+ // See if [tMin, tMax] intersects [0, 1]
+ if ((tMin > 1 + origin[a]) || (tMax < origin[a])) {
+ // There was no intersection along this dimension;
+ // the boxes cannot possibly overlap.
+ return false;
+ }
+ }
+
+ // There was no dimension along which there is no intersection.
+ // Therefore the boxes overlap.
+ return true;
+}
+
+
+void Box2D::computeAxes() {
+ m_axis[0] = m_corner[1] - m_corner[0];
+ m_axis[1] = m_corner[3] - m_corner[0];
+
+ // Make the length of each m_axisin = 1/edge length so we know any
+ // dot product must be less than 1 to fall within the edge.
+ float len[2];
+ for (int a = 0; a < 2; ++a) {
+ float lenSq = m_axis[a].squaredLength();
+ m_axisin[a] = m_axis[a] / lenSq;
+ origin[a] = m_corner[0].dot(m_axisin[a]);
+ len[a] = sqrt(lenSq);
+ m_axis[a] /= len[a];
+ }
+
+ // w * h
+ m_area = len[0] * len[1];
+
+
+ m_center = (m_corner[0] + m_corner[2]) * 0.5f;
+}
+
+
+Box2D::Box2D(const Vector2& center, float w, float h, float angle) {
+ Vector2 X( cos(angle), sin(angle));
+ Vector2 Y(-sin(angle), cos(angle));
+
+ X *= w / 2;
+ Y *= h / 2;
+
+ m_corner[0] = center - X - Y;
+ m_corner[1] = center + X - Y;
+ m_corner[2] = center + X + Y;
+ m_corner[3] = center - X + Y;
+
+ computeAxes();
+}
+
+
+Box2D::Box2D(const AABox2D& b) {
+ for (int i = 0; i < 4; ++i) {
+ m_corner[i] = b.corner(i);
+ }
+
+ computeAxes();
+}
+
+
+Box2D::Box2D(const Vector2& min, const Vector2& max) {
+ *this = Box2D(Rect2D::xyxy(min, max));
+}
+
+
+Box2D::Box2D(const CFrame& frame, Box2D& b) {
+ for (int i = 0; i < 4; ++i) {
+ m_corner[i] = frame.pointToWorldSpace(Vector3(b.corner(i), 0)).xy();
+ }
+ computeAxes();
+}
+
+
+} // G3D
diff --git a/dep/src/g3dlite/BumpMapPreprocess.cpp b/dep/src/g3dlite/BumpMapPreprocess.cpp
new file mode 100644
index 00000000000..20281caf8cb
--- /dev/null
+++ b/dep/src/g3dlite/BumpMapPreprocess.cpp
@@ -0,0 +1,43 @@
+/**
+ \file BumpMapPreprocess.cpp
+
+ \maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ \created 2010-01-28
+ \edited 2010-01-28
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+#include "G3D/BumpMapPreprocess.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+BumpMapPreprocess::BumpMapPreprocess(const Any& any) {
+ *this = BumpMapPreprocess();
+ for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
+ const std::string& key = toLower(it->key);
+ if (key == "lowpassfilter") {
+ lowPassFilter = it->value;
+ } else if (key == "zextentpixels") {
+ zExtentPixels = it->value;
+ } else if (key == "scalezbynz") {
+ scaleZByNz = it->value;
+ } else {
+ any.verify(false, "Illegal key: " + it->key);
+ }
+ }
+}
+
+
+BumpMapPreprocess::operator Any() const {
+ Any any(Any::TABLE, "BumpMapPreprocess");
+ any["lowPassFilter"] = lowPassFilter;
+ any["zExtentPixels"] = zExtentPixels;
+ any["scaleZByNz"] = scaleZByNz;
+ return any;
+}
+
+}
diff --git a/dep/src/g3dlite/CMakeLists.txt b/dep/src/g3dlite/CMakeLists.txt
index 8f0a6191623..0a548e44f8b 100644
--- a/dep/src/g3dlite/CMakeLists.txt
+++ b/dep/src/g3dlite/CMakeLists.txt
@@ -2,19 +2,48 @@
########### next target ###############
SET(g3dlite_STAT_SRCS
- AABox.cpp
- Box.cpp
- Crypto.cpp
- format.cpp
- Matrix3.cpp
- Plane.cpp
- System.cpp
- Triangle.cpp
- Vector3.cpp
- Vector4.cpp
+ AABox.cpp
+ Box.cpp
+ Crypto.cpp
+ format.cpp
+ Matrix3.cpp
+ Plane.cpp
+ System.cpp
+ Triangle.cpp
+ Vector3.cpp
+ Vector4.cpp
+ debugAssert.cpp
+ fileutils.cpp
+ g3dmath.cpp
+ g3dfnmatch.cpp
+ prompt.cpp
+ stringutils.cpp
+ Any.cpp
+ BinaryFormat.cpp
+ BinaryInput.cpp
+ BinaryOutput.cpp
+ Capsule.cpp
+ CollisionDetection.cpp
+ CoordinateFrame.cpp
+ Cylinder.cpp
+ Line.cpp
+ LineSegment.cpp
+ Log.cpp
+ Matrix4.cpp
+ MemoryManager.cpp
+ Quat.cpp
+ Random.cpp
+ Ray.cpp
+ ReferenceCount.cpp
+ Sphere.cpp
+ TextInput.cpp
+ TextOutput.cpp
+ UprightFrame.cpp
+ Vector2.cpp
)
include_directories(
+ ${CMAKE_SOURCE_DIR}/dep/include
${CMAKE_SOURCE_DIR}/dep/include/g3dlite
)
diff --git a/dep/src/g3dlite/Capsule.cpp b/dep/src/g3dlite/Capsule.cpp
new file mode 100644
index 00000000000..2ad3891c960
--- /dev/null
+++ b/dep/src/g3dlite/Capsule.cpp
@@ -0,0 +1,179 @@
+/**
+ @file Capsule.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-02-07
+ @edited 2005-08-18
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/Capsule.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/LineSegment.h"
+#include "G3D/Sphere.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Line.h"
+#include "G3D/AABox.h"
+
+namespace G3D {
+
+Capsule::Capsule(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+Capsule::Capsule() {
+}
+
+
+Capsule::Capsule(const Vector3& _p1, const Vector3& _p2, float _r)
+ : p1(_p1), p2(_p2), _radius(_r) {
+}
+
+
+void Capsule::serialize(class BinaryOutput& b) const {
+ p1.serialize(b);
+ p2.serialize(b);
+ b.writeFloat64(_radius);
+}
+
+
+void Capsule::deserialize(class BinaryInput& b) {
+ p1.deserialize(b);
+ p2.deserialize(b);
+ _radius = b.readFloat64();
+}
+
+
+Line Capsule::axis() const {
+ return Line::fromTwoPoints(p1, p2);
+}
+
+
+float Capsule::volume() const {
+ return
+ // Sphere volume
+ pow(_radius, 3) * pi() * 4 / 3 +
+
+ // Cylinder volume
+ pow(_radius, 2) * (p1 - p2).magnitude();
+}
+
+
+float Capsule::area() const {
+
+ return
+ // Sphere area
+ pow(_radius, 2) * 4 * pi() +
+
+ // Cylinder area
+ twoPi() * _radius * (p1 - p2).magnitude();
+}
+
+
+void Capsule::getBounds(AABox& out) const {
+ Vector3 min = p1.min(p2) - (Vector3(1, 1, 1) * _radius);
+ Vector3 max = p1.max(p2) + (Vector3(1, 1, 1) * _radius);
+
+ out = AABox(min, max);
+}
+
+
+bool Capsule::contains(const Vector3& p) const {
+ return LineSegment::fromTwoPoints(p1, p2).distanceSquared(p) <= square(radius());
+}
+
+
+void Capsule::getRandomSurfacePoint(Vector3& p, Vector3& N) const {
+ float h = height();
+ float r = radius();
+
+ // Create a random point on a standard capsule and then rotate to the global frame.
+
+ // Relative areas
+ float capRelArea = sqrt(r) / 2.0f;
+ float sideRelArea = r * h;
+
+ float r1 = uniformRandom(0, capRelArea * 2 + sideRelArea);
+
+ if (r1 < capRelArea * 2) {
+
+ // Select a point uniformly at random on a sphere
+ N = Sphere(Vector3::zero(), 1).randomSurfacePoint();
+ p = N * r;
+ p.y += sign(p.y) * h / 2.0f;
+ } else {
+ // Side
+ float a = uniformRandom(0, (float)twoPi());
+ N.x = cos(a);
+ N.y = 0;
+ N.z = sin(a);
+ p.x = N.x * r;
+ p.z = N.y * r;
+ p.y = uniformRandom(-h / 2.0f, h / 2.0f);
+ }
+
+ // Transform to world space
+ CoordinateFrame cframe;
+ getReferenceFrame(cframe);
+
+ p = cframe.pointToWorldSpace(p);
+ N = cframe.normalToWorldSpace(N);
+}
+
+
+void Capsule::getReferenceFrame(CoordinateFrame& cframe) const {
+ cframe.translation = center();
+
+ Vector3 Y = (p1 - p2).direction();
+ Vector3 X = (abs(Y.dot(Vector3::unitX())) > 0.9) ? Vector3::unitY() : Vector3::unitX();
+ Vector3 Z = X.cross(Y).direction();
+ X = Y.cross(Z);
+ cframe.rotation.setColumn(0, X);
+ cframe.rotation.setColumn(1, Y);
+ cframe.rotation.setColumn(2, Z);
+}
+
+
+Vector3 Capsule::randomInteriorPoint() const {
+ float h = height();
+ float r = radius();
+
+ // Create a random point in a standard capsule and then rotate to the global frame.
+
+ Vector3 p;
+
+ float hemiVolume = pi() * (r*r*r) * 4 / 6.0;
+ float cylVolume = pi() * square(r) * h;
+
+ float r1 = uniformRandom(0, 2.0 * hemiVolume + cylVolume);
+
+ if (r1 < 2.0 * hemiVolume) {
+
+ p = Sphere(Vector3::zero(), r).randomInteriorPoint();
+
+ p.y += sign(p.y) * h / 2.0f;
+
+ } else {
+
+ // Select a point uniformly at random on a disk
+ float a = uniformRandom(0, (float)twoPi());
+ float r2 = sqrt(uniformRandom(0, 1)) * r;
+
+ p = Vector3(cos(a) * r2,
+ uniformRandom(-h / 2.0f, h / 2.0f),
+ sin(a) * r2);
+ }
+
+ // Transform to world space
+ CoordinateFrame cframe;
+ getReferenceFrame(cframe);
+
+ return cframe.pointToWorldSpace(p);
+}
+
+} // namespace
diff --git a/dep/src/g3dlite/CollisionDetection.cpp b/dep/src/g3dlite/CollisionDetection.cpp
new file mode 100644
index 00000000000..77eef0a5500
--- /dev/null
+++ b/dep/src/g3dlite/CollisionDetection.cpp
@@ -0,0 +1,2455 @@
+/**
+ @file CollisionDetection.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @cite Bounce direction based on Paul Nettle's ftp://ftp.3dmaileffects.com/pub/FluidStudios/CollisionDetection/Fluid_Studios_Generic_Collision_Detection_for_Games_Using_Ellipsoids.pdf and comments by Max McGuire. Ray-sphere code by Eric Haines.
+
+ @created 2001-11-24
+ @edited 2008-12-29
+ */
+
+#include "G3D/CoordinateFrame.h"
+#include "G3D/platform.h"
+#include "G3D/CollisionDetection.h"
+#include "G3D/debugAssert.h"
+#include "G3D/vectorMath.h"
+#include "G3D/Capsule.h"
+#include "G3D/Plane.h"
+#include "G3D/Line.h"
+#include "G3D/LineSegment.h"
+#include "G3D/Sphere.h"
+#include "G3D/Box.h"
+#include "G3D/Triangle.h"
+#include "G3D/Vector3.h"
+#include "G3D/AABox.h"
+
+#ifdef _MSC_VER
+// Turn on fast floating-point optimizations
+#pragma float_control( push )
+#pragma fp_contract( on )
+#pragma fenv_access( off )
+#pragma float_control( except, off )
+#pragma float_control( precise, off )
+#endif
+
+
+namespace G3D {
+
+bool CollisionDetection::ignoreBool;
+Vector3 CollisionDetection::ignore;
+Array<Vector3> CollisionDetection::ignoreArray;
+
+
+
+Vector3 CollisionDetection::separatingAxisForSolidBoxSolidBox(
+ const int separatingAxisIndex,
+ const Box & box1,
+ const Box & box2) {
+ debugAssert(separatingAxisIndex >= 0);
+ debugAssert(separatingAxisIndex < 15);
+ Vector3 axis;
+ if (separatingAxisIndex < 3) {
+ axis = box1.axis(separatingAxisIndex);
+ } else if (separatingAxisIndex < 6) {
+ axis = box2.axis(separatingAxisIndex - 3);
+ } else {
+ int box1Index = (separatingAxisIndex - 6) / 3;
+ int box2Index = (separatingAxisIndex - 6) % 3;
+ axis = cross(box1.axis(box1Index), box2.axis(box2Index));
+ }
+ return axis;
+}
+
+#ifdef _MSC_VER
+# pragma warning (push)
+# pragma warning (disable : 4244)
+#endif
+
+float CollisionDetection::projectedDistanceForSolidBoxSolidBox(
+ const int separatingAxisIndex,
+ const Vector3 & a,
+ const Vector3 & b,
+ const Vector3 & D,
+ const double* c,
+ const double* ca,
+ const double* ad,
+ const double* bd)
+{
+ (void)D;
+
+ float R0 = 0.0f;
+ float R1 = 0.0f;
+ float R = 0.0f;
+ switch (separatingAxisIndex) {
+ case 0:
+ // A0
+ R0 = a[0];
+ R1 = b[0] * ca[0] + b[1] * ca[1] + b[2] * ca[2];
+ R = fabs(ad[0]);
+ break;
+ case 1:
+ // A1
+ R0 = a[1];
+ R1 = b[0] * ca[3] + b[1] * ca[4] + b[2] * ca[5];
+ R = fabs(ad[1]);
+ break;
+ case 2:
+ // A2
+ R0 = a[2];
+ R1 = b[0] * ca[6] + b[1] * ca[7] + b[2] * ca[8];
+ R = fabs(ad[2]);
+ break;
+ case 3:
+ // B0
+ R0 = a[0] * ca[0] + a[1] * ca[3] + a[2] * ca[6];
+ R1 = b[0];
+ R = fabs(bd[0]);
+ break;
+ case 4:
+ // B1
+ R0 = a[0] * ca[1] + a[1] * ca[4] + a[2] * ca[7];
+ R1 = b[1];
+ R = fabs(bd[1]);
+ break;
+ case 5:
+ // B2
+ R0 = a[0] * ca[2] + a[1] * ca[5] + a[2] * ca[8];
+ R1 = b[2];
+ R = fabs(bd[2]);
+ break;
+ case 6:
+ // A0 x B0
+ R0 = a[1] * ca[6] + a[2] * ca[3];
+ R1 = b[1] * ca[2] + b[2] * ca[1];
+ R = fabs(c[3] * ad[2] - c[6] * ad[1]);
+ break;
+ case 7:
+ // A0 x B1
+ R0 = a[1] * ca[7] + a[2] * ca[4];
+ R1 = b[0] * ca[2] + b[2] * ca[0];
+ R = fabs(c[4] * ad[2] - c[7] * ad[1]);
+ break;
+ case 8:
+ // A0 x B2
+ R0 = a[1] * ca[8] + a[2] * ca[5];
+ R1 = b[0] * ca[1] + b[1] * ca[0];
+ R = fabs(c[5] * ad[2] - c[8] * ad[1]);
+ break;
+ case 9:
+ // A1 x B0
+ R0 = a[0] * ca[6] + a[2] * ca[0];
+ R1 = b[1] * ca[5] + b[2] * ca[4];
+ R = fabs(c[6] * ad[0] - c[0] * ad[2]);
+ break;
+ case 10:
+ // A1 x B1
+ R0 = a[0] * ca[7] + a[2] * ca[1];
+ R1 = b[0] * ca[5] + b[2] * ca[3];
+ R = fabs(c[7] * ad[0] - c[1] * ad[2]);
+ break;
+ case 11:
+ // A1 x B2
+ R0 = a[0] * ca[8] + a[2] * ca[2];
+ R1 = b[0] * ca[4] + b[1] * ca[3];
+ R = fabs(c[8] * ad[0] - c[2] * ad[2]);
+ break;
+ case 12:
+ // A2 x B0
+ R0 = a[0] * ca[3] + a[1] * ca[0];
+ R1 = b[1] * ca[8] + b[2] * ca[7];
+ R = fabs(c[0] * ad[1] - c[3] * ad[0]);
+ break;
+ case 13:
+ // A2 x B1
+ R0 = a[0] * ca[4] + a[1] * ca[1];
+ R1 = b[0] * ca[8] + b[2] * ca[6];
+ R = fabs(c[1] * ad[1] - c[4] * ad[0]);
+ break;
+ case 14:
+ // A2 x B2
+ R0 = a[0] * ca[5] + a[1] * ca[2];
+ R1 = b[0] * ca[7] + b[1] * ca[6];
+ R = fabs(c[2] * ad[1] - c[5] * ad[0]);
+ break;
+ default:
+ debugAssertM(false, "fell through switch statement");
+ }
+
+ return (R - (R0 + R1));
+}
+
+
+bool CollisionDetection::parallelAxisForSolidBoxSolidBox(
+ const double* ca,
+ const double epsilon,
+ int & axis1,
+ int & axis2) {
+ const double parallelDot = 1.0 - epsilon;
+ for (int i = 0; i < 9; i++) {
+ if (ca[i] >= parallelDot) {
+ axis1 = i / 3;
+ axis2 = i % 3;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+void CollisionDetection::fillSolidBoxSolidBoxInfo(
+ const Box & box1,
+ const Box & box2,
+ Vector3 & a,
+ Vector3 & b,
+ Vector3 & D,
+ double* c,
+ double* ca,
+ double* ad,
+ double* bd) {
+ // length between center and each side of box1 and box2
+ a = box1.extent() * 0.5;
+ b = box2.extent() * 0.5;
+
+ // difference between centers of box1 and box2
+ D = box2.center() - box1.center();
+
+ // store the value of all possible dot products between the
+ // axes of box1 and box2, c_{row, col} in the Eberly paper
+ // corresponds to c[row * 3 + col] for this 9 element array.
+ //
+ // c[] holds signed values, ca[] hold absolute values
+ for (int i = 0; i < 9; i++) {
+ c[i] = dot(box1.axis(i / 3), box2.axis(i % 3));
+ ca[i] = fabs(c[i]);
+ }
+
+ // store all possible dot products between the axes of box1 and D,
+ // as well as the axes of box2 and D
+ for (int i = 0; i < 3; i++) {
+ ad[i] = dot(box1.axis(i), D);
+ bd[i] = dot(box2.axis(i), D);
+ }
+}
+
+
+
+bool CollisionDetection::conservativeBoxBoxTest(
+ const Vector3 & a, const Vector3 & b, const Vector3 & D) {
+ // do a quick bounding sphere test because it is relatively
+ // cheap, (three dot products, two sqrts, and a few others)
+ double boxRadius1 = a.magnitude();
+ double boxRadius2 = b.magnitude();
+ return (D.squaredMagnitude() < square(boxRadius1 + boxRadius2));
+}
+
+
+
+
+bool CollisionDetection::fixedSolidBoxIntersectsFixedSolidBox(
+ const Box& box1,
+ const Box& box2,
+ const int lastSeparatingAxis) {
+ // for explanations of the variable please refer to the
+ // paper and fillSolidBoxSolidBoxInfo()
+ Vector3 a;
+ Vector3 b;
+ Vector3 D;
+ double c[9];
+ double ca[9];
+ double ad[3];
+ double bd[3];
+
+ fillSolidBoxSolidBoxInfo(box1, box2, a, b, D, c, ca, ad, bd);
+
+ int dummy1, dummy2;
+ bool parallelAxes = parallelAxisForSolidBoxSolidBox(ca, 0.00001,
+ dummy1, dummy2);
+
+ // check the separating axis from the last time step
+ if (lastSeparatingAxis != -1 &&
+ (lastSeparatingAxis < 6 || !parallelAxes)) {
+ double projectedDistance = projectedDistanceForSolidBoxSolidBox(
+ lastSeparatingAxis, a, b, D, c, ca, ad, bd);
+
+ // the separating axis from the last time step is still
+ // valid, the boxes do not intersect
+ if (projectedDistance > 0.0) {
+ return false;
+ }
+ }
+
+ // test if the boxes can be separated by a plane normal to
+ // any of the three axes of box1, any of the three axes of box2,
+ // or any of the 9 possible cross products of axes from box1
+ // and box2
+ for (int i = 0; i < 15; i++) {
+ // do not need to check edge-edge cases if any two of
+ // the axes are parallel
+ if (parallelAxes && i == 6) {
+ return true;
+ }
+
+ double projectedDistance =
+ projectedDistanceForSolidBoxSolidBox(i, a, b, D, c, ca, ad, bd);
+
+ // found a separating axis, the boxes do not intersect
+ if (projectedDistance > 0.0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+void CollisionDetection::closestPointsBetweenLineAndLine(
+ const Line & line1,
+ const Line & line2,
+ Vector3 & closest1,
+ Vector3 & closest2) {
+ // TODO make accessors for Line that don't make a copy of data
+ Vector3 P0 = line1.point();
+ Vector3 u = line1.direction();
+ Vector3 Q0 = line2.point();
+ Vector3 v = line2.direction();
+ Vector3 w0 = P0 - Q0;
+
+ // a = 1.0, c = 1.0
+ double b = dot(u, v);
+ double d = dot(u, w0);
+ double e = dot(v, w0);
+ double D = 1.0 - b * b;
+ double sc, tc;
+
+ static const double epsilon = 0.00001;
+
+ if (D < epsilon) {
+ // lines are parallel, choose P0 as one point, find the point
+ // on line2 that is closest to P0
+ sc = 0.0;
+ tc = (b > 1.0) ? (d / b) : (e / 1.0);
+ } else {
+ // lines are not parallel
+ sc = (b * e - 1.0 * d) / D;
+ tc = (1.0 * e - b * d) / D;
+ }
+
+ closest1 = P0 + (sc * u);
+ closest2 = Q0 + (tc * v);
+}
+
+
+
+float CollisionDetection::penetrationDepthForFixedBoxFixedBox(
+ const Box& box1,
+ const Box& box2,
+ Array<Vector3>& contactPoints,
+ Array<Vector3>& contactNormals,
+ const int lastSeparatingAxis) {
+
+ contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+ contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+
+ Vector3 a;
+ Vector3 b;
+ Vector3 D;
+ double c[9];
+ double ca[9];
+ double ad[3];
+ double bd[3];
+
+ debugAssert(lastSeparatingAxis >= -1);
+ debugAssert(lastSeparatingAxis < 15);
+
+ fillSolidBoxSolidBoxInfo(box1, box2, a, b, D, c, ca, ad, bd);
+
+ int axis1, axis2;
+ bool parallelAxes = parallelAxisForSolidBoxSolidBox(ca, 0.00001,
+ axis1, axis2);
+
+
+ // check the separating axis from the last time step
+ if (lastSeparatingAxis != -1 &&
+ (lastSeparatingAxis < 6 || !parallelAxes)) {
+ float projectedDistance = projectedDistanceForSolidBoxSolidBox(
+ lastSeparatingAxis, a, b, D, c, ca, ad, bd);
+
+ // the separating axis from the last time step is still
+ // valid, the boxes do not intersect
+ if (projectedDistance > 0.0) {
+ return -projectedDistance;
+ }
+ }
+
+ // test if the boxes can be separated by a plane normal to
+ // any of the three axes of box1, any of the three axes of box2,
+ // (test 9 possible cross products later)
+ float penetration = -finf();
+ int penetrationAxisIndex = -1;
+
+ for (int i = 0; i < 6; i++) {
+ float projectedDistance =
+ projectedDistanceForSolidBoxSolidBox(i, a, b, D, c, ca, ad, bd);
+
+ // found a separating axis, the boxes do not intersect
+ if (projectedDistance > 0.0) {
+ return -projectedDistance;
+ }
+
+ // keep track of the axis that is least violated
+ if (projectedDistance > penetration) {
+ penetration = projectedDistance;
+ penetrationAxisIndex = i;
+ }
+ }
+
+
+ // for each edge-edge case we have to adjust the magnitude of
+ // penetration since we did not include the dot(L, L) denominator
+ // that can be smaller than 1.0 for the edge-edge cases.
+ if (!parallelAxes) {
+ double edgeDistances[9];
+
+ // run through edge-edge cases to see if we can find a separating axis
+ for (int i = 6; i < 15; i++) {
+ float projectedDistance =
+ projectedDistanceForSolidBoxSolidBox(i, a, b, D, c, ca, ad, bd);
+
+ // found a separating axis, the boxes do not intersect,
+ // correct magnitude and return projected distance
+ if (projectedDistance > 0.0) {
+ Vector3 L = separatingAxisForSolidBoxSolidBox(i, box1, box2);
+ projectedDistance /= dot(L, L);
+ return -projectedDistance;
+ }
+
+ edgeDistances[i - 6] = projectedDistance;
+ }
+
+ // no separating axis found, the boxes do intersect,
+ // correct the magnitudes of the projectedDistance values
+ for (int i = 6; i < 15; i++) {
+ // find the negative penetration value with the smallest magnitude,
+ // the adjustment done for the edge-edge cases only increases
+ // magnitude by dividing by a number smaller than 1 and greater than 0
+ float projectedDistance = (float)edgeDistances[i - 6];
+ if (projectedDistance > penetration) {
+ Vector3 L = separatingAxisForSolidBoxSolidBox(i, box1, box2);
+ projectedDistance /= dot(L, L);
+ if (projectedDistance > penetration) {
+ penetration = projectedDistance;
+ penetrationAxisIndex = i;
+ }
+ }
+ }
+ }
+
+ // get final separating axis vector
+ Vector3 L = separatingAxisForSolidBoxSolidBox(penetrationAxisIndex,
+ box1, box2);
+
+ // set L to be the normal that faces away from box1
+ if (dot(L, D) < 0) {
+ L = -L;
+ }
+
+ Vector3 contactPoint;
+
+ if (penetrationAxisIndex < 6) {
+ // vertex to face collision, find deepest colliding vertex
+ const Box* vertexBox;
+ const Box* faceBox;
+ Vector3 faceNormal = L;
+
+ // L will be the outward facing normal for the faceBox
+ if (penetrationAxisIndex < 3) {
+ faceBox = & box1;
+ vertexBox = & box2;
+ if (dot(L, D) < 0) {
+ faceNormal = -L;
+ }
+ } else {
+ faceBox = & box2;
+ vertexBox = & box1;
+ if (dot(L, D) > 0) {
+ faceNormal = -L;
+ }
+ }
+
+ // find the vertex that is farthest away in the direction
+ // face normal direction
+ int deepestPointIndex = 0;
+ float deepestPointDot = dot(faceNormal, vertexBox->corner(0));
+ for (int i = 1; i < 8; i++) {
+ float dotProduct = dot(faceNormal, vertexBox->corner(i));
+ if (dotProduct < deepestPointDot) {
+ deepestPointDot = dotProduct;
+ deepestPointIndex = i;
+ }
+ }
+
+ // return the point half way between the deepest point and the
+ // contacting face
+ contactPoint = vertexBox->corner(deepestPointIndex) +
+ (-penetration * 0.5 * faceNormal);
+ } else {
+ // edge-edge case, find the two ege lines
+ int edge1 = (penetrationAxisIndex - 6) / 3;
+ int edge2 = (penetrationAxisIndex - 6) % 3;
+ Vector3 linePoint1 = box1.center();
+ Vector3 linePoint2 = box2.center();
+ Vector3 lineDir1;
+ Vector3 lineDir2;
+
+ // find edge line by finding the edge axis, and the
+ // other two axes that are closest to the other box
+ for (int i = 0; i < 3; i++ ) {
+ if (i == edge1) {
+ lineDir1 = box1.axis(i);
+ } else {
+ Vector3 axis = box1.axis(i);
+ if (dot(axis, L) < 0) {
+ axis = -axis;
+ }
+ linePoint1 += axis * a[i];
+ }
+
+ if (i == edge2) {
+ lineDir2 = box2.axis(i);
+ } else {
+ Vector3 axis = box2.axis(i);
+ if (dot(axis, L) > 0) {
+ axis = -axis;
+ }
+ linePoint2 += axis * b[i];
+ }
+ }
+
+ // make lines from the two closest edges, and find
+ // the points that on each line that are closest to the other
+ Line line1 = Line::fromPointAndDirection(linePoint1, lineDir1);
+ Line line2 = Line::fromPointAndDirection(linePoint2, lineDir2);
+ Vector3 closest1;
+ Vector3 closest2;
+
+ closestPointsBetweenLineAndLine(line1, line2, closest1, closest2);
+
+ // take the average of the two closest edge points for the final
+ // contact point
+ contactPoint = (closest1 + closest2) * 0.5;
+ }
+
+ contactPoints.push(contactPoint);
+ contactNormals.push(L);
+
+ return -penetration;
+
+}
+
+
+
+
+float CollisionDetection::penetrationDepthForFixedSphereFixedBox(
+ const Sphere& sphere,
+ const Box& box,
+ Array<Vector3>& contactPoints,
+ Array<Vector3>& contactNormals) {
+
+ contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+ contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+
+ // In its local coordinate frame, the box measures
+ // 2 * halfExtent[a] along dimesion a.
+ Vector3 halfExtent(box.extent(0), box.extent(1), box.extent(2));
+ halfExtent *= 0.5f;
+
+ CoordinateFrame boxFrame;
+ box.getLocalFrame(boxFrame);
+
+ // Transform the sphere to the box's coordinate frame.
+ Vector3 center = boxFrame.pointToObjectSpace(sphere.center);
+
+ // Find the square of the distance from the sphere to the box
+
+
+ // Distance along each axis from the closest side of the box
+ // to the sphere center. Negative values are *inside* the box.
+ Vector3 distOutsideBox;
+
+ // Divide space up into the 27 regions corresponding
+ // to {+|-|0}X, {+|-|0}Y, {+|-|0}Z and classify the
+ // sphere center into one of them.
+ Vector3 centerRegion;
+
+ // In the edge collision case, the edge is between vertices
+ // (constant + variable) and (constant - variable).
+ Vector3 constant, variable;
+
+ int numNonZero = 0;
+
+ // Iterate over axes
+ for (int a = 0; a < 3; ++a) {
+ // For each (box side), see which direction the sphere
+ // is outside the box (positive or negative). Add the
+ // square of that distance to the total distance from
+ // the box.
+
+ float distanceFromLow = -halfExtent[a] - center[a];
+ float distanceFromHigh = center[a] - halfExtent[a];
+
+ if (fabsf(distanceFromLow) < fabsf(distanceFromHigh)) {
+ distOutsideBox[a] = distanceFromLow;
+ } else {
+ distOutsideBox[a] = distanceFromHigh;
+ }
+
+ if (distanceFromLow < 0.0) {
+ if (distanceFromHigh < 0.0) {
+ // Inside the box
+ centerRegion[a] = 0.0;
+ variable[a] = 1.0;
+ } else {
+ // Off the high side
+ centerRegion[a] = 1.0;
+ constant[a] = halfExtent[a];
+ ++numNonZero;
+ }
+ } else if (distanceFromHigh < 0.0) {
+ // Off the low side
+ centerRegion[a] = -1.0;
+ constant[a] = -halfExtent[a];
+ ++numNonZero;
+ } else {
+ debugAssertM(false,
+ "distanceFromLow and distanceFromHigh cannot both be positive");
+ }
+ }
+
+ // Squared distance between the outside of the box and the
+ // sphere center.
+ float d2 = Vector3::zero().max(distOutsideBox).squaredMagnitude();
+
+ if (d2 > square(sphere.radius)) {
+ // There is no penetration because the distance is greater
+ // than the radius of the sphere. This is the common case
+ // and we quickly exit.
+ return -1;
+ }
+
+ // We know there is some penetration but need to classify it.
+ //
+ // Examine the region that contains the center of the sphere. If
+ // there is exactly one non-zero axis, the collision is with a
+ // plane. If there are exactly two non-zero axes, the collision
+ // is with an edge. If all three axes are non-zero, the collision is
+ // with a vertex. If there are no non-zero axes, the center is inside
+ // the box.
+
+ double depth = -1;
+ switch (numNonZero) {
+ case 3: // Vertex collision
+ // The collision point is the vertex at constant, the normal
+ // is the vector from there to the sphere center.
+ contactNormals.append(boxFrame.normalToWorldSpace(constant - center));
+ contactPoints.append(boxFrame.pointToWorldSpace(constant));
+ depth = sphere.radius - sqrt(d2);
+ break;
+
+ case 2: // Edge collision
+ {
+ // TODO: unwrapping the edge constructor and closest point
+ // code will probably make it faster.
+
+ // Determine the edge
+ Line line = Line::fromPointAndDirection(constant, variable);
+
+ // Penetration depth:
+ depth = sphere.radius - sqrt(d2);
+
+ // The contact point is the closes point to the sphere on the line
+ Vector3 X = line.closestPoint(center);
+ contactNormals.append(boxFrame.normalToWorldSpace(X - center).direction());
+ contactPoints.append(boxFrame.pointToWorldSpace(X));
+ }
+ break;
+
+ case 1: // Plane collision
+ {
+ // The plane normal is the centerRegion vector,
+ // so the sphere normal is the negative. Take
+ // it to world space from box-space.
+
+ // Center region doesn't need to be normalized because
+ // it is known to contain only one non-zero value
+ // and that value is +/- 1.
+ Vector3 N = boxFrame.normalToWorldSpace(-centerRegion);
+ contactNormals.append(N);
+
+ // Penetration depth:
+ depth = sphere.radius - sqrtf(d2);
+
+ // Compute the contact point from the penetration depth
+ contactPoints.append(sphere.center + N * (sphere.radius - depth));
+ }
+ break;
+
+ case 0: // Volume collision
+
+ // The sphere center is inside the box. This is an easy case
+ // to handle. Note that all axes of distOutsideBox must
+ // be negative.
+
+ // Arbitratily choose the sphere center as a contact point
+ contactPoints.append(sphere.center);
+
+ // Find the least-negative penetration axis.
+ //
+ // We could have computed this during the loop over the axes,
+ // but since volume collisions are rare (they only occur with
+ // large time steps), this case will seldom be executed and
+ // should not be optimized at the expense of the others.
+ if (distOutsideBox.x > distOutsideBox.y) {
+ if (distOutsideBox.x > distOutsideBox.z) {
+ // Smallest penetration on x-axis
+ // Chose normal based on which side we're closest to.
+ // Keep in mind that this is a normal to the sphere,
+ // so it is the inverse of the box normal.
+ if (center.x > 0) {
+ contactNormals.append(boxFrame.normalToWorldSpace(-Vector3::unitX()));
+ } else {
+ contactNormals.append(boxFrame.normalToWorldSpace(Vector3::unitX()));
+ }
+ depth = -distOutsideBox.x;
+ } else {
+ // Smallest penetration on z-axis
+ goto ZAXIS;
+ }
+ } else if (distOutsideBox.y > distOutsideBox.z) {
+ // Smallest penetration on y-axis
+ // Chose normal based on which side we're closest to.
+ // Keep in mind that this is a normal to the sphere,
+ // so it is the inverse of the box normal.
+ if (center.y > 0) {
+ contactNormals.append(boxFrame.normalToWorldSpace(-Vector3::unitY()));
+ } else {
+ contactNormals.append(boxFrame.normalToWorldSpace(Vector3::unitY()));
+ }
+ depth = -distOutsideBox.y;
+ } else {
+ // Smallest on z-axis
+ZAXIS:
+ // Chose normal based on which side we're closest to.
+ // Keep in mind that this is a normal to the sphere,
+ // so it is the inverse of the box normal.
+ if (center.z > 0) {
+ contactNormals.append(boxFrame.normalToWorldSpace(-Vector3::unitZ()));
+ } else {
+ contactNormals.append(boxFrame.normalToWorldSpace(Vector3::unitZ()));
+ }
+ depth = -distOutsideBox.z;
+ }
+ break;
+
+ default:
+ debugAssertM(false, "Fell through switch");
+ break;
+ }
+
+ return depth;
+}
+
+
+float CollisionDetection::penetrationDepthForFixedSphereFixedSphere(
+ const Sphere& sphereA,
+ const Sphere& sphereB,
+ Array<Vector3>& contactPoints,
+ Array<Vector3>& contactNormals) {
+
+ Vector3 axis = sphereB.center - sphereA.center;
+ double radius = sphereA.radius + sphereB.radius;
+ double mag = axis.magnitude();
+ axis /= mag;
+ double depth = -(mag - radius);
+
+ contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+ contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+
+ if (depth >= 0) {
+ contactPoints.append(sphereA.center + axis * (sphereA.radius - depth / 2));
+ contactNormals.append(axis);
+ }
+
+ return depth;
+}
+
+
+float CollisionDetection::penetrationDepthForFixedSphereFixedPlane(
+ const Sphere& sphereA,
+ const Plane& planeB,
+ Array<Vector3>& contactPoints,
+ Array<Vector3>& contactNormals) {
+
+ Vector3 N;
+ double d;
+
+ planeB.getEquation(N, d);
+
+ double depth = -(sphereA.center.dot(N) + d - sphereA.radius);
+
+ contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+ contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+
+ if (depth >= 0) {
+ contactPoints.append(N * (depth - sphereA.radius) + sphereA.center);
+ contactNormals.append(N);
+ }
+
+ return depth;
+}
+
+
+float CollisionDetection::penetrationDepthForFixedBoxFixedPlane(
+ const Box& box,
+ const Plane& plane,
+ Array<Vector3>& contactPoints,
+ Array<Vector3>& contactNormals) {
+
+ Vector3 N;
+ double d;
+
+ plane.getEquation(N, d);
+
+ contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+ contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
+
+ float lowest = finf();
+ for (int i = 0; i < 8; ++i) {
+ const Vector3 vertex = box.corner(i);
+
+ float x = vertex.dot(N) + (float)d;
+
+ if (x <= 0) {
+ // All vertices below the plane should be contact points.
+ contactPoints.append(vertex);
+ contactNormals.append(-N);
+ }
+
+ lowest = min(lowest, x);
+ }
+
+ // Depth should be a positive number
+ return -lowest;
+}
+
+
+float CollisionDetection::collisionTimeForMovingPointFixedPlane(
+ const Vector3& point,
+ const Vector3& velocity,
+ const Plane& plane,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ // Solve for the time at which normal.dot(point + velocity) + d == 0.
+ double d;
+ Vector3 normal;
+ plane.getEquation(normal, d);
+
+ float vdotN = velocity.dot(normal);
+ float pdotN = point.dot(normal);
+
+ if (fuzzyEq(pdotN + d, 0)) {
+ // The point is *in* the plane.
+ location = point;
+ outNormal = normal;
+ return 0;
+ }
+
+ if (vdotN >= 0) {
+ // no collision will occur
+ location = Vector3::inf();
+ return finf();
+ }
+
+ float t = -(pdotN + d) / vdotN;
+ if (t < 0) {
+ location = Vector3::inf();
+ return finf();
+ } else {
+ location = point + velocity * t;
+ outNormal = normal;
+ return t;
+ }
+}
+
+bool __fastcall CollisionDetection::rayAABox(
+ const Ray& ray,
+ const Vector3& invDir,
+ const AABox& box,
+ const Vector3& boxCenter,
+ float boundingRadiusSquared,
+ Vector3& location,
+ bool& inside) {
+
+ debugAssertM(fabs(ray.direction().squaredLength() - 1.0f) < 0.01f, format("Length = %f", ray.direction().length()));
+ {
+ // Pre-emptive partial bounding sphere test
+ const Vector3 L(boxCenter - ray.origin());
+ float d = L.dot(ray.direction());
+
+ float L2 = L.dot(L);
+ float D2 = square(d);
+ float M2 = L2 - D2;
+
+ if (((d < 0) && (L2 > boundingRadiusSquared)) || (M2 > boundingRadiusSquared)) {
+ inside = false;
+ return false;
+ }
+ // Passing here does not mean that the ray hits the bounding sphere;
+ // we would still have to perform more expensive tests to determine
+ // that.
+ }
+
+ inside = true;
+ const Vector3& MinB = box.low();
+ const Vector3& MaxB = box.high();
+ Vector3 MaxT(-1.0f, -1.0f, -1.0f);
+
+ // Find candidate planes.
+ for (int i = 0; i < 3; ++i) {
+ if (ray.origin()[i] < MinB[i]) {
+ location[i] = MinB[i];
+ inside = false;
+
+ // Calculate T distances to candidate planes
+ if (ray.direction()[i] != 0) {
+ MaxT[i] = (MinB[i] - ray.origin()[i]) * invDir[i];
+ }
+ } else if (ray.origin()[i] > MaxB[i]) {
+ location[i] = MaxB[i];
+ inside = false;
+
+ // Calculate T distances to candidate planes
+ if (ray.direction()[i] != 0) {
+ MaxT[i] = (MaxB[i] - ray.origin()[i]) * invDir[i];
+ }
+ }
+ }
+
+ if (inside) {
+ // Ray origin inside bounding box
+ location = ray.origin();
+ return true;
+ }
+
+ // Get largest of the maxT's for final choice of intersection
+ int WhichPlane = 0;
+ if (MaxT[1] > MaxT[WhichPlane]) {
+ WhichPlane = 1;
+ }
+
+ if (MaxT[2] > MaxT[WhichPlane]) {
+ WhichPlane = 2;
+ }
+
+ // Check final candidate actually inside box
+ if (MaxT[WhichPlane] < 0.0f) {
+ // Miss the box
+ return false;
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ if (i != WhichPlane) {
+ location[i] = ray.origin()[i] + MaxT[WhichPlane] * ray.direction()[i];
+ if ((location[i] < MinB[i]) ||
+ (location[i] > MaxB[i])) {
+ // On this plane we're outside the box extents, so
+ // we miss the box
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+float CollisionDetection::collisionTimeForMovingPointFixedSphere(
+ const Vector3& point,
+ const Vector3& velocity,
+ const Sphere& sphere,
+ Vector3& location,
+ Vector3& outNormal,
+ bool solid) {
+
+ if (solid && sphere.contains(point)) {
+ location = point;
+ outNormal = (point - sphere.center).direction();
+ return 0.0f;
+ }
+
+ float speed = velocity.magnitude();
+ const Vector3& direction = velocity / speed;
+
+ // length of the axis between the start and the sphere
+ const Vector3& L = sphere.center - point;
+ float d = L.dot(direction);
+
+ float L2 = L.dot(L);
+ float R2 = square(sphere.radius);
+ float D2 = square(d);
+
+ if ((d < 0.0f) && (L2 > R2)) {
+ location = Vector3::inf();
+ return finf();
+ }
+
+ const float M2 = L2 - D2;
+
+ if (M2 > R2) {
+ location = Vector3::inf();
+ return finf();
+ }
+
+ float q = sqrt(R2 - M2);
+ float time;
+
+ if (L2 > R2) {
+ time = d - q;
+ } else {
+ time = d + q;
+ }
+
+ time /= speed;
+
+ location = point + velocity * time;
+ outNormal = (location - sphere.center).direction();
+
+ return time;
+}
+
+
+float CollisionDetection::collisionTimeForMovingSphereFixedSphere(
+ const Sphere& movingSphere,
+ const Vector3& velocity,
+ const Sphere& fixedSphere,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ const Vector3& sep = (fixedSphere.center - movingSphere.center);
+ float sepLen = sep.squaredLength();
+ if (sepLen < square(movingSphere.radius + fixedSphere.radius)) {
+ // Interpenetrating
+ outNormal = sep.directionOrZero();
+ location = fixedSphere.center - outNormal * fixedSphere.radius;
+ return 0;
+ }
+
+ float time = collisionTimeForMovingPointFixedSphere
+ (movingSphere.center, velocity,
+ Sphere(fixedSphere.center, fixedSphere.radius + movingSphere.radius),
+ location, outNormal);
+
+ if (time < finf()) {
+ // Location is now the center of the moving sphere at the collision time.
+ // Adjust for the size of the moving sphere. Two spheres always collide
+ // along a line between their centers.
+ location += (location - fixedSphere.center) * movingSphere.radius / fixedSphere.radius;
+ }
+
+ return time;
+}
+
+
+/*
+float CollisionDetection::collisionTimeForMovingPointFixedTriangle(
+ const Vector3& point,
+ const Vector3& velocity,
+ const Triangle& triangle,
+ Vector3& outLocation,
+ Vector3& outNormal) {
+
+ double time = collisionTimeForMovingPointFixedPlane(point, velocity, triangle.plane(), outLocation, outNormal);
+
+ if (time == finf()) {
+ // No collision with the plane of the triangle.
+ return finf();
+ }
+
+ if (isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(), outLocation, triangle.primaryAxis())) {
+ // Collision occured inside the triangle
+ return time;
+ } else {
+ // Missed the triangle
+ outLocation = Vector3::inf();
+ return finf();
+ }
+}*/
+
+/*
+float CollisionDetection::collisionTimeForMovingPointFixedTriangle(
+ const Vector3& orig,
+ const Vector3& dir,
+ const Vector3& vert0,
+ const Vector3& vert1,
+ const Vector3& vert2) {
+
+ // Barycenteric coords
+ double u, v;
+ #define EPSILON 0.000001
+ #define CROSS(dest,v1,v2) \
+ dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
+ dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
+ dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
+
+ #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
+
+ #define SUB(dest,v1,v2) \
+ dest[0]=v1[0]-v2[0]; \
+ dest[1]=v1[1]-v2[1]; \
+ dest[2]=v1[2]-v2[2];
+
+ double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
+
+ // find vectors for two edges sharing vert0
+ SUB(edge1, vert1, vert0);
+ SUB(edge2, vert2, vert0);
+
+ // begin calculating determinant - also used to calculate U parameter
+ CROSS(pvec, dir, edge2);
+
+ // if determinant is near zero, ray lies in plane of triangle
+ const double det = DOT(edge1, pvec);
+
+ if (det < EPSILON) {
+ return finf();
+ }
+
+ // calculate distance from vert0 to ray origin
+ SUB(tvec, orig, vert0);
+
+ // calculate U parameter and test bounds
+ u = DOT(tvec, pvec);
+ if ((u < 0.0) || (u > det)) {
+ // Hit the plane outside the triangle
+ return finf();
+ }
+
+ // prepare to test V parameter
+ CROSS(qvec, tvec, edge1);
+
+ // calculate V parameter and test bounds
+ v = DOT(dir, qvec);
+ if ((v < 0.0) || (u + v > det)) {
+ // Hit the plane outside the triangle
+ return finf();
+ }
+
+ // calculate t, scale parameters, ray intersects triangle
+ // If we want u,v, we can compute this
+ // double t = DOT(edge2, qvec);
+ //const double inv_det = 1.0 / det;
+ //t *= inv_det;
+ //u *= inv_det;
+ //v *= inv_det;
+ // return t;
+
+ // Case where we don't need correct (u, v):
+
+ const double t = DOT(edge2, qvec);
+
+ if (t >= 0) {
+ // Note that det must be positive
+ return t / det;
+ } else {
+ // We had to travel backwards in time to intersect
+ return finf();
+ }
+
+ #undef EPSILON
+ #undef CROSS
+ #undef DOT
+ #undef SUB
+}
+*/
+
+float CollisionDetection::collisionTimeForMovingPointFixedBox(
+ const Vector3& point,
+ const Vector3& velocity,
+ const Box& box,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ double bestTime;
+
+ Vector3 normal;
+ Vector3 v[4];
+
+ // Prime the loop
+ int f = 0;
+ box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
+ bestTime = collisionTimeForMovingPointFixedRectangle(point, velocity, v[0], v[1], v[2], v[3], location, normal);
+ outNormal = normal;
+
+ // Check other faces
+ for (f = 1; f < 6; ++f) {
+ Vector3 pos;
+ box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
+ float time = collisionTimeForMovingPointFixedRectangle(point, velocity, v[0], v[1], v[2], v[3], pos, normal);
+ if (time < bestTime) {
+ bestTime = time;
+ outNormal = normal;
+ location = pos;
+ }
+ }
+
+ return bestTime;
+}
+
+
+float CollisionDetection::collisionTimeForMovingPointFixedAABox(
+ const Vector3& origin,
+ const Vector3& dir,
+ const AABox& box,
+ Vector3& location,
+ bool& Inside,
+ Vector3& normal) {
+
+ if (collisionLocationForMovingPointFixedAABox(origin, dir, box, location, Inside, normal)) {
+ return (location - origin).magnitude();
+ } else {
+ return (float)finf();
+ }
+}
+
+
+bool CollisionDetection::collisionLocationForMovingPointFixedAABox(
+ const Vector3& origin,
+ const Vector3& dir,
+ const AABox& box,
+ Vector3& location,
+ bool& Inside,
+ Vector3& normal) {
+
+ // Integer representation of a floating-point value.
+ #define IR(x) ((uint32&)x)
+
+ Inside = true;
+ const Vector3& MinB = box.low();
+ const Vector3& MaxB = box.high();
+ Vector3 MaxT(-1.0f, -1.0f, -1.0f);
+
+ // Find candidate planes.
+ for (int i = 0; i < 3; ++i) {
+ if (origin[i] < MinB[i]) {
+ location[i] = MinB[i];
+ Inside = false;
+
+ // Calculate T distances to candidate planes
+ if (IR(dir[i])) {
+ MaxT[i] = (MinB[i] - origin[i]) / dir[i];
+ }
+ } else if (origin[i] > MaxB[i]) {
+ location[i] = MaxB[i];
+ Inside = false;
+
+ // Calculate T distances to candidate planes
+ if (IR(dir[i])) {
+ MaxT[i] = (MaxB[i] - origin[i]) / dir[i];
+ }
+ }
+ }
+
+ if (Inside) {
+ // Ray origin inside bounding box
+ location = origin;
+ return false;
+ }
+
+ // Get largest of the maxT's for final choice of intersection
+ int WhichPlane = 0;
+ if (MaxT[1] > MaxT[WhichPlane]) {
+ WhichPlane = 1;
+ }
+
+ if (MaxT[2] > MaxT[WhichPlane]) {
+ WhichPlane = 2;
+ }
+
+ // Check final candidate actually inside box
+ if (IR(MaxT[WhichPlane]) & 0x80000000) {
+ // Miss the box
+ return false;
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ if (i != WhichPlane) {
+ location[i] = origin[i] + MaxT[WhichPlane] * dir[i];
+ if ((location[i] < MinB[i]) ||
+ (location[i] > MaxB[i])) {
+ // On this plane we're outside the box extents, so
+ // we miss the box
+ return false;
+ }
+ }
+ }
+
+ // Choose the normal to be the plane normal facing into the ray
+ normal = Vector3::zero();
+ normal[WhichPlane] = (dir[WhichPlane] > 0) ? -1.0 : 1.0;
+
+ return true;
+
+ #undef IR
+}
+
+
+
+float CollisionDetection::collisionTimeForMovingPointFixedRectangle(
+ const Vector3& point,
+ const Vector3& velocity,
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ Plane plane = Plane(v0, v1, v2);
+
+ float time = collisionTimeForMovingPointFixedPlane(point, velocity, plane, location, outNormal);
+
+ if (time == finf()) {
+ // No collision is ever going to happen
+ return time;
+ }
+
+ if (isPointInsideRectangle(v0, v1, v2, v3, plane.normal(), location)) {
+ // The intersection point is inside the rectangle; that is the location where
+ // the point hits the rectangle.
+ return time;
+ } else {
+ return finf();
+ }
+}
+
+/** Used by findRayCapsuleIntersection.
+ @cite From magic software http://www.magic-software.com/Source/Intersection3D/MgcIntr3DLinCap.cpp */
+static int findRayCapsuleIntersectionAux(
+ const Vector3& rkOrigin,
+ const Vector3& rkDirection,
+ const Capsule& rkCapsule,
+ double afT[2]) {
+
+ Vector3 capsuleDirection = rkCapsule.point(1) - rkCapsule.point(0);
+
+ // set up quadratic Q(t) = a*t^2 + 2*b*t + c
+ Vector3 kU, kV, kW = capsuleDirection;
+ float fWLength = kW.unitize();
+ Vector3::generateOrthonormalBasis(kU, kV, kW);
+ Vector3 kD(kU.dot(rkDirection), kV.dot(rkDirection), kW.dot(rkDirection));
+ float fDLength = kD.unitize();
+
+ float fEpsilon = 1e-6f;
+
+ float fInvDLength = 1.0f/fDLength;
+ Vector3 kDiff = rkOrigin - rkCapsule.point(0);
+ Vector3 kP(kU.dot(kDiff),kV.dot(kDiff),kW.dot(kDiff));
+ float fRadiusSqr = square(rkCapsule.radius());
+
+ float fInv, fA, fB, fC, fDiscr, fRoot, fT, fTmp;
+
+ // Is the velocity parallel to the capsule direction? (or zero)
+ if ((abs(kD.z) >= 1.0f - fEpsilon) || (fDLength < fEpsilon)) {
+
+ float fAxisDir = rkDirection.dot(capsuleDirection);
+
+ fDiscr = fRadiusSqr - kP.x*kP.x - kP.y*kP.y;
+ if ((fAxisDir < 0) && (fDiscr >= 0.0f)) {
+ // Velocity anti-parallel to the capsule direction
+ fRoot = sqrt(fDiscr);
+ afT[0] = (kP.z + fRoot)*fInvDLength;
+ afT[1] = -(fWLength - kP.z + fRoot)*fInvDLength;
+ return 2;
+ } else if ((fAxisDir > 0) && (fDiscr >= 0.0f)) {
+ // Velocity parallel to the capsule direction
+ fRoot = sqrt(fDiscr);
+ afT[0] = -(kP.z + fRoot)*fInvDLength;
+ afT[1] = (fWLength - kP.z + fRoot)*fInvDLength;
+ return 2;
+ } else {
+ // sphere heading wrong direction, or no velocity at all
+ return 0;
+ }
+ }
+
+ // test intersection with infinite cylinder
+ fA = kD.x*kD.x + kD.y*kD.y;
+ fB = kP.x*kD.x + kP.y*kD.y;
+ fC = kP.x*kP.x + kP.y*kP.y - fRadiusSqr;
+ fDiscr = fB*fB - fA*fC;
+ if (fDiscr < 0.0f) {
+ // line does not intersect infinite cylinder
+ return 0;
+ }
+
+ int iQuantity = 0;
+
+ if (fDiscr > 0.0f) {
+ // line intersects infinite cylinder in two places
+ fRoot = sqrt(fDiscr);
+ fInv = 1.0f/fA;
+ fT = (-fB - fRoot)*fInv;
+ fTmp = kP.z + fT*kD.z;
+ if ((0.0f <= fTmp) && (fTmp <= fWLength)) {
+ afT[iQuantity] = fT * fInvDLength;
+ iQuantity++;
+ }
+
+ fT = (-fB + fRoot)*fInv;
+ fTmp = kP.z + fT*kD.z;
+
+ if ((0.0f <= fTmp) && (fTmp <= fWLength)) {
+ afT[iQuantity++] = fT*fInvDLength;
+ }
+
+ if (iQuantity == 2) {
+ // line intersects capsule wall in two places
+ return 2;
+ }
+ } else {
+ // line is tangent to infinite cylinder
+ fT = -fB/fA;
+ fTmp = kP.z + fT*kD.z;
+ if ((0.0f <= fTmp) && (fTmp <= fWLength)) {
+ afT[0] = fT*fInvDLength;
+ return 1;
+ }
+ }
+
+ // test intersection with bottom hemisphere
+ // fA = 1
+ fB += kP.z*kD.z;
+ fC += kP.z*kP.z;
+ fDiscr = fB*fB - fC;
+ if (fDiscr > 0.0f) {
+ fRoot = sqrt(fDiscr);
+ fT = -fB - fRoot;
+ fTmp = kP.z + fT*kD.z;
+ if (fTmp <= 0.0f) {
+ afT[iQuantity++] = fT*fInvDLength;
+ if (iQuantity == 2) {
+ return 2;
+ }
+ }
+
+ fT = -fB + fRoot;
+ fTmp = kP.z + fT*kD.z;
+ if (fTmp <= 0.0f) {
+ afT[iQuantity++] = fT*fInvDLength;
+ if (iQuantity == 2) {
+ return 2;
+ }
+ }
+ } else if (fDiscr == 0.0f) {
+ fT = -fB;
+ fTmp = kP.z + fT*kD.z;
+ if (fTmp <= 0.0f) {
+ afT[iQuantity++] = fT*fInvDLength;
+ if (iQuantity == 2) {
+ return 2;
+ }
+ }
+ }
+
+ // test intersection with top hemisphere
+ // fA = 1
+ fB -= kD.z*fWLength;
+ fC += fWLength*(fWLength - 2.0f*kP.z);
+
+ fDiscr = fB*fB - fC;
+ if (fDiscr > 0.0f) {
+ fRoot = sqrt(fDiscr);
+ fT = -fB - fRoot;
+ fTmp = kP.z + fT*kD.z;
+ if (fTmp >= fWLength) {
+ afT[iQuantity++] = fT*fInvDLength;
+ if (iQuantity == 2) {
+ return 2;
+ }
+ }
+
+ fT = -fB + fRoot;
+ fTmp = kP.z + fT*kD.z;
+ if (fTmp >= fWLength) {
+ afT[iQuantity++] = fT*fInvDLength;
+ if (iQuantity == 2) {
+ return 2;
+ }
+ }
+ } else if (fDiscr == 0.0f) {
+ fT = -fB;
+ fTmp = kP.z + fT*kD.z;
+ if (fTmp >= fWLength) {
+ afT[iQuantity++] = fT*fInvDLength;
+ if (iQuantity == 2) {
+ return 2;
+ }
+ }
+ }
+
+ return iQuantity;
+}
+
+
+/** Used by collisionTimeForMovingPointFixedCapsule.
+ @cite From magic software http://www.magic-software.com/Source/Intersection3D/MgcIntr3DLinCap.cpp
+
+ @param rkRay The ray
+ @param rkCapsule The capsule
+ @param riQuantity The number of intersections found
+ @param akPoint The intersections found
+ @return True if there is at least one intersection
+ */
+static bool findRayCapsuleIntersection(
+ const Ray& rkRay,
+ const Capsule& rkCapsule,
+ int& riQuantity,
+ Vector3 akPoint[2]) {
+
+ double afT[2];
+ riQuantity = findRayCapsuleIntersectionAux(rkRay.origin(), rkRay.direction(), rkCapsule, afT);
+
+ // Only return intersections that occur in the future
+ int iClipQuantity = 0;
+ int i;
+ for (i = 0; i < riQuantity; ++i) {
+ if (afT[i] >= 0.0f) {
+ akPoint[iClipQuantity] = rkRay.origin() + afT[i] * rkRay.direction();
+ ++iClipQuantity;
+ }
+ }
+
+ riQuantity = iClipQuantity;
+ return (riQuantity > 0);
+}
+
+float CollisionDetection::collisionTimeForMovingPointFixedCapsule(
+ const Vector3& _point,
+ const Vector3& velocity,
+ const Capsule& capsule,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ float timeScale = velocity.magnitude();
+
+ if (timeScale == 0.0f) {
+ timeScale = 1;
+ }
+
+ Vector3 direction = velocity / timeScale;
+ int numIntersections;
+ Vector3 intersection[2];
+ findRayCapsuleIntersection(Ray::fromOriginAndDirection(_point, direction), capsule, numIntersections, intersection);
+
+ if (numIntersections == 2) {
+ // A collision can only occur if there are two intersections. If there is one
+ // intersection, that one is exiting the capsule.
+
+ // Find the entering intersection (the first one that occurs).
+ float d0 = (intersection[0] - _point).squaredMagnitude();
+ float d1 = (intersection[1] - _point).squaredMagnitude();
+
+ // Compute the surface normal (if we aren't ignoring the result)
+ if (&outNormal != &ignore) {
+ Vector3 p2 = LineSegment::fromTwoPoints(capsule.point(0), capsule.point(1)).closestPoint(_point);
+ outNormal = (_point - p2).direction();
+ }
+
+ if (d0 > d1) {
+ location = intersection[1];
+ return sqrt(d1) / timeScale;
+ } else {
+ location = intersection[0];
+ return sqrt(d0) / timeScale;
+ }
+ } else {
+ // No entering intersection discovered; return no intersection.
+ location = Vector3::inf();
+ return finf();
+ }
+}
+
+
+float CollisionDetection::collisionTimeForMovingSphereFixedPlane(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Plane& plane,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ if (sphere.radius == 0) {
+ // Optimization for zero radius sphere
+ return collisionTimeForMovingPointFixedPlane(sphere.center, velocity, plane, location, outNormal);
+ }
+
+ // The collision point on the sphere will be the point at
+ // center - (radius * normal). Collisions only occur when
+ // the sphere is travelling into the plane.
+
+ double d;
+ plane.getEquation(outNormal, d);
+
+ double vdotN = velocity.dot(outNormal);
+
+ if (fuzzyGt(vdotN, 0)) {
+ // No collision when the sphere is moving towards a backface.
+ location = Vector3::inf();
+ return (float)finf();
+ }
+
+ float cdotN = sphere.center.dot(outNormal);
+
+ // Distance from the center to the plane
+ float distance = cdotN + (float)d;
+
+ // Where is the collision on the sphere?
+ Vector3 point = sphere.center - (sphere.radius * outNormal);
+
+ if (fuzzyLe(G3D::abs(distance), sphere.radius)) {
+ // Already interpenetrating
+ location = sphere.center - distance * outNormal;
+ return 0;
+ } else {
+ return collisionTimeForMovingPointFixedPlane(point, velocity, plane, location, outNormal);
+ }
+
+}
+
+
+float CollisionDetection::collisionTimeForMovingSphereFixedTriangle(
+ const class Sphere& sphere,
+ const Vector3& velocity,
+ const Triangle& triangle,
+ Vector3& outLocation,
+ float b[3]) {
+
+ Vector3 dummy;
+ float time = collisionTimeForMovingSphereFixedPlane(sphere, velocity, triangle.plane(),
+ outLocation, dummy);
+
+ if (time == finf()) {
+ // No collision is ever going to happen
+ return time;
+ }
+
+ // We will hit the plane of the triangle at *time*. See if
+ // the intersection point actually is within the triangle.
+
+ if (isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(),
+ outLocation, b, triangle.primaryAxis())) {
+
+ // The intersection point is inside the triangle; that is the location where
+ // the sphere hits the triangle.
+
+# ifdef G3D_DEBUG
+ {
+ // Internal consistency checks
+ debugAssertM(b[0] >= 0.0 && b[0] <= 1.0f, "Intersection is outside triangle.");
+ debugAssertM(b[1] >= 0.0 && b[1] <= 1.0f, "Intersection is outside triangle.");
+ debugAssertM(b[2] >= 0.0 && b[2] <= 1.0f, "Intersection is outside triangle.");
+ Vector3 blend =
+ b[0] * triangle.vertex(0) +
+ b[1] * triangle.vertex(1) +
+ b[2] * triangle.vertex(2);
+ debugAssertM(blend.fuzzyEq(outLocation), "Barycentric coords don't match intersection.");
+ // Call again so that we can debug the problem
+ // isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(),
+ // outLocation, b, triangle.primaryAxis());
+ }
+# endif
+
+ return time;
+ }
+
+ // The collision (if it exists) is with a point on the triangle perimeter.
+ // Switch over to moving the triangle towards a fixed sphere and see at what time
+ // they will hit.
+
+ // Closest point on the triangle to the sphere intersection with the plane.
+ int edgeIndex;
+ const Vector3& point = closestPointOnTrianglePerimeter(triangle._vertex, triangle.edgeDirection,
+ triangle.edgeMagnitude, outLocation, edgeIndex);
+
+ float t = 0;
+ if (! sphere.contains(point)) {
+ // The point is outside the sphere--see when it will hit
+ t = collisionTimeForMovingPointFixedSphere(point, -velocity, sphere, dummy, dummy);
+ }
+
+ if (t < finf()) {
+ outLocation = point;
+ // Compute Barycentric coords
+
+ // Index of the next vertex
+ static const int next[] = {1, 2, 0};
+
+ // Project along the edge in question.
+ // Avoid sqrt by taking advantage of the existing edgeDirection unit vector.
+ b[next[edgeIndex]] = (outLocation - triangle._vertex[edgeIndex]).dot
+ (triangle.edgeDirection[edgeIndex]) / triangle.edgeMagnitude[edgeIndex];
+
+ b[edgeIndex] = 1.0f - b[next[edgeIndex]];
+
+ b[next[next[edgeIndex]]] = 0.0f;
+
+# ifdef G3D_DEBUG
+ {
+ // Internal consistency checks
+ for (int i = 0; i < 3; ++i) {
+ debugAssertM(fuzzyGe(b[i], 0.0f) && fuzzyLe(b[i], 1.0f), "Intersection is outside triangle.");
+ }
+ Vector3 blend =
+ b[0] * triangle.vertex(0) +
+ b[1] * triangle.vertex(1) +
+ b[2] * triangle.vertex(2);
+ debugAssertM(blend.fuzzyEq(outLocation),
+ format("Barycentric coords don't match intersection. %s != %s",
+ blend.toString().c_str(),
+ outLocation.toString().c_str()));
+
+ // Call again so that we can debug the problem
+ collisionTimeForMovingPointFixedSphere(point, -velocity, sphere, dummy, dummy);
+ }
+# endif
+
+ // Due to tiny roundoffs, these values might be slightly out of bounds.
+ // Ensure that they are legal. Note that the above debugging code
+ // verifies that we are not clamping truly illegal values.
+ for (int i = 0; i < 3; ++i) {
+ b[i] = clamp(b[i], 0.0f, 1.0f);
+ }
+ }
+
+ // The collision occured at the point, if it occured. The normal
+ // was the plane normal, computed above.
+
+ return t;
+}
+
+
+float CollisionDetection::collisionTimeForMovingSphereFixedRectangle(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ Plane plane(v0, v1, v2);
+
+ float time = collisionTimeForMovingSphereFixedPlane(sphere, velocity, plane, location, outNormal);
+
+ if (time == finf()) {
+ // No collision is ever going to happen
+ return time;
+ }
+
+ if (isPointInsideRectangle(v0, v1, v2, v3, plane.normal(), location)) {
+ // The intersection point is inside the rectangle; that is the location where
+ // the sphere hits the rectangle.
+ return time;
+ }
+
+ // Switch over to moving the rectangle towards a fixed sphere and see at what time
+ // they will hit.
+
+ Vector3 point = closestPointToRectanglePerimeter(v0, v1, v2, v3, sphere.center);
+
+ Vector3 dummy;
+ double t = collisionTimeForMovingPointFixedSphere(point, -velocity, sphere, location, dummy);
+
+ // Normal is the plane normal, location is the original location of the point.
+ location = point;
+
+ return t;
+}
+
+
+float CollisionDetection::collisionTimeForMovingSphereFixedBox(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Box& box,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ if (fixedSolidSphereIntersectsFixedSolidBox(sphere, box)) {
+ // TODO: Compute more useful location and normal?
+ location = sphere.center;
+ outNormal = Vector3::zero();
+ return 0;
+ }
+
+ float bestTime;
+
+ Vector3 v[4];
+ int f = 0;
+ box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
+ bestTime = collisionTimeForMovingSphereFixedRectangle(sphere, velocity, v[0], v[1], v[2], v[3], location, outNormal);
+
+ for (f = 1; f < 6; ++f) {
+ Vector3 pos, normal;
+ box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
+ float time = collisionTimeForMovingSphereFixedRectangle(sphere, velocity, v[0], v[1], v[2], v[3], pos, normal);
+ if (time < bestTime) {
+ bestTime = time;
+ location = pos;
+ outNormal = normal;
+ }
+ }
+
+ return bestTime;
+}
+
+
+float CollisionDetection::collisionTimeForMovingSphereFixedCapsule(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Capsule& capsule,
+ Vector3& location,
+ Vector3& outNormal) {
+
+ (void)outNormal;
+
+ Capsule _capsule(capsule.point(0), capsule.point(1), capsule.radius() + sphere.radius);
+
+ Vector3 normal;
+ double time = collisionTimeForMovingPointFixedCapsule(sphere.center, velocity, _capsule, location, normal);
+
+ if (time < finf()) {
+ // Location is now the position of the center of the sphere at the time of collision.
+ // We have to adjust the collision location for the size of the sphere.
+ location -= sphere.radius * normal;
+ }
+
+ return time;
+}
+
+
+Vector3 CollisionDetection::bounceDirection(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const float collisionTime,
+ const Vector3& collisionLocation,
+ const Vector3& collisionNormal) {
+
+ // Location when the collision occurs
+ Vector3 sphereLocation = sphere.center + velocity * collisionTime;
+
+ Vector3 normal = (sphereLocation - collisionLocation);
+ if (fuzzyEq(normal.squaredMagnitude(), 0)) {
+ normal = collisionNormal;
+ } else {
+ normal.unitize();
+ }
+
+ Vector3 direction = velocity.direction();
+
+ // Reflect direction about the normal
+ return direction - 2.0 * normal * normal.dot(direction);
+}
+
+
+Vector3 CollisionDetection::slideDirection(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const float collisionTime,
+ const Vector3& collisionLocation) {
+
+ Vector3 sphereLocation = sphere.center + velocity * collisionTime;
+ Vector3 normal = (sphereLocation - collisionLocation).direction();
+ Vector3 direction = velocity.direction();
+
+ // subtract off the part in the direction away from the normal.
+ return direction - normal * normal.dot(direction);
+}
+
+
+Vector3 CollisionDetection::closestPointOnLineSegment(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& point) {
+
+ const Vector3& edge = (v1 - v0);
+ float edgeLength = edge.magnitude();
+
+ if (edgeLength == 0) {
+ // The line segment is a point
+ return v0;
+ }
+
+ return closestPointOnLineSegment(v0, v1, edge / edgeLength, edgeLength, point);
+}
+
+
+Vector3 CollisionDetection::closestPointOnLineSegment(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& edgeDirection,
+ const float edgeLength,
+ const Vector3& point) {
+
+ debugAssert((v1 - v0).direction().fuzzyEq(edgeDirection));
+ debugAssert(fuzzyEq((v1 - v0).magnitude(), edgeLength));
+
+ // Vector towards the point
+ const Vector3& c = point - v0;
+
+ // Projected onto the edge itself
+ float t = edgeDirection.dot(c);
+
+ if (t <= 0) {
+ // Before the start
+ return v0;
+ } else if (t >= edgeLength) {
+ // After the end
+ return v1;
+ } else {
+ // At distance t along the edge
+ return v0 + edgeDirection * t;
+ }
+}
+
+
+Vector3 CollisionDetection::closestPointOnTrianglePerimeter(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& point) {
+
+ Vector3 v[3] = {v0, v1, v2};
+ Vector3 edgeDirection[3] = {(v1 - v0), (v2 - v1), (v0 - v2)};
+ float edgeLength[3];
+
+ for (int i = 0; i < 3; ++i) {
+ edgeLength[i] = edgeDirection[i].magnitude();
+ edgeDirection[i] /= edgeLength[i];
+ }
+
+ int edgeIndex;
+ return closestPointOnTrianglePerimeter(v, edgeDirection, edgeLength, point, edgeIndex);
+}
+
+
+Vector3 CollisionDetection::closestPointOnTrianglePerimeter(
+ const Vector3 v[3],
+ const Vector3 edgeDirection[3],
+ const float edgeLength[3],
+ const Vector3& point,
+ int& edgeIndex) {
+
+ // Closest point on segment from v[i] to v[i + 1]
+ Vector3 r[3];
+
+ // Distance squared from r[i] to point
+ float d[3];
+
+ // Index of the next point
+ static const int next[] = {1, 2, 0};
+
+ for (int i = 0; i < 3; ++i) {
+ r[i] = closestPointOnLineSegment(v[i], v[next[i]], edgeDirection[i], edgeLength[i], point);
+ d[i] = (r[i] - point).squaredMagnitude();
+ }
+
+ if (d[0] < d[1]) {
+ if (d[0] < d[2]) {
+ // Between v0 and v1
+ edgeIndex = 0;
+ } else {
+ // Between v2 and v0
+ edgeIndex = 2;
+ }
+ } else {
+ if (d[1] < d[2]) {
+ // Between v1 and v2
+ edgeIndex = 1;
+ } else {
+ // Between v2 and v0
+ edgeIndex = 2;
+ }
+ }
+
+# ifdef G3D_DEBUG
+ {
+ Vector3 diff = r[edgeIndex] - v[edgeIndex];
+ debugAssertM(fuzzyEq(diff.direction().dot(edgeDirection[edgeIndex]), 1.0f) ||
+ diff.fuzzyEq(Vector3::zero()), "Point not on correct triangle edge");
+ float frac = diff.dot(edgeDirection[edgeIndex])/edgeLength[edgeIndex];
+ debugAssertM(frac >= -0.000001, "Point off low side of edge.");
+ debugAssertM(frac <= 1.000001, "Point off high side of edge.");
+ }
+# endif
+
+ return r[edgeIndex];
+}
+
+
+bool CollisionDetection::isPointInsideTriangle(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& normal,
+ const Vector3& point,
+ float b[3],
+ Vector3::Axis primaryAxis) {
+
+ if (primaryAxis == Vector3::DETECT_AXIS) {
+ primaryAxis = normal.primaryAxis();
+ }
+
+ // Check that the point is within the triangle using a Barycentric
+ // coordinate test on a two dimensional plane.
+ int i, j;
+
+ switch (primaryAxis) {
+ case Vector3::X_AXIS:
+ i = Vector3::Y_AXIS;
+ j = Vector3::Z_AXIS;
+ break;
+
+ case Vector3::Y_AXIS:
+ i = Vector3::Z_AXIS;
+ j = Vector3::X_AXIS;
+ break;
+
+ case Vector3::Z_AXIS:
+ i = Vector3::X_AXIS;
+ j = Vector3::Y_AXIS;
+ break;
+
+ default:
+ // This case is here to supress a warning on Linux
+ i = j = 0;
+ debugAssertM(false, "Should not get here.");
+ break;
+ }
+
+ // See if all barycentric coordinates are non-negative
+
+ // 2D area via cross product
+# define AREA2(d, e, f) (((e)[i] - (d)[i]) * ((f)[j] - (d)[j]) - ((f)[i] - (d)[i]) * ((e)[j] - (d)[j]))
+
+ // Area of the polygon
+ float area = AREA2(v0, v1, v2);
+ if (area == 0) {
+ // This triangle has zero area, so the point must not
+ // be in it unless the triangle point is the test point.
+ return (v0 == point);
+ }
+
+ debugAssert(area != 0);
+
+ float invArea = 1.0f / area;
+
+ // (avoid normalization until absolutely necessary)
+ b[0] = AREA2(point, v1, v2) * invArea;
+
+ if ((b[0] < 0.0f) || (b[0] > 1.0f)) {
+ return false;
+ }
+
+ b[1] = AREA2(v0, point, v2) * invArea;
+ if ((b[1] < 0.0f) || (b[1] > 1.0f)) {
+ return false;
+ }
+
+ b[2] = 1.0f - b[0] - b[1];
+
+# undef AREA2
+
+ return (b[2] >= 0.0f) && (b[2] <= 1.0f);
+}
+
+
+bool CollisionDetection::isPointInsideRectangle(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ const Vector3& normal,
+ const Vector3& point) {
+
+ return isPointInsideTriangle(v0, v1, v2, normal, point) ||
+ isPointInsideTriangle(v2, v3, v0, normal, point);
+}
+
+
+Vector3 CollisionDetection::closestPointToRectanglePerimeter(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ const Vector3& point) {
+
+ Vector3 r0 = closestPointOnLineSegment(v0, v1, point);
+ Vector3 r1 = closestPointOnLineSegment(v1, v2, point);
+ Vector3 r2 = closestPointOnLineSegment(v2, v3, point);
+ Vector3 r3 = closestPointOnLineSegment(v3, v0, point);
+
+ double d0 = (r0 - point).squaredMagnitude();
+ double d1 = (r1 - point).squaredMagnitude();
+ double d2 = (r2 - point).squaredMagnitude();
+ double d3 = (r3 - point).squaredMagnitude();
+
+ if (d0 < d1) {
+ if (d0 < d2) {
+ if (d0 < d3) {
+ return r0;
+ } else {
+ return r3;
+ }
+ } else {
+ if (d2 < d3) {
+ return r2;
+ } else {
+ return r3;
+ }
+ }
+ } else {
+ if (d1 < d2) {
+ if (d1 < d3) {
+ return r1;
+ } else {
+ return r3;
+ }
+ } else {
+ if (d2 < d3) {
+ return r2;
+ } else {
+ return r3;
+ }
+ }
+ }
+}
+
+
+Vector3 CollisionDetection::closestPointToRectangle(
+ const Vector3& v0,
+ const Vector3& v1,
+ const Vector3& v2,
+ const Vector3& v3,
+ const Vector3& point) {
+
+ Plane plane(v0, v1, v2);
+
+ // Project the point into the plane
+ double a, b, c, d;
+ plane.getEquation(a, b, c, d);
+
+ double distance = a*point.x + b*point.y + c*point.z + d;
+ Vector3 planePoint = point - distance * plane.normal();
+
+ if (isPointInsideRectangle(v0, v1, v2, v3, plane.normal(), planePoint)) {
+ return planePoint;
+ } else {
+ return closestPointToRectanglePerimeter(v0, v1, v2, v3, planePoint);
+ }
+}
+
+
+bool CollisionDetection::fixedSolidSphereIntersectsFixedSolidSphere(
+ const Sphere& sphere1,
+ const Sphere& sphere2) {
+
+ return (sphere1.center - sphere2.center).squaredMagnitude() < square(sphere1.radius + sphere2.radius);
+}
+
+
+bool CollisionDetection::fixedSolidSphereIntersectsFixedSolidBox(
+ const Sphere& sphere,
+ const Box& box) {
+
+ // If the center of the sphere is within the box, the whole
+ // sphere is within the box.
+ if (box.contains(sphere.center)) {
+ return true;
+ }
+
+ float r2 = square(sphere.radius);
+
+ // Find the closest point on the surface of the box to the sphere. If
+ // this point is within the sphere's radius, they intersect.
+ int f;
+ for (f = 0; f < 6; ++f) {
+ Vector3 v0, v1, v2, v3;
+ box.getFaceCorners(f, v0, v1, v2, v3);
+ if ((closestPointToRectangle(v0, v1, v2, v3, sphere.center) - sphere.center).squaredMagnitude() <= r2) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+bool CollisionDetection::movingSpherePassesThroughFixedBox(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Box& box,
+ double timeLimit) {
+
+ // If they intersect originally, they definitely pass through each other.
+ if (fixedSolidSphereIntersectsFixedSolidBox(sphere, box)) {
+ return true;
+ }
+
+ // See if the sphere hits the box during the time period.
+ Vector3 dummy1, dummy2;
+
+ return (collisionTimeForMovingSphereFixedBox(sphere, velocity, box, dummy1, dummy2) < timeLimit);
+}
+
+
+bool CollisionDetection::movingSpherePassesThroughFixedSphere(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Sphere& fixedSphere,
+ double timeLimit) {
+
+ if (fixedSolidSphereIntersectsFixedSolidSphere(sphere, fixedSphere)) {
+ return true;
+ }
+
+ // Extend the fixed sphere by the radius of the moving sphere
+ Sphere bigFixed(fixedSphere.center, fixedSphere.radius + sphere.radius);
+ Vector3 dummy1, dummy2;
+
+ // If the sphere collides with the other sphere during the time limit, it passes through
+ return (collisionTimeForMovingPointFixedSphere(sphere.center, velocity, bigFixed, dummy1, dummy2) < timeLimit);
+}
+
+
+
+bool CollisionDetection::fixedSolidSphereIntersectsFixedTriangle(
+ const Sphere& sphere,
+ const Triangle& triangle) {
+
+ // How far is the sphere from the plane of the triangle
+ const Plane& plane = triangle.plane();
+
+ // Does the closest point to the sphere center lie within the triangle?
+ Vector3 v = plane.closestPoint(sphere.center);
+
+ // Is the closest point to the plane within the sphere?
+ if ((v - sphere.center).squaredLength() <= square(sphere.radius)) {
+ // Is it also within the triangle?
+ float b[3];
+ if (isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(),
+ v, b, triangle.primaryAxis())){
+ // The closest point is inside the triangle
+ return true;
+ }
+ }
+
+ // ignored
+ int edgeIndex;
+
+ v = closestPointOnTrianglePerimeter(triangle._vertex, triangle.edgeDirection, triangle.edgeMagnitude, sphere.center, edgeIndex);
+
+ // Is the closest point within the sphere?
+ return ((v - sphere.center).squaredLength() <= square(sphere.radius));
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// AABB-triangle overlap test code based on Tomas Akenine-Möller's
+// http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/tribox3.txt
+// Ported 2008-12-28
+
+#define X 0
+#define Y 1
+#define Z 2
+
+#define FINDMINMAX(x0, x1, x2, min, max) \
+ min = max = x0; \
+ if(x1<min) min=x1;\
+ if(x1>max) max=x1;\
+ if(x2<min) min=x2;\
+ if(x2>max) max=x2;
+
+static bool planeBoxOverlap(const Vector3& normal, const Vector3& vert, const Vector3& maxbox) {
+ Vector3 vmin, vmax;
+ float v;
+
+ // for each axis
+ for(int a = 0; a < 3; ++a) {
+ v = vert[a];
+
+ if (normal[a] > 0.0f) {
+ vmin[a] = -maxbox[a] - v;
+ vmax[a] = maxbox[a] - v;
+ } else {
+ vmin[a] = maxbox[a] - v;
+ vmax[a] = -maxbox[a] - v;
+ }
+ }
+
+ if (normal.dot(vmin) > 0.0f) {
+ return false;
+ } else if (normal.dot(vmax) >= 0.0f) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/*======================== X-tests ========================*/
+
+#define AXISTEST_X01(a, b, fa, fb) \
+ p0 = a*v0[Y] - b*v0[Z]; \
+ p2 = a*v2[Y] - b*v2[Z]; \
+ if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
+ rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
+ if(min>rad || max<-rad) return false;
+
+
+#define AXISTEST_X2(a, b, fa, fb) \
+ p0 = a*v0[Y] - b*v0[Z]; \
+ p1 = a*v1[Y] - b*v1[Z]; \
+ if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
+ rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
+ if(min>rad || max<-rad) return false;
+
+/*======================== Y-tests ========================*/
+
+#define AXISTEST_Y02(a, b, fa, fb) \
+ p0 = -a*v0[X] + b*v0[Z]; \
+ p2 = -a*v2[X] + b*v2[Z]; \
+ if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
+ rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
+ if(min>rad || max<-rad) return false;
+
+#define AXISTEST_Y1(a, b, fa, fb) \
+ p0 = -a*v0[X] + b*v0[Z]; \
+ p1 = -a*v1[X] + b*v1[Z]; \
+ if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
+ rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
+ if(min>rad || max<-rad) return false;
+
+/*======================== Z-tests ========================*/
+
+#define AXISTEST_Z12(a, b, fa, fb) \
+ p1 = a*v1[X] - b*v1[Y]; \
+ p2 = a*v2[X] - b*v2[Y]; \
+ if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \
+ rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
+ if(min>rad || max<-rad) return false;
+
+#define AXISTEST_Z0(a, b, fa, fb) \
+ p0 = a*v0[X] - b*v0[Y]; \
+ p1 = a*v1[X] - b*v1[Y]; \
+ if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
+ rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
+ if(min>rad || max<-rad) return false;
+
+bool CollisionDetection::fixedSolidBoxIntersectsFixedTriangle(
+ const AABox& box, const Triangle& tri) {
+
+ // use separating axis theorem to test overlap between triangle and box
+ // need to test for overlap in these directions:
+ // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle
+ // we do not even need to test these)
+ // 2) normal of the triangle
+ // 3) crossproduct(edge from tri, {x,y,z}-direction)
+ // this gives 3x3=9 more tests
+
+ // This is the fastest branch (on Sun).
+ // Move the triangle to the object space of the box
+ // Triangle vertices in box object space
+
+ const Vector3& boxcenter = box.center();
+ const Vector3& boxhalfsize = box.extent() * 0.5f;
+
+ const Vector3& v0 = tri.vertex(0) - boxcenter;
+ const Vector3& v1 = tri.vertex(1) - boxcenter;
+ const Vector3& v2 = tri.vertex(2) - boxcenter;
+
+ // Compute triangle edges in object space
+ const Vector3& e0 = v1 - v0;
+ const Vector3& e1 = v2 - v1;
+ const Vector3& e2 = v0 - v2;
+
+ // Bullet 3:
+ // test the 9 tests first (this was faster)
+ float min,max,p0,p1,p2,rad;
+ Vector3 fe;
+
+ fe = abs(e0);
+ AXISTEST_X01(e0[Z], e0[Y], fe[Z], fe[Y]);
+ AXISTEST_Y02(e0[Z], e0[X], fe[Z], fe[X]);
+ AXISTEST_Z12(e0[Y], e0[X], fe[Y], fe[X]);
+
+ fe = abs(e1);
+ AXISTEST_X01(e1[Z], e1[Y], fe[Z], fe[Y]);
+ AXISTEST_Y02(e1[Z], e1[X], fe[Z], fe[X]);
+ AXISTEST_Z0 (e1[Y], e1[X], fe[Y], fe[X]);
+
+ fe = abs(e2);
+ AXISTEST_X2 (e2[Z], e2[Y], fe[Z], fe[Y]);
+ AXISTEST_Y1 (e2[Z], e2[X], fe[Z], fe[X]);
+ AXISTEST_Z12(e2[Y], e2[X], fe[Y], fe[X]);
+
+ // Bullet 1:
+ // first test overlap in the {x,y,z}-directions
+ // find min, max of the triangle each direction, and test for overlap in
+ // that direction -- this is equivalent to testing a minimal AABB around
+ // the triangle against the AABB
+
+ // test in X-direction
+ FINDMINMAX(v0[X],v1[X],v2[X],min,max);
+ if (min > boxhalfsize[X] || max < -boxhalfsize[X]) {
+ return false;
+ }
+
+ // test in Y-direction
+ FINDMINMAX(v0[Y],v1[Y],v2[Y],min,max);
+ if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) {
+ return false;
+ }
+
+ // test in Z-direction
+ FINDMINMAX(v0[Z],v1[Z],v2[Z],min,max);
+ if (min > boxhalfsize[Z] || max < -boxhalfsize[Z]) {
+ return false;
+ }
+
+ // Bullet 2:
+ // test if the box intersects the plane of the triangle
+ // compute plane equation of triangle: normal*x+d=0
+
+ if (! planeBoxOverlap(tri.normal(), v0, boxhalfsize)) {
+ return false;
+ }
+
+ // box and triangle overlap
+ return true;
+}
+#undef X
+#undef Y
+#undef Z
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+} // namespace
+
+#ifdef _MSC_VER
+// Turn off fast floating-point optimizations
+#pragma float_control( pop )
+#pragma warning (pop)
+#endif
diff --git a/dep/src/g3dlite/Color1.cpp b/dep/src/g3dlite/Color1.cpp
new file mode 100644
index 00000000000..04f3f9412b1
--- /dev/null
+++ b/dep/src/g3dlite/Color1.cpp
@@ -0,0 +1,58 @@
+/**
+ @file Color1.cpp
+
+ Color class.
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-30
+ @edited 2009-03-27
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Color1.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Color3.h"
+
+namespace G3D {
+
+const Color1& Color1::one() {
+ static const Color1 x(1.0f);
+ return x;
+}
+
+
+const Color1& Color1::zero() {
+ const static Color1 x(0.0f);
+ return x;
+}
+
+
+Color1::Color1(BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+Color3 Color1::rgb() const {
+ return Color3(value, value, value);
+}
+
+
+void Color1::deserialize(BinaryInput& bi) {
+ value = bi.readFloat32();
+}
+
+
+void Color1::serialize(BinaryOutput& bo) const {
+ bo.writeFloat32(value);
+}
+
+
+Color1::Color1(const class Color1uint8& other) {
+ value = other.value / 255.0f;
+}
+
+} // namespace G3D
+
diff --git a/dep/src/g3dlite/Color1uint8.cpp b/dep/src/g3dlite/Color1uint8.cpp
new file mode 100644
index 00000000000..21cd564ba92
--- /dev/null
+++ b/dep/src/g3dlite/Color1uint8.cpp
@@ -0,0 +1,38 @@
+/**
+ @file Color1uint8.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-30
+ @edited 2007-01-30
+ */
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/Color1.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+Color1uint8::Color1uint8(const class Color1& c) : value(iClamp(iFloor(c.value * 256), 0, 255)) {
+}
+
+
+Color1uint8::Color1uint8(class BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Color1uint8::serialize(class BinaryOutput& bo) const {
+ bo.writeUInt8(value);
+}
+
+
+void Color1uint8::deserialize(class BinaryInput& bi) {
+ value = bi.readUInt8();
+}
+
+
+}
diff --git a/dep/src/g3dlite/Color3.cpp b/dep/src/g3dlite/Color3.cpp
new file mode 100644
index 00000000000..deb0bd87ee7
--- /dev/null
+++ b/dep/src/g3dlite/Color3.cpp
@@ -0,0 +1,384 @@
+/**
+ @file Color3.cpp
+
+ Color class.
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-06-02
+ @edited 2010-01-28
+ */
+
+#include "G3D/platform.h"
+#include <stdlib.h>
+#include "G3D/Color3.h"
+#include "G3D/Vector3.h"
+#include "G3D/format.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Color3uint8.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+Color3::Color3(const Any& any) {
+ *this = Color3::zero();
+ any.verifyName("Color3");
+ std::string name = toLower(any.name());
+
+ switch (any.type()) {
+ case Any::TABLE:
+
+ for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
+ const std::string& key = toLower(it->key);
+ if (key == "r") {
+ r = it->value;
+ } else if (key == "g") {
+ g = it->value;
+ } else if (key == "b") {
+ b = it->value;
+ } else {
+ any.verify(false, "Illegal key: " + it->key);
+ }
+ }
+ break;
+
+ case Any::ARRAY:
+ if (name == "color3") {
+ any.verifySize(3);
+ r = any[0];
+ g = any[1];
+ b = any[2];
+ } else if (name == "color3::one") {
+ any.verifySize(0);
+ *this = one();
+ } else if (name == "color3::zero") {
+ any.verifySize(0);
+ *this = zero();
+ } else if (name == "color3::fromargb") {
+ *this = Color3::fromARGB((int)any[0].number());
+ } else {
+ any.verify(false, "Expected Color3 constructor");
+ }
+ break;
+
+ default:
+ any.verify(false, "Bad Color3 constructor");
+ }
+}
+
+
+Color3::operator Any() const {
+ Any a(Any::ARRAY, "Color3");
+ a.append(r, g, b);
+ return a;
+}
+
+
+Color3 Color3::ansiMap(uint32 i) {
+ static const Color3 map[] =
+ {Color3::black(), Color3::red() * 0.75f, Color3::green() * 0.75f, Color3::yellow() * 0.75f,
+ Color3::blue() * 0.75f, Color3::purple() * 0.75f, Color3::cyan() * 0.75f, Color3::white() * 0.75f,
+ Color3::white() * 0.90f, Color3::red(), Color3::green(), Color3::yellow(), Color3::blue(),
+ Color3::purple(), Color3::cyan(), Color3::white()};
+
+ return map[i & 15];
+}
+
+
+Color3 Color3::pastelMap(uint32 i) {
+ uint32 x = Crypto::crc32(&i, sizeof(uint32));
+ // Create fairly bright, saturated colors
+ Vector3 v(((x >> 22) & 1023) / 1023.0f,
+ (((x >> 11) & 2047) / 2047.0f) * 0.5f + 0.25f,
+ ((x & 2047) / 2047.0f) * 0.75f + 0.25f);
+ return Color3::fromHSV(v);
+}
+
+
+const Color3& Color3::red() {
+ static Color3 c(1.0f, 0.0f, 0.0f);
+ return c;
+}
+
+
+const Color3& Color3::green() {
+ static Color3 c(0.0f, 1.0f, 0.0f);
+ return c;
+}
+
+
+const Color3& Color3::blue() {
+ static Color3 c(0.0f, 0.0f, 1.0f);
+ return c;
+}
+
+
+const Color3& Color3::purple() {
+ static Color3 c(0.7f, 0.0f, 1.0f);
+ return c;
+}
+
+
+const Color3& Color3::cyan() {
+ static Color3 c(0.0f, 0.7f, 1.0f);
+ return c;
+}
+
+
+const Color3& Color3::yellow() {
+ static Color3 c(1.0f, 1.0f, 0.0f);
+ return c;
+}
+
+
+const Color3& Color3::brown() {
+ static Color3 c(0.5f, 0.5f, 0.0f);
+ return c;
+}
+
+
+const Color3& Color3::orange() {
+ static Color3 c(1.0f, 0.5f, 0.0f);
+ return c;
+}
+
+
+const Color3& Color3::black() {
+ static Color3 c(0.0f, 0.0f, 0.0f);
+ return c;
+}
+
+const Color3& Color3::zero() {
+ static Color3 c(0.0f, 0.0f, 0.0f);
+ return c;
+}
+
+
+const Color3& Color3::one() {
+ static Color3 c(1.0f, 1.0f, 1.0f);
+ return c;
+}
+
+
+const Color3& Color3::gray() {
+ static Color3 c(0.7f, 0.7f, 0.7f);
+ return c;
+}
+
+
+const Color3& Color3::white() {
+ static Color3 c(1, 1, 1);
+ return c;
+}
+
+
+bool Color3::isFinite() const {
+ return G3D::isFinite(r) && G3D::isFinite(g) && G3D::isFinite(b);
+}
+
+
+Color3::Color3(BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Color3::deserialize(BinaryInput& bi) {
+ r = bi.readFloat32();
+ g = bi.readFloat32();
+ b = bi.readFloat32();
+}
+
+
+void Color3::serialize(BinaryOutput& bo) const {
+ bo.writeFloat32(r);
+ bo.writeFloat32(g);
+ bo.writeFloat32(b);
+}
+
+
+const Color3& Color3::wheelRandom() {
+ static const Color3 colorArray[8] =
+ {Color3::blue(), Color3::red(), Color3::green(),
+ Color3::orange(), Color3::yellow(),
+ Color3::cyan(), Color3::purple(), Color3::brown()};
+
+ return colorArray[iRandom(0, 7)];
+}
+
+
+size_t Color3::hashCode() const {
+ unsigned int rhash = (*(int*)(void*)(&r));
+ unsigned int ghash = (*(int*)(void*)(&g));
+ unsigned int bhash = (*(int*)(void*)(&b));
+
+ return rhash + (ghash * 37) + (bhash * 101);
+}
+
+
+Color3::Color3(const Vector3& v) {
+ r = v.x;
+ g = v.y;
+ b = v.z;
+}
+
+
+Color3::Color3(const class Color3uint8& other) {
+ r = other.r / 255.0f;
+ g = other.g / 255.0f;
+ b = other.b / 255.0f;
+}
+
+
+Color3 Color3::fromARGB(uint32 x) {
+ return Color3((float)((x >> 16) & 0xFF), (float)((x >> 8) & 0xFF), (float)(x & 0xFF)) / 255.0f;
+}
+
+//----------------------------------------------------------------------------
+
+
+Color3 Color3::random() {
+ return Color3(uniformRandom(),
+ uniformRandom(),
+ uniformRandom()).direction();
+}
+
+//----------------------------------------------------------------------------
+Color3& Color3::operator/= (float fScalar) {
+ if (fScalar != 0.0f) {
+ float fInvScalar = 1.0f / fScalar;
+ r *= fInvScalar;
+ g *= fInvScalar;
+ b *= fInvScalar;
+ } else {
+ r = (float)G3D::finf();
+ g = (float)G3D::finf();
+ b = (float)G3D::finf();
+ }
+
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+float Color3::unitize (float fTolerance) {
+ float fLength = length();
+
+ if ( fLength > fTolerance ) {
+ float fInvLength = 1.0f / fLength;
+ r *= fInvLength;
+ g *= fInvLength;
+ b *= fInvLength;
+ } else {
+ fLength = 0.0f;
+ }
+
+ return fLength;
+}
+
+//----------------------------------------------------------------------------
+Color3 Color3::fromHSV(const Vector3& _hsv) {
+ debugAssertM((_hsv.x <= 1.0f && _hsv.x >= 0.0f)
+ && (_hsv.y <= 1.0f && _hsv.y >= 0.0f)
+ && ( _hsv.z <= 1.0f && _hsv.z >= 0.0f), "H,S,V must be between [0,1]");
+ const int i = iMin(5, G3D::iFloor(6.0 * _hsv.x));
+ const float f = 6.0f * _hsv.x - i;
+ const float m = _hsv.z * (1.0f - (_hsv.y));
+ const float n = _hsv.z * (1.0f - (_hsv.y * f));
+ const float k = _hsv.z * (1.0f - (_hsv.y * (1 - f)));
+ switch(i) {
+ case 0:
+ return Color3(_hsv.z, k, m);
+
+ case 1:
+ return Color3(n, _hsv.z, m);
+
+ case 2:
+ return Color3(m, _hsv.z, k);
+
+ case 3:
+ return Color3(m, n, _hsv.z);
+
+ case 4:
+ return Color3(k, m, _hsv.z);
+
+ case 5:
+ return Color3(_hsv.z, m, n);
+
+ default:
+ debugAssertM(false, "fell through switch..");
+ }
+ return Color3::black();
+}
+
+
+Vector3 Color3::toHSV(const Color3& _rgb) {
+ debugAssertM((_rgb.r <= 1.0f && _rgb.r >= 0.0f)
+ && (_rgb.g <= 1.0f && _rgb.g >= 0.0f)
+ && (_rgb.b <= 1.0f && _rgb.b >= 0.0f), "R,G,B must be between [0,1]");
+ Vector3 hsv = Vector3::zero();
+ hsv.z = G3D::max(G3D::max(_rgb.r, _rgb.g), _rgb.b);
+ if (G3D::fuzzyEq(hsv.z, 0.0f)) {
+ return hsv;
+ }
+
+ const float x = G3D::min(G3D::min(_rgb.r, _rgb.g), _rgb.b);
+ hsv.y = (hsv.z - x) / hsv.z;
+
+ if (G3D::fuzzyEq(hsv.y, 0.0f)) {
+ return hsv;
+ }
+
+ Vector3 rgbN;
+ rgbN.x = (hsv.z - _rgb.r) / (hsv.z - x);
+ rgbN.y = (hsv.z - _rgb.g) / (hsv.z - x);
+ rgbN.z = (hsv.z - _rgb.b) / (hsv.z - x);
+
+ if (_rgb.r == hsv.z) { // note from the max we know that it exactly equals one of the three.
+ hsv.x = (_rgb.g == x)? 5.0f + rgbN.z : 1.0f - rgbN.y;
+ } else if (_rgb.g == hsv.z) {
+ hsv.x = (_rgb.b == x)? 1.0f + rgbN.x : 3.0f - rgbN.z;
+ } else {
+ hsv.x = (_rgb.r == x)? 3.0f + rgbN.y : 5.0f - rgbN.x;
+ }
+
+ hsv.x /= 6.0f;
+
+ return hsv;
+}
+
+Color3 Color3::jetColorMap(const float& val) {
+ debugAssertM(val <= 1.0f && val >= 0.0f , "value should be in [0,1]");
+
+ //truncated triangles where sides have slope 4
+ Color3 jet;
+
+ jet.r = G3D::min(4.0f * val - 1.5f,-4.0f * val + 4.5f) ;
+ jet.g = G3D::min(4.0f * val - 0.5f,-4.0f * val + 3.5f) ;
+ jet.b = G3D::min(4.0f * val + 0.5f,-4.0f * val + 2.5f) ;
+
+
+ jet.r = G3D::clamp(jet.r, 0.0f, 1.0f);
+ jet.g = G3D::clamp(jet.g, 0.0f, 1.0f);
+ jet.b = G3D::clamp(jet.b, 0.0f, 1.0f);
+
+ return jet;
+}
+
+
+
+
+
+std::string Color3::toString() const {
+ return G3D::format("(%g, %g, %g)", r, g, b);
+}
+
+//----------------------------------------------------------------------------
+
+Color3 Color3::rainbowColorMap(float hue) {
+ return fromHSV(Vector3(hue, 1.0f, 1.0f));
+}
+
+
+}; // namespace
+
diff --git a/dep/src/g3dlite/Color3uint8.cpp b/dep/src/g3dlite/Color3uint8.cpp
new file mode 100644
index 00000000000..a744710c752
--- /dev/null
+++ b/dep/src/g3dlite/Color3uint8.cpp
@@ -0,0 +1,45 @@
+/**
+ @file Color3uint8.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-04-07
+ @edited 2006-01-07
+ */
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Color3uint8.h"
+#include "G3D/Color3.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+Color3uint8::Color3uint8(const class Color3& c) {
+ r = iMin(255, iFloor(c.r * 256));
+ g = iMin(255, iFloor(c.g * 256));
+ b = iMin(255, iFloor(c.b * 256));
+}
+
+
+Color3uint8::Color3uint8(class BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Color3uint8::serialize(class BinaryOutput& bo) const {
+ bo.writeUInt8(r);
+ bo.writeUInt8(g);
+ bo.writeUInt8(b);
+}
+
+
+void Color3uint8::deserialize(class BinaryInput& bi) {
+ r = bi.readUInt8();
+ g = bi.readUInt8();
+ b = bi.readUInt8();
+}
+
+
+}
diff --git a/dep/src/g3dlite/Color4.cpp b/dep/src/g3dlite/Color4.cpp
new file mode 100644
index 00000000000..eab09eb9c7e
--- /dev/null
+++ b/dep/src/g3dlite/Color4.cpp
@@ -0,0 +1,192 @@
+/**
+ @file Color4.cpp
+
+ Color class.
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Portions by Laura Wollstadt, graphics3d.com
+ @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
+
+
+ @created 2002-06-25
+ @edited 2009-11-10
+ */
+
+#include <stdlib.h>
+#include "G3D/Color4.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/Vector4.h"
+#include "G3D/format.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+Color4::Color4(const Any& any) {
+ *this = Color4::zero();
+ any.verifyName("Color4");
+
+ if (any.type() == Any::TABLE) {
+ for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
+ const std::string& key = toLower(it->key);
+ if (key == "r") {
+ r = it->value;
+ } else if (key == "g") {
+ g = it->value;
+ } else if (key == "b") {
+ b = it->value;
+ } else if (key == "a") {
+ a = it->value;
+ } else {
+ any.verify(false, "Illegal key: " + it->key);
+ }
+ }
+ } else if (toLower(any.name()) == "color4") {
+ r = any[0];
+ g = any[1];
+ b = any[2];
+ a = any[3];
+ } else {
+ any.verifyName("Color4::fromARGB");
+ *this = Color4::fromARGB((int)any[0].number());
+ }
+}
+
+
+Color4::operator Any() const {
+ Any any(Any::ARRAY, "Color4");
+ any.append(r, g, b, a);
+ return any;
+}
+
+
+const Color4& Color4::one() {
+ const static Color4 x(1.0f, 1.0f, 1.0f, 1.0f);
+ return x;
+}
+
+
+const Color4& Color4::zero() {
+ static Color4 c(0.0f, 0.0f, 0.0f, 0.0f);
+ return c;
+}
+
+
+const Color4& Color4::inf() {
+ static Color4 c((float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf());
+ return c;
+}
+
+
+const Color4& Color4::nan() {
+ static Color4 c((float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan());
+ return c;
+}
+
+
+const Color4& Color4::clear() {
+ return Color4::zero();
+}
+
+
+Color4::Color4(const Vector4& v) {
+ r = v.x;
+ g = v.y;
+ b = v.z;
+ a = v.w;
+}
+
+
+Color4::Color4(const Color4uint8& c) : r(c.r), g(c.g), b(c.b), a(c.a) {
+ *this /= 255.0f;
+}
+
+size_t Color4::hashCode() const {
+ unsigned int rhash = (*(int*)(void*)(&r));
+ unsigned int ghash = (*(int*)(void*)(&g));
+ unsigned int bhash = (*(int*)(void*)(&b));
+ unsigned int ahash = (*(int*)(void*)(&a));
+
+ return rhash + (ghash * 37) + (bhash * 101) + (ahash * 241);
+}
+
+Color4 Color4::fromARGB(uint32 x) {
+ return Color4(
+ (float)((x >> 16) & 0xFF),
+ (float)((x >> 8) & 0xFF),
+ (float)(x & 0xFF),
+ (float)((x >> 24) & 0xFF)) / 255.0;
+}
+
+
+Color4::Color4(BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Color4::deserialize(BinaryInput& bi) {
+ r = bi.readFloat32();
+ g = bi.readFloat32();
+ b = bi.readFloat32();
+ a = bi.readFloat32();
+}
+
+
+void Color4::serialize(BinaryOutput& bo) const {
+ bo.writeFloat32(r);
+ bo.writeFloat32(g);
+ bo.writeFloat32(b);
+ bo.writeFloat32(a);
+}
+
+
+//----------------------------------------------------------------------------
+
+Color4 Color4::operator/ (float fScalar) const {
+ Color4 kQuot;
+
+ if (fScalar != 0.0f) {
+ float fInvScalar = 1.0f / fScalar;
+ kQuot.r = fInvScalar * r;
+ kQuot.g = fInvScalar * g;
+ kQuot.b = fInvScalar * b;
+ kQuot.a = fInvScalar * a;
+ return kQuot;
+
+ } else {
+
+ return Color4::inf();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+Color4& Color4::operator/= (float fScalar) {
+ if (fScalar != 0.0f) {
+ float fInvScalar = 1.0f / fScalar;
+ r *= fInvScalar;
+ g *= fInvScalar;
+ b *= fInvScalar;
+ a *= fInvScalar;
+ } else {
+ r = (float)G3D::finf();
+ g = (float)G3D::finf();
+ b = (float)G3D::finf();
+ a = (float)G3D::finf();
+ }
+
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+
+std::string Color4::toString() const {
+ return G3D::format("(%g, %g, %g, %g)", r, g, b, a);
+}
+
+//----------------------------------------------------------------------------
+
+}; // namespace
+
diff --git a/dep/src/g3dlite/Color4uint8.cpp b/dep/src/g3dlite/Color4uint8.cpp
new file mode 100644
index 00000000000..5cc3a578aca
--- /dev/null
+++ b/dep/src/g3dlite/Color4uint8.cpp
@@ -0,0 +1,47 @@
+/**
+ @file Color4uint8.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-04-07
+ @edited 2006-01-07
+ */
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/Color4.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+Color4uint8::Color4uint8(const class Color4& c) {
+ r = iMin(255, iFloor(c.r * 256));
+ g = iMin(255, iFloor(c.g * 256));
+ b = iMin(255, iFloor(c.b * 256));
+ a = iMin(255, iFloor(c.a * 256));
+}
+
+
+Color4uint8::Color4uint8(class BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Color4uint8::serialize(class BinaryOutput& bo) const {
+ bo.writeUInt8(r);
+ bo.writeUInt8(g);
+ bo.writeUInt8(b);
+ bo.writeUInt8(a);
+}
+
+
+void Color4uint8::deserialize(class BinaryInput& bi) {
+ r = bi.readUInt8();
+ g = bi.readUInt8();
+ b = bi.readUInt8();
+ a = bi.readUInt8();
+}
+
+
+}
diff --git a/dep/src/g3dlite/Cone.cpp b/dep/src/g3dlite/Cone.cpp
new file mode 100644
index 00000000000..3104b8424a7
--- /dev/null
+++ b/dep/src/g3dlite/Cone.cpp
@@ -0,0 +1,79 @@
+/**
+ @file Cone.cpp
+
+ Cone class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-07-09
+ @edited 2006-01-29
+*/
+
+#include "G3D/platform.h"
+#include "G3D/Cone.h"
+#include "G3D/Line.h"
+#include "G3D/Sphere.h"
+#include "G3D/Box.h"
+
+namespace G3D {
+
+Cone::Cone(const Vector3 &tip, const Vector3 &direction, float angle) {
+ this->tip = tip;
+ this->direction = direction.direction();
+ this->angle = angle;
+
+ debugAssert(angle >= 0);
+ debugAssert(angle <= pi());
+}
+
+/**
+ Forms the smallest cone that contains the box. Undefined if
+ the tip is inside or on the box.
+ */
+Cone::Cone(const Vector3& tip, const Box& box) {
+ this->tip = tip;
+ this->direction = (box.center() - tip).direction();
+
+ // Find the biggest angle
+ float smallestDotProduct = direction.dot((box.corner(0) - tip).direction());
+
+ for (int i = 1; i < 8; ++i) {
+ float dp = direction.dot((box.corner(i) - tip).direction());
+
+ debugAssert(dp > 0);
+
+ if (dp < smallestDotProduct) {
+ smallestDotProduct = dp;
+ }
+ }
+
+ angle = acosf(smallestDotProduct);
+}
+
+
+bool Cone::intersects(const Sphere& b) const {
+ // If the bounding sphere contains the tip, then
+ // they definitely touch.
+ if (b.contains(this->tip)) {
+ return true;
+ }
+
+ // Move the tip backwards, effectively making the cone bigger
+ // to account for the radius of the sphere.
+
+ Vector3 tip = this->tip - direction * b.radius / sinf(angle);
+
+ return Cone(tip, direction, angle).contains(b.center);
+}
+
+
+bool Cone::contains(const Vector3& v) const {
+
+ Vector3 d = (v - tip).direction();
+
+ float x = d.dot(direction);
+
+ return (x > 0) && (x >= cosf(angle));
+}
+
+}; // namespace
diff --git a/dep/src/g3dlite/ConvexPolyhedron.cpp b/dep/src/g3dlite/ConvexPolyhedron.cpp
new file mode 100644
index 00000000000..5fa76e3ed41
--- /dev/null
+++ b/dep/src/g3dlite/ConvexPolyhedron.cpp
@@ -0,0 +1,457 @@
+/**
+ @file ConvexPolyhedron.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-11-11
+ @edited 2009-08-10
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/platform.h"
+#include "G3D/ConvexPolyhedron.h"
+#include "G3D/debug.h"
+
+namespace G3D {
+
+ConvexPolygon::ConvexPolygon(const Array<Vector3>& __vertex) : _vertex(__vertex) {
+ // Intentionally empty
+}
+
+
+ConvexPolygon::ConvexPolygon(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
+ _vertex.append(v0, v1, v2);
+}
+
+
+bool ConvexPolygon::isEmpty() const {
+ return (_vertex.length() == 0) || (getArea() <= fuzzyEpsilon);
+}
+
+
+float ConvexPolygon::getArea() const {
+
+ if (_vertex.length() < 3) {
+ return 0;
+ }
+
+ float sum = 0;
+
+ int length = _vertex.length();
+ // Split into triangle fan, compute individual area
+ for (int v = 2; v < length; v++) {
+ int i0 = 0;
+ int i1 = v - 1;
+ int i2 = v;
+
+ sum += (_vertex[i1] - _vertex[i0]).cross(_vertex[i2] - _vertex[i0]).magnitude() / 2;
+ }
+
+ return sum;
+}
+
+void ConvexPolygon::cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below) {
+ DirectedEdge edge;
+ cut(plane, above, below, edge);
+}
+
+void ConvexPolygon::cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below, DirectedEdge &newEdge) {
+ above._vertex.resize(0);
+ below._vertex.resize(0);
+
+ if (isEmpty()) {
+ //debugPrintf("Empty\n");
+ return;
+ }
+
+ int v = 0;
+ int length = _vertex.length();
+
+
+ Vector3 polyNormal = normal();
+ Vector3 planeNormal= plane.normal();
+
+ // See if the polygon is *in* the plane.
+ if (planeNormal.fuzzyEq(polyNormal) || planeNormal.fuzzyEq(-polyNormal)) {
+ // Polygon is parallel to the plane. It must be either above,
+ // below, or in the plane.
+
+ double a, b, c, d;
+ Vector3 pt = _vertex[0];
+
+ plane.getEquation(a,b,c,d);
+ float r = (float)(a * pt.x + b * pt.y + c * pt.z + d);
+
+ if (fuzzyGe(r, 0)) {
+ // The polygon is entirely in the plane.
+ //debugPrintf("Entirely above\n");
+ above = *this;
+ return;
+ } else {
+ //debugPrintf("Entirely below (1)\n");
+ below = *this;
+ return;
+ }
+ }
+
+
+ // Number of edges crossing the plane. Used for
+ // debug assertions.
+ int count = 0;
+
+ // True when the last _vertex we looked at was above the plane
+ bool lastAbove = plane.halfSpaceContains(_vertex[v]);
+
+ if (lastAbove) {
+ above._vertex.append(_vertex[v]);
+ } else {
+ below._vertex.append(_vertex[v]);
+ }
+
+ for (v = 1; v < length; v++) {
+ bool isAbove = plane.halfSpaceContains(_vertex[v]);
+
+ if (lastAbove ^ isAbove) {
+ // Switched sides.
+ // Create an interpolated point that lies
+ // in the plane, between the two points.
+ Line line = Line::fromTwoPoints(_vertex[v - 1], _vertex[v]);
+ Vector3 interp = line.intersection(plane);
+
+ if (! interp.isFinite()) {
+
+ // Since the polygon is not in the plane (we checked above),
+ // it must be the case that this edge (and only this edge)
+ // is in the plane. This only happens when the polygon is
+ // entirely below the plane except for one edge. This edge
+ // forms a degenerate polygon, so just treat the whole polygon
+ // as below the plane.
+ below = *this;
+ above._vertex.resize(0);
+ //debugPrintf("Entirely below\n");
+ return;
+ }
+
+ above._vertex.append(interp);
+ below._vertex.append(interp);
+ if (lastAbove) {
+ newEdge.stop = interp;
+ } else {
+ newEdge.start = interp;
+ }
+ count++;
+ }
+
+ lastAbove = isAbove;
+ if (lastAbove) {
+ above._vertex.append(_vertex[v]);
+ } else {
+ below._vertex.append(_vertex[v]);
+ }
+ }
+
+ // Loop back to the first point, seeing if an interpolated point is
+ // needed.
+ bool isAbove = plane.halfSpaceContains(_vertex[0]);
+ if (lastAbove ^ isAbove) {
+ Line line = Line::fromTwoPoints(_vertex[length - 1], _vertex[0]);
+ Vector3 interp = line.intersection(plane);
+ if (! interp.isFinite()) {
+ // Since the polygon is not in the plane (we checked above),
+ // it must be the case that this edge (and only this edge)
+ // is in the plane. This only happens when the polygon is
+ // entirely below the plane except for one edge. This edge
+ // forms a degenerate polygon, so just treat the whole polygon
+ // as below the plane.
+ below = *this;
+ above._vertex.resize(0);
+ //debugPrintf("Entirely below\n");
+ return;
+ }
+
+ above._vertex.append(interp);
+ below._vertex.append(interp);
+ debugAssertM(count < 2, "Convex polygons may only intersect planes at two edges.");
+ if (lastAbove) {
+ newEdge.stop = interp;
+ } else {
+ newEdge.start = interp;
+ }
+ ++count;
+ }
+
+ debugAssertM((count == 2) || (count == 0), "Convex polygons may only intersect planes at two edges.");
+}
+
+
+ConvexPolygon ConvexPolygon::inverse() const {
+ ConvexPolygon result;
+ int length = _vertex.length();
+ result._vertex.resize(length);
+
+ for (int v = 0; v < length; v++) {
+ result._vertex[v] = _vertex[length - v - 1];
+ }
+
+ return result;
+}
+
+
+void ConvexPolygon::removeDuplicateVertices(){
+ // Any valid polygon should have 3 or more vertices, but why take chances?
+ if (_vertex.size() >= 2){
+
+ // Remove duplicate vertices.
+ for (int i=0;i<_vertex.size()-1;++i){
+ if (_vertex[i].fuzzyEq(_vertex[i+1])){
+ _vertex.remove(i+1);
+ --i; // Don't move forward.
+ }
+ }
+
+ // Check the last vertex against the first.
+ if (_vertex[_vertex.size()-1].fuzzyEq(_vertex[0])){
+ _vertex.pop();
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+ConvexPolyhedron::ConvexPolyhedron(const Array<ConvexPolygon>& _face) : face(_face) {
+ // Intentionally empty
+}
+
+
+float ConvexPolyhedron::getVolume() const {
+
+ if (face.length() < 4) {
+ return 0;
+ }
+
+ // The volume of any pyramid is 1/3 * h * base area.
+ // Discussion at: http://nrich.maths.org/mathsf/journalf/oct01/art1/
+
+ float sum = 0;
+
+ // Choose the first _vertex of the first face as the origin.
+ // This lets us skip one face, too, and avoids negative heights.
+ Vector3 v0 = face[0]._vertex[0];
+ for (int f = 1; f < face.length(); f++) {
+ const ConvexPolygon& poly = face[f];
+
+ float height = (poly._vertex[0] - v0).dot(poly.normal());
+ float base = poly.getArea();
+
+ sum += height * base;
+ }
+
+ return sum / 3;
+}
+
+bool ConvexPolyhedron::isEmpty() const {
+ return (face.length() == 0) || (getVolume() <= fuzzyEpsilon);
+}
+
+void ConvexPolyhedron::cut(const Plane& plane, ConvexPolyhedron &above, ConvexPolyhedron &below) {
+ above.face.resize(0);
+ below.face.resize(0);
+
+ Array<DirectedEdge> edge;
+
+ int f;
+
+ // See if the plane cuts this polyhedron at all. Detect when
+ // the polyhedron is entirely to one side or the other.
+ //{
+ int numAbove = 0, numIn = 0, numBelow = 0;
+ bool ruledOut = false;
+ double d;
+ Vector3 abc;
+ plane.getEquation(abc, d);
+
+ // This number has to be fairly large to prevent precision problems down
+ // the road.
+ const float eps = 0.005f;
+ for (f = face.length() - 1; (f >= 0) && (!ruledOut); f--) {
+ const ConvexPolygon& poly = face[f];
+ for (int v = poly._vertex.length() - 1; (v >= 0) && (!ruledOut); v--) {
+ double r = abc.dot(poly._vertex[v]) + d;
+ if (r > eps) {
+ numAbove++;
+ } else if (r < -eps) {
+ numBelow++;
+ } else {
+ numIn++;
+ }
+
+ ruledOut = (numAbove != 0) && (numBelow !=0);
+ }
+ }
+
+ if (numBelow == 0) {
+ above = *this;
+ return;
+ } else if (numAbove == 0) {
+ below = *this;
+ return;
+ }
+ //}
+
+ // Clip each polygon, collecting split edges.
+ for (f = face.length() - 1; f >= 0; f--) {
+ ConvexPolygon a, b;
+ DirectedEdge e;
+ face[f].cut(plane, a, b, e);
+
+ bool aEmpty = a.isEmpty();
+ bool bEmpty = b.isEmpty();
+
+ //debugPrintf("\n");
+ if (! aEmpty) {
+ //debugPrintf(" Above %f\n", a.getArea());
+ above.face.append(a);
+ }
+
+ if (! bEmpty) {
+ //debugPrintf(" Below %f\n", b.getArea());
+ below.face.append(b);
+ }
+
+ if (! aEmpty && ! bEmpty) {
+ //debugPrintf(" == Split\n");
+ edge.append(e);
+ } else {
+ // Might be the case that the polygon is entirely on
+ // one side of the plane yet there is an edge we need
+ // because it touches the plane.
+ //
+ // Extract the non-empty _vertex list and examine it.
+ // If we find exactly one edge in the plane, add that edge.
+ const Array<Vector3>& _vertex = (aEmpty ? b._vertex : a._vertex);
+ int L = _vertex.length();
+ int count = 0;
+ for (int v = 0; v < L; v++) {
+ if (plane.fuzzyContains(_vertex[v]) && plane.fuzzyContains(_vertex[(v + 1) % L])) {
+ e.start = _vertex[v];
+ e.stop = _vertex[(v + 1) % L];
+ count++;
+ }
+ }
+
+ if (count == 1) {
+ edge.append(e);
+ }
+ }
+ }
+
+ if (above.face.length() == 1) {
+ // Only one face above means that this entire
+ // polyhedron is below the plane. Move that face over.
+ below.face.append(above.face[0]);
+ above.face.resize(0);
+ } else if (below.face.length() == 1) {
+ // This shouldn't happen, but it arises in practice
+ // from numerical imprecision.
+ above.face.append(below.face[0]);
+ below.face.resize(0);
+ }
+
+ if ((above.face.length() > 0) && (below.face.length() > 0)) {
+ // The polyhedron was actually cut; create a cap polygon
+ ConvexPolygon cap;
+
+ // Collect the final polgyon by sorting the edges
+ int numVertices = edge.length();
+/*debugPrintf("\n");
+for (int xx=0; xx < numVertices; xx++) {
+ std::string s1 = edge[xx].start.toString();
+ std::string s2 = edge[xx].stop.toString();
+ debugPrintf("%s -> %s\n", s1.c_str(), s2.c_str());
+}
+*/
+
+ // Need at least three points to make a polygon
+ debugAssert(numVertices >= 3);
+
+ Vector3 last_vertex = edge.last().stop;
+ cap._vertex.append(last_vertex);
+
+ // Search for the next _vertex. Because of accumulating
+ // numerical error, we have to find the closest match, not
+ // just the one we expect.
+ for (int v = numVertices - 1; v >= 0; v--) {
+ // matching edge index
+ int index = 0;
+ int num = edge.length();
+ double distance = (edge[index].start - last_vertex).squaredMagnitude();
+ for (int e = 1; e < num; e++) {
+ double d = (edge[e].start - last_vertex).squaredMagnitude();
+
+ if (d < distance) {
+ // This is the new closest one
+ index = e;
+ distance = d;
+ }
+ }
+
+ // Don't tolerate ridiculous error.
+ debugAssertM(distance < 0.02, "Edge missing while closing polygon.");
+
+ last_vertex = edge[index].stop;
+ cap._vertex.append(last_vertex);
+ }
+
+ //debugPrintf("\n");
+ //debugPrintf("Cap (both) %f\n", cap.getArea());
+ above.face.append(cap);
+ below.face.append(cap.inverse());
+ }
+
+ // Make sure we put enough faces on each polyhedra
+ debugAssert((above.face.length() == 0) || (above.face.length() >= 4));
+ debugAssert((below.face.length() == 0) || (below.face.length() >= 4));
+}
+
+///////////////////////////////////////////////
+
+ConvexPolygon2D::ConvexPolygon2D(const Array<Vector2>& pts, bool reverse) : m_vertex(pts) {
+ if (reverse) {
+ m_vertex.reverse();
+ }
+}
+
+
+bool ConvexPolygon2D::contains(const Vector2& p, bool reverse) const {
+ // Compute the signed area of each polygon from p to an edge.
+ // If the area is non-negative for all polygons then p is inside
+ // the polygon. (To adapt this algorithm for a concave polygon,
+ // the *sum* of the areas must be non-negative).
+
+ float r = reverse ? -1 : 1;
+
+ for (int i0 = 0; i0 < m_vertex.size(); ++i0) {
+ int i1 = (i0 + 1) % m_vertex.size();
+ const Vector2& v0 = m_vertex[i0];
+ const Vector2& v1 = m_vertex[i1];
+
+ Vector2 e0 = v0 - p;
+ Vector2 e1 = v1 - p;
+
+ // Area = (1/2) cross product, negated to be ccw in
+ // a 2D space; we neglect the 1/2
+ float area = -(e0.x * e1.y - e0.y * e1.x);
+
+ if (area * r < 0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+}
+
diff --git a/dep/src/g3dlite/CoordinateFrame.cpp b/dep/src/g3dlite/CoordinateFrame.cpp
new file mode 100644
index 00000000000..9b639b62082
--- /dev/null
+++ b/dep/src/g3dlite/CoordinateFrame.cpp
@@ -0,0 +1,436 @@
+/**
+ @file CoordinateFrame.cpp
+
+ Coordinate frame class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-06-02
+ @edited 2009-11-13
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+*/
+
+#include "G3D/platform.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Quat.h"
+#include "G3D/Matrix4.h"
+#include "G3D/Box.h"
+#include "G3D/AABox.h"
+#include "G3D/Sphere.h"
+#include "G3D/Triangle.h"
+#include "G3D/Ray.h"
+#include "G3D/Capsule.h"
+#include "G3D/Cylinder.h"
+#include "G3D/UprightFrame.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+CoordinateFrame::CoordinateFrame(const Any& any) {
+ any.verifyName("CFrame");
+ if (toUpper(any.name()) == "CFRAME") {
+ any.verifyType(Any::TABLE, Any::ARRAY);
+ if (any.type() == Any::TABLE) {
+ rotation = any["rotation"];
+ translation = any["translation"];
+ } else {
+ any.verifySize(2);
+ rotation = any[0];
+ translation = any[1];
+ }
+ } else {
+ any.verifyName("CFrame::fromXYZYPRDegrees");
+ any.verifyType(Any::ARRAY);
+ any.verifySize(3, 6);
+
+ int s = any.size();
+
+ *this = fromXYZYPRDegrees(any[0], any[1], any[2],
+ (s > 3) ? any[3].number() : 0.0f,
+ (s > 4) ? any[4].number() : 0.0f,
+ (s > 5) ? any[5].number() : 0.0f);
+ }
+}
+
+
+CoordinateFrame::operator Any() const {
+ float x, y, z, yaw, pitch, roll;
+ getXYZYPRDegrees(x, y, z, yaw, pitch, roll);
+ Any a(Any::ARRAY, "CFrame::fromXYZYPRDegrees");
+ a.append(x, y, z, yaw);
+ if ( ! G3D::fuzzyEq(yaw, 0.0f) || ! G3D::fuzzyEq(pitch, 0.0f) || ! G3D::fuzzyEq(roll, 0.0f)) {
+ a.append(yaw);
+ if (! G3D::fuzzyEq(pitch, 0.0f) || ! G3D::fuzzyEq(roll, 0.0f)) {
+ a.append(pitch);
+ if (! G3D::fuzzyEq(roll, 0.0f)) {
+ a.append(roll);
+ }
+ }
+ }
+ return a;
+}
+
+
+CoordinateFrame::CoordinateFrame(const class UprightFrame& f) {
+ *this = f.toCoordinateFrame();
+}
+
+
+CoordinateFrame::CoordinateFrame() :
+ rotation(Matrix3::identity()), translation(Vector3::zero()) {
+}
+
+CoordinateFrame CoordinateFrame::fromXYZYPRRadians(float x, float y, float z, float yaw,
+ float pitch, float roll) {
+ Matrix3 rotation = Matrix3::fromAxisAngle(Vector3::unitY(), yaw);
+
+ rotation = Matrix3::fromAxisAngle(rotation.column(0), pitch) * rotation;
+ rotation = Matrix3::fromAxisAngle(rotation.column(2), roll) * rotation;
+
+ const Vector3 translation(x, y, z);
+
+ return CoordinateFrame(rotation, translation);
+}
+
+
+void CoordinateFrame::getXYZYPRRadians(float& x, float& y, float& z,
+ float& yaw, float& pitch, float& roll) const {
+ x = translation.x;
+ y = translation.y;
+ z = translation.z;
+
+ const Vector3& look = lookVector();
+
+ if (abs(look.y) > 0.99f) {
+ // Looking nearly straight up or down
+
+ yaw = G3D::pi() + atan2(look.x, look.z);
+ pitch = asin(look.y);
+ roll = 0.0f;
+
+ } else {
+
+ // Yaw cannot be affected by others, so pull it first
+ yaw = G3D::pi() + atan2(look.x, look.z);
+
+ // Pitch is the elevation of the yaw vector
+ pitch = asin(look.y);
+
+ Vector3 actualRight = rightVector();
+ Vector3 expectedRight = look.cross(Vector3::unitY());
+
+ roll = 0;//acos(actualRight.dot(expectedRight)); TODO
+ }
+}
+
+
+void CoordinateFrame::getXYZYPRDegrees(float& x, float& y, float& z,
+ float& yaw, float& pitch, float& roll) const {
+ getXYZYPRRadians(x, y, z, yaw, pitch, roll);
+ yaw = toDegrees(yaw);
+ pitch = toDegrees(pitch);
+ roll = toDegrees(roll);
+}
+
+
+CoordinateFrame CoordinateFrame::fromXYZYPRDegrees(float x, float y, float z,
+ float yaw, float pitch, float roll) {
+ return fromXYZYPRRadians(x, y, z, toRadians(yaw), toRadians(pitch), toRadians(roll));
+}
+
+
+Ray CoordinateFrame::lookRay() const {
+ return Ray::fromOriginAndDirection(translation, lookVector());
+}
+
+
+bool CoordinateFrame::fuzzyEq(const CoordinateFrame& other) const {
+
+ for (int c = 0; c < 3; ++c) {
+ for (int r = 0; r < 3; ++r) {
+ if (! G3D::fuzzyEq(other.rotation[r][c], rotation[r][c])) {
+ return false;
+ }
+ }
+ if (! G3D::fuzzyEq(translation[c], other.translation[c])) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool CoordinateFrame::fuzzyIsIdentity() const {
+ const Matrix3& I = Matrix3::identity();
+
+ for (int c = 0; c < 3; ++c) {
+ for (int r = 0; r < 3; ++r) {
+ if (fuzzyNe(I[r][c], rotation[r][c])) {
+ return false;
+ }
+ }
+ if (fuzzyNe(translation[c], 0)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool CoordinateFrame::isIdentity() const {
+ return
+ (translation == Vector3::zero()) &&
+ (rotation == Matrix3::identity());
+}
+
+
+Matrix4 CoordinateFrame::toMatrix4() const {
+ return Matrix4(*this);
+}
+
+
+std::string CoordinateFrame::toXML() const {
+ return G3D::format(
+ "<COORDINATEFRAME>\n %lf,%lf,%lf,%lf,\n %lf,%lf,%lf,%lf,\n %lf,%lf,%lf,%lf,\n %lf,%lf,%lf,%lf\n</COORDINATEFRAME>\n",
+ rotation[0][0], rotation[0][1], rotation[0][2], translation.x,
+ rotation[1][0], rotation[1][1], rotation[1][2], translation.y,
+ rotation[2][0], rotation[2][1], rotation[2][2], translation.z,
+ 0.0, 0.0, 0.0, 1.0);
+}
+
+
+Plane CoordinateFrame::toObjectSpace(const Plane& p) const {
+ Vector3 N, P;
+ double d;
+ p.getEquation(N, d);
+ P = N * (float)d;
+ P = pointToObjectSpace(P);
+ N = normalToObjectSpace(N);
+ return Plane(N, P);
+}
+
+
+Plane CoordinateFrame::toWorldSpace(const Plane& p) const {
+ Vector3 N, P;
+ double d;
+ p.getEquation(N, d);
+ P = N * (float)d;
+ P = pointToWorldSpace(P);
+ N = normalToWorldSpace(N);
+ return Plane(N, P);
+}
+
+
+Triangle CoordinateFrame::toObjectSpace(const Triangle& t) const {
+ return Triangle(pointToObjectSpace(t.vertex(0)),
+ pointToObjectSpace(t.vertex(1)),
+ pointToObjectSpace(t.vertex(2)));
+}
+
+
+Triangle CoordinateFrame::toWorldSpace(const Triangle& t) const {
+ return Triangle(pointToWorldSpace(t.vertex(0)),
+ pointToWorldSpace(t.vertex(1)),
+ pointToWorldSpace(t.vertex(2)));
+}
+
+
+Cylinder CoordinateFrame::toWorldSpace(const Cylinder& c) const {
+ return Cylinder(
+ pointToWorldSpace(c.point(0)),
+ pointToWorldSpace(c.point(1)),
+ c.radius());
+}
+
+
+Capsule CoordinateFrame::toWorldSpace(const Capsule& c) const {
+ return Capsule(
+ pointToWorldSpace(c.point(0)),
+ pointToWorldSpace(c.point(1)),
+ c.radius());
+}
+
+
+Box CoordinateFrame::toWorldSpace(const AABox& b) const {
+ Box b2(b);
+ return toWorldSpace(b2);
+}
+
+
+Box CoordinateFrame::toWorldSpace(const Box& b) const {
+ Box out(b);
+
+ for (int i = 0; i < 8; ++i) {
+ out._corner[i] = pointToWorldSpace(b._corner[i]);
+ debugAssert(! isNaN(out._corner[i].x));
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ out._axis[i] = vectorToWorldSpace(b._axis[i]);
+ }
+
+ out._center = pointToWorldSpace(b._center);
+
+ return out;
+}
+
+
+Box CoordinateFrame::toObjectSpace(const Box &b) const {
+ return inverse().toWorldSpace(b);
+}
+
+
+Box CoordinateFrame::toObjectSpace(const AABox& b) const {
+ return toObjectSpace(Box(b));
+}
+
+
+CoordinateFrame::CoordinateFrame(class BinaryInput& b) : rotation(Matrix3::zero()) {
+ deserialize(b);
+}
+
+
+void CoordinateFrame::deserialize(class BinaryInput& b) {
+ rotation.deserialize(b);
+ translation.deserialize(b);
+}
+
+
+void CoordinateFrame::serialize(class BinaryOutput& b) const {
+ rotation.serialize(b);
+ translation.serialize(b);
+}
+
+
+Sphere CoordinateFrame::toWorldSpace(const Sphere &b) const {
+ return Sphere(pointToWorldSpace(b.center), b.radius);
+}
+
+
+Sphere CoordinateFrame::toObjectSpace(const Sphere &b) const {
+ return Sphere(pointToObjectSpace(b.center), b.radius);
+}
+
+
+Ray CoordinateFrame::toWorldSpace(const Ray& r) const {
+ return Ray::fromOriginAndDirection(pointToWorldSpace(r.origin()), vectorToWorldSpace(r.direction()));
+}
+
+
+Ray CoordinateFrame::toObjectSpace(const Ray& r) const {
+ return Ray::fromOriginAndDirection(pointToObjectSpace(r.origin()), vectorToObjectSpace(r.direction()));
+}
+
+
+void CoordinateFrame::lookAt(const Vector3 &target) {
+ lookAt(target, Vector3::unitY());
+}
+
+
+void CoordinateFrame::lookAt(
+ const Vector3& target,
+ Vector3 up) {
+
+ up = up.direction();
+
+ Vector3 look = (target - translation).direction();
+ if (fabs(look.dot(up)) > .99f) {
+ up = Vector3::unitX();
+ if (fabs(look.dot(up)) > .99f) {
+ up = Vector3::unitY();
+ }
+ }
+
+ up -= look * look.dot(up);
+ up.unitize();
+
+ Vector3 z = -look;
+ Vector3 x = -z.cross(up);
+ x.unitize();
+
+ Vector3 y = z.cross(x);
+
+ rotation.setColumn(0, x);
+ rotation.setColumn(1, y);
+ rotation.setColumn(2, z);
+}
+
+
+CoordinateFrame CoordinateFrame::lerp(
+ const CoordinateFrame& other,
+ float alpha) const {
+
+ if (alpha == 1.0f) {
+ return other;
+ } else if (alpha == 0.0f) {
+ return *this;
+ } else {
+ Quat q1 = Quat(this->rotation);
+ Quat q2 = Quat(other.rotation);
+
+ return CoordinateFrame(
+ q1.slerp(q2, alpha).toRotationMatrix(),
+ this->translation * (1 - alpha) + other.translation * alpha);
+ }
+}
+
+
+void CoordinateFrame::pointToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
+ vout.resize(v.size());
+
+ for (int i = v.size() - 1; i >= 0; --i) {
+ vout[i] = pointToWorldSpace(v[i]);
+ }
+}
+
+
+void CoordinateFrame::normalToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
+ vout.resize(v.size());
+
+ for (int i = v.size() - 1; i >= 0; --i) {
+ vout[i] = normalToWorldSpace(v[i]);
+ }
+}
+
+
+void CoordinateFrame::vectorToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
+ vout.resize(v.size());
+
+ for (int i = v.size() - 1; i >= 0; --i) {
+ vout[i] = vectorToWorldSpace(v[i]);
+ }
+}
+
+
+void CoordinateFrame::pointToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
+ vout.resize(v.size());
+
+ for (int i = v.size() - 1; i >= 0; --i) {
+ vout[i] = pointToObjectSpace(v[i]);
+ }
+}
+
+
+void CoordinateFrame::normalToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
+ vout.resize(v.size());
+
+ for (int i = v.size() - 1; i >= 0; --i) {
+ vout[i] = normalToObjectSpace(v[i]);
+ }
+}
+
+
+void CoordinateFrame::vectorToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
+ vout.resize(v.size());
+
+ for (int i = v.size() - 1; i >= 0; --i) {
+ vout[i] = vectorToObjectSpace(v[i]);
+ }
+}
+
+} // namespace
diff --git a/dep/src/g3dlite/Crypto.cpp b/dep/src/g3dlite/Crypto.cpp
index 03851193e57..c69b23375ce 100644
--- a/dep/src/g3dlite/Crypto.cpp
+++ b/dep/src/g3dlite/Crypto.cpp
@@ -1,7 +1,8 @@
/**
@file Crypto.cpp
- @author Morgan McGuire, matrix@graphics3d.com
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2006-03-28
@edited 2006-04-06
@@ -10,8 +11,10 @@
#include "G3D/platform.h"
#include "G3D/Crypto.h"
#include "G3D/g3dmath.h"
+#include <zlib.h>
namespace G3D {
+
int Crypto::smallPrime(int n) {
debugAssert(n < numSmallPrimes() && n >= 0);
@@ -20,125 +23,48 @@ int Crypto::smallPrime(int n) {
// http://primes.utm.edu/lists/small/1000.txt
static const int table[] = {
- 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
- 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
- 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
- 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
- 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
- 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
- 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
- 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
- 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
- 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
- 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
- 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
- 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
- 739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
- 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
- 877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
- 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
- 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
- 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
- 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
- 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
- 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
- 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
- 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
- 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
- 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
- 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
+ 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
+ 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
+ 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
+ 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
+ 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
+ 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
+ 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
+ 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
+ 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
+ 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
+ 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
+ 739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
+ 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
+ 877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
+ 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
+ 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
+ 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
+ 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
+ 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
+ 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
+ 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
+ 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
+ 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
+ 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
+ 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
- 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,
- 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
+ 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,
+ 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
1993, 1997, 1999};
return table[n];
}
+
int Crypto::numSmallPrimes() {
return 303;
}
uint32 Crypto::crc32(const void* byte, size_t numBytes) {
- static const uint32 crc32Table[256] = {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
- 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
- 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
- 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
- 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
- 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
- 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
- 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
- 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
-
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
- 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
- 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
- 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
- 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
- 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
- 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
- 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
- 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
-
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
- 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
- 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
- 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
- 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
- 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
- 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
- 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
- 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
-
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
- 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
- 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
- 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
- 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
- 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
- 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
- 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
- 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
- };
-
- // By definition, initialize to all binary 1's
- uint32 value = 0xFFFFFFFF;
-
- for (size_t i = 0; i < numBytes; ++i) {
- value = (value >> 8 ) ^ crc32Table[static_cast<const uint8*>(byte)[i] ^ (value & 0xFF)];
- }
-
- return value;
+ return ::crc32(::crc32(0, Z_NULL, 0), static_cast<const Bytef *>(byte), numBytes);
}
} // G3D
-
diff --git a/dep/src/g3dlite/Crypto_md5.cpp b/dep/src/g3dlite/Crypto_md5.cpp
new file mode 100644
index 00000000000..c7ee535d61e
--- /dev/null
+++ b/dep/src/g3dlite/Crypto_md5.cpp
@@ -0,0 +1,471 @@
+/**
+ @file Crypto_md5.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ Copyright 2006-2007, Morgan McGuire. All rights reserved.
+
+ @created 2006-03-28
+ @edited 2006-04-06
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Crypto.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+#include <cstring>
+
+namespace G3D {
+
+
+MD5Hash::MD5Hash(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void MD5Hash::deserialize(class BinaryInput& b) {
+ b.readBytes(value, 16);
+}
+
+
+void MD5Hash::serialize(class BinaryOutput& b) const {
+ b.writeBytes(value, 16);
+}
+
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+static void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+static void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+#ifdef __cplusplus
+}
+#endif
+
+
+
+MD5Hash Crypto::md5(const void* data, size_t n) {
+ md5_state_t state;
+ md5_init(&state);
+ md5_append(&state, (const uint8*)data, (int)n);
+
+ MD5Hash h;
+ md5_finish(&state, &(h[0]));
+ return h;
+}
+
+/*
+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
+
+ 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.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+ either statically or dynamically; added missing #include <string.h>
+ in library.
+ 2002-03-11 lpd Corrected argument list for main(), and added int return
+ type, in test program and T value program.
+ 2002-02-21 lpd Added missing #include <stdio.h> in test program.
+ 2000-07-03 lpd Patched to eliminate warnings about "constant is
+ unsigned in ANSI C, signed in traditional"; made test program
+ self-checking.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+
+#if defined(G3D_LINUX) || defined(G3D_OSX)
+# if defined(G3D_OSX_PPC)
+# include <ppc/endian.h>
+# elif defined(G3D_OSX_INTEL)
+# include <i386/endian.h>
+# elif defined(__linux__)
+# include <endian.h>
+# elif defined(__FreeBSD__)
+# include <sys/endian.h>
+# endif
+#else
+# define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+#if BYTE_ORDER > 0
+ /* Define storage only for big-endian CPUs. */
+ md5_word_t X[16];
+#else
+ /* Define storage for little-endian or both types of CPUs. */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+#endif
+
+ {
+#if BYTE_ORDER == 0
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+#endif
+#if BYTE_ORDER == 0
+ else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+ {
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const md5_byte_t *xp = data;
+ int i;
+
+# if BYTE_ORDER == 0
+ X = xbuf; /* (dynamic only) */
+# else
+# define xbuf X /* (static only) */
+# endif
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+ }
+#endif
+ }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+ const md5_byte_t *p = data;
+ int left = nbytes;
+ int offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += nbytes >> 29;
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 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
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
+
+}
diff --git a/dep/src/g3dlite/Cylinder.cpp b/dep/src/g3dlite/Cylinder.cpp
new file mode 100644
index 00000000000..7a7b9f9440d
--- /dev/null
+++ b/dep/src/g3dlite/Cylinder.cpp
@@ -0,0 +1,176 @@
+/**
+ @file Cylinder.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-02-07
+ @edited 2006-02-18
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Cylinder.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/LineSegment.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Line.h"
+#include "G3D/AABox.h"
+
+namespace G3D {
+
+Cylinder::Cylinder(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+Cylinder::Cylinder() {
+}
+
+
+Cylinder::Cylinder(const Vector3& _p1, const Vector3& _p2, float _r)
+ : p1(_p1), p2(_p2), mRadius(_r) {
+}
+
+
+void Cylinder::serialize(class BinaryOutput& b) const {
+ p1.serialize(b);
+ p2.serialize(b);
+ b.writeFloat64(mRadius);
+}
+
+
+void Cylinder::deserialize(class BinaryInput& b) {
+ p1.deserialize(b);
+ p2.deserialize(b);
+ mRadius = b.readFloat64();
+}
+
+
+Line Cylinder::axis() const {
+ return Line::fromTwoPoints(p1, p2);
+}
+
+
+
+float Cylinder::radius() const {
+ return mRadius;
+}
+
+
+float Cylinder::volume() const {
+ return
+ (float)pi() * square(mRadius) * (p1 - p2).magnitude();
+}
+
+
+float Cylinder::area() const {
+ return
+ // Sides
+ (twoPi() * mRadius) * height() +
+
+ // Caps
+ twoPi() * square(mRadius);
+}
+
+void Cylinder::getBounds(AABox& out) const {
+ Vector3 min = p1.min(p2) - (Vector3(1, 1, 1) * mRadius);
+ Vector3 max = p1.max(p2) + (Vector3(1, 1, 1) * mRadius);
+ out = AABox(min, max);
+}
+
+bool Cylinder::contains(const Vector3& p) const {
+ return LineSegment::fromTwoPoints(p1, p2).distanceSquared(p) <= square(mRadius);
+}
+
+
+void Cylinder::getReferenceFrame(CoordinateFrame& cframe) const {
+ cframe.translation = center();
+
+ Vector3 Y = (p1 - p2).direction();
+ Vector3 X = (abs(Y.dot(Vector3::unitX())) > 0.9) ? Vector3::unitY() : Vector3::unitX();
+ Vector3 Z = X.cross(Y).direction();
+ X = Y.cross(Z);
+ cframe.rotation.setColumn(0, X);
+ cframe.rotation.setColumn(1, Y);
+ cframe.rotation.setColumn(2, Z);
+}
+
+
+void Cylinder::getRandomSurfacePoint(Vector3& p, Vector3& N) const {
+ float h = height();
+ float r = radius();
+
+ // Create a random point on a standard cylinder and then rotate to the global frame.
+
+ // Relative areas (factor of 2PI already taken out)
+ float capRelArea = square(r) / 2.0f;
+ float sideRelArea = r * h;
+
+ float r1 = uniformRandom(0, capRelArea * 2 + sideRelArea);
+
+ if (r1 < capRelArea * 2) {
+
+ // Select a point uniformly at random on a disk
+ // @cite http://mathworld.wolfram.com/DiskPointPicking.html
+ float a = uniformRandom(0, (float)twoPi());
+ float r2 = sqrt(uniformRandom(0, 1)) * r;
+ p.x = cos(a) * r2;
+ p.z = sin(a) * r2;
+
+ N.x = 0;
+ N.z = 0;
+ if (r1 < capRelArea) {
+ // Top
+ p.y = h / 2.0f;
+ N.y = 1;
+ } else {
+ // Bottom
+ p.y = -h / 2.0f;
+ N.y = -1;
+ }
+ } else {
+ // Side
+ float a = uniformRandom(0, (float)twoPi());
+ N.x = cos(a);
+ N.y = 0;
+ N.z = sin(a);
+ p.x = N.x * r;
+ p.z = N.y * r;
+ p.y = uniformRandom(-h / 2.0f, h / 2.0f);
+ }
+
+ // Transform to world space
+ CoordinateFrame cframe;
+ getReferenceFrame(cframe);
+
+ p = cframe.pointToWorldSpace(p);
+ N = cframe.normalToWorldSpace(N);
+}
+
+
+Vector3 Cylinder::randomInteriorPoint() const {
+ float h = height();
+ float r = radius();
+
+ // Create a random point in a standard cylinder and then rotate to the global frame.
+
+ // Select a point uniformly at random on a disk
+ // @cite http://mathworld.wolfram.com/DiskPointPicking.html
+ float a = uniformRandom(0, (float)twoPi());
+ float r2 = sqrt(uniformRandom(0, 1)) * r;
+
+ Vector3 p( cos(a) * r2,
+ uniformRandom(-h / 2.0f, h / 2.0f),
+ sin(a) * r2);
+
+ // Transform to world space
+ CoordinateFrame cframe;
+ getReferenceFrame(cframe);
+
+ return cframe.pointToWorldSpace(p);
+}
+
+} // namespace
diff --git a/dep/src/g3dlite/GCamera.cpp b/dep/src/g3dlite/GCamera.cpp
new file mode 100644
index 00000000000..64b0c94543e
--- /dev/null
+++ b/dep/src/g3dlite/GCamera.cpp
@@ -0,0 +1,502 @@
+/**
+ @file GCamera.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @author Jeff Marsceill, 08jcm@williams.edu
+
+ @created 2005-07-20
+ @edited 2009-11-24
+*/
+#include "G3D/GCamera.h"
+#include "G3D/platform.h"
+#include "G3D/Rect2D.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Ray.h"
+#include "G3D/Matrix4.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+GCamera::GCamera(const Any& any) {
+ any.verifyName("GCamera");
+ any.verifyType(Any::TABLE);
+ *this = GCamera();
+
+ const Any::AnyTable& table = any.table();
+ Any::AnyTable::Iterator it = table.begin();
+ while (it.hasMore()) {
+ const std::string& k = toUpper(it->key);
+ if (k == "FOVDIRECTION") {
+ const std::string& v = toUpper(it->value);
+ if (v == "HORIZONTAL") {
+ m_direction = HORIZONTAL;
+ } else if (v == "VERTICAL") {
+ m_direction = VERTICAL;
+ } else {
+ any.verify(false, "fovDirection must be \"HORIZONTAL\" or \"VERTICAL\"");
+ }
+ } else if (k == "COORDINATEFRAME") {
+ m_cframe = it->value;
+ } else if (k == "FOVDEGREES") {
+ m_fieldOfView = toRadians(it->value.number());
+ } else if (k == "NEARPLANEZ") {
+ m_nearPlaneZ = it->value;
+ } else if (k == "FARPLANEZ") {
+ m_farPlaneZ = it->value;
+ } else {
+ any.verify(false, std::string("Illegal key in table: ") + it->key);
+ }
+ ++it;
+ }
+}
+
+
+GCamera::operator Any() const {
+ Any any(Any::TABLE, "GCamera");
+
+ any.set("fovDirection", std::string((m_direction == HORIZONTAL) ? "HORIZONTAL" : "VERTICAL"));
+ any.set("fovDegrees", toDegrees(m_fieldOfView));
+ any.set("nearPlaneZ", nearPlaneZ());
+ any.set("farPlaneZ", farPlaneZ());
+ any.set("coordinateFrame", coordinateFrame());
+
+ return any;
+}
+
+
+GCamera::GCamera() {
+ setNearPlaneZ(-0.2f);
+ setFarPlaneZ(-100.0f);
+ setFieldOfView((float)toRadians(90.0f), HORIZONTAL);
+}
+
+
+GCamera::GCamera(const Matrix4& proj, const CFrame& frame) {
+ float left, right, bottom, top, nearval, farval;
+ proj.getPerspectiveProjectionParameters(left, right, bottom, top, nearval, farval);
+ setNearPlaneZ(-nearval);
+ setFarPlaneZ(-farval);
+ float x = right;
+
+ // Assume horizontal field of view
+ setFieldOfView(atan2(x, -m_nearPlaneZ) * 2.0f, HORIZONTAL);
+ setCoordinateFrame(frame);
+}
+
+
+GCamera::~GCamera() {
+}
+
+
+void GCamera::getCoordinateFrame(CoordinateFrame& c) const {
+ c = m_cframe;
+}
+
+
+void GCamera::setCoordinateFrame(const CoordinateFrame& c) {
+ m_cframe = c;
+}
+
+
+void GCamera::setFieldOfView(float angle, FOVDirection dir) {
+ debugAssert((angle < pi()) && (angle > 0));
+
+ m_fieldOfView = angle;
+ m_direction = dir;
+}
+
+
+float GCamera::imagePlaneDepth() const{
+ return -m_nearPlaneZ;
+}
+
+float GCamera::viewportWidth(const Rect2D& viewport) const {
+ // Compute the side of a square at the near plane based on our field of view
+ float s = 2.0f * -m_nearPlaneZ * tan(m_fieldOfView * 0.5f);
+
+ if (m_direction == VERTICAL) {
+ s *= viewport.width() / viewport.height();
+ }
+
+ return s;
+}
+
+
+float GCamera::viewportHeight(const Rect2D& viewport) const {
+ // Compute the side of a square at the near plane based on our field of view
+ float s = 2.0f * -m_nearPlaneZ * tan(m_fieldOfView * 0.5f);
+
+ debugAssert(m_fieldOfView < toRadians(180));
+ if (m_direction == HORIZONTAL) {
+ s *= viewport.height() / viewport.width();
+ }
+
+ return s;
+}
+
+
+Ray GCamera::worldRay(float x, float y, const Rect2D& viewport) const {
+
+ int screenWidth = iFloor(viewport.width());
+ int screenHeight = iFloor(viewport.height());
+
+ Vector3 origin = m_cframe.translation;
+
+ float cx = screenWidth / 2.0f;
+ float cy = screenHeight / 2.0f;
+
+ float vw = viewportWidth(viewport);
+ float vh = viewportHeight(viewport);
+
+ Vector3 direction = Vector3( (x - cx) * vw / screenWidth,
+ -(y - cy) * vh / screenHeight,
+ m_nearPlaneZ);
+
+ direction = m_cframe.vectorToWorldSpace(direction);
+
+ // Normalize the direction (we didn't do it before)
+ direction = direction.direction();
+
+ return Ray::fromOriginAndDirection(origin, direction);
+}
+
+
+void GCamera::getProjectPixelMatrix(const Rect2D& viewport, Matrix4& P) const {
+ getProjectUnitMatrix(viewport, P);
+ float screenWidth = viewport.width();
+ float screenHeight = viewport.height();
+
+ float sx = screenWidth / 2.0;
+ float sy = screenHeight / 2.0;
+
+ P = Matrix4(sx, 0, 0, sx + viewport.x0(),
+ 0, -sy, 0, sy + viewport.y0(),
+ 0, 0, 1, 0,
+ 0, 0, 0, 1) * P;
+}
+
+
+void GCamera::getProjectUnitMatrix(const Rect2D& viewport, Matrix4& P) const {
+
+ float screenWidth = viewport.width();
+ float screenHeight = viewport.height();
+
+ float r, l, t, b, n, f, x, y;
+
+ if (m_direction == VERTICAL) {
+ y = -m_nearPlaneZ * tan(m_fieldOfView / 2);
+ x = y * (screenWidth / screenHeight);
+ } else { //m_direction == HORIZONTAL
+ x = -m_nearPlaneZ * tan(m_fieldOfView / 2);
+ y = x * (screenHeight / screenWidth);
+ }
+
+ n = -m_nearPlaneZ;
+ f = -m_farPlaneZ;
+ r = x;
+ l = -x;
+ t = y;
+ b = -y;
+
+ P = Matrix4::perspectiveProjection(l, r, b, t, n, f);
+}
+
+Vector3 GCamera::projectUnit(const Vector3& point, const Rect2D& viewport) const {
+ Matrix4 M;
+ getProjectUnitMatrix(viewport, M);
+
+ Vector4 cameraSpacePoint(coordinateFrame().pointToObjectSpace(point), 1.0f);
+ const Vector4& screenSpacePoint = M * cameraSpacePoint;
+
+ return Vector3(screenSpacePoint.xyz() / screenSpacePoint.w);
+}
+
+Vector3 GCamera::project(const Vector3& point,
+ const Rect2D& viewport) const {
+
+ // Find the point in the homogeneous cube
+ const Vector3& cube = projectUnit(point, viewport);
+
+ return convertFromUnitToNormal(cube, viewport);
+}
+
+Vector3 GCamera::unprojectUnit(const Vector3& v, const Rect2D& viewport) const {
+
+ const Vector3& projectedPoint = convertFromUnitToNormal(v, viewport);
+
+ return unproject(projectedPoint, viewport);
+}
+
+
+Vector3 GCamera::unproject(const Vector3& v, const Rect2D& viewport) const {
+
+ const float n = m_nearPlaneZ;
+ const float f = m_farPlaneZ;
+
+ float z;
+
+ if (-f >= finf()) {
+ // Infinite far plane
+ z = 1.0f / (((-1.0f / n) * v.z) + 1.0f / n);
+ } else {
+ z = 1.0f / ((((1.0f / f) - (1.0f / n)) * v.z) + 1.0f / n);
+ }
+
+ const Ray& ray = worldRay(v.x, v.y, viewport);
+
+ // Find out where the ray reaches the specified depth.
+ const Vector3& out = ray.origin() + ray.direction() * -z / (ray.direction().dot(m_cframe.lookVector()));
+
+ return out;
+}
+
+
+float GCamera::worldToScreenSpaceArea(float area, float z, const Rect2D& viewport) const {
+ (void)viewport;
+ if (z >= 0) {
+ return finf();
+ }
+ return area * (float)square(imagePlaneDepth() / z);
+}
+
+
+void GCamera::getClipPlanes(
+ const Rect2D& viewport,
+ Array<Plane>& clip) const {
+
+ Frustum fr;
+ frustum(viewport, fr);
+ clip.resize(fr.faceArray.size(), DONT_SHRINK_UNDERLYING_ARRAY);
+ for (int f = 0; f < clip.size(); ++f) {
+ clip[f] = fr.faceArray[f].plane;
+ }
+}
+
+
+GCamera::Frustum GCamera::frustum(const Rect2D& viewport) const {
+ Frustum f;
+ frustum(viewport, f);
+ return f;
+}
+
+
+void GCamera::frustum(const Rect2D& viewport, Frustum& fr) const {
+
+ // The volume is the convex hull of the vertices definining the view
+ // frustum and the light source point at infinity.
+
+ const float x = viewportWidth(viewport) / 2;
+ const float y = viewportHeight(viewport) / 2;
+ const float zn = m_nearPlaneZ;
+ const float zf = m_farPlaneZ;
+ float xx, zz, yy;
+
+ float halfFOV = m_fieldOfView * 0.5f;
+
+ // This computes the normal, which is based on the complement of the
+ // halfFOV angle, so the equations are "backwards"
+ if (m_direction == VERTICAL) {
+ yy = -cosf(halfFOV);
+ xx = yy * viewport.height() / viewport.width();
+ zz = -sinf(halfFOV);
+ } else {
+ xx = -cosf(halfFOV);
+ yy = xx * viewport.width() / viewport.height();
+ zz = -sinf(halfFOV);
+ }
+
+ // Near face (ccw from UR)
+ fr.vertexPos.append(
+ Vector4( x, y, zn, 1),
+ Vector4(-x, y, zn, 1),
+ Vector4(-x, -y, zn, 1),
+ Vector4( x, -y, zn, 1));
+
+ // Far face (ccw from UR, from origin)
+ if (m_farPlaneZ == -finf()) {
+ fr.vertexPos.append(Vector4( x, y, zn, 0),
+ Vector4(-x, y, zn, 0),
+ Vector4(-x, -y, zn, 0),
+ Vector4( x, -y, zn, 0));
+ } else {
+ // Finite
+ const float s = zf / zn;
+ fr.vertexPos.append(Vector4( x * s, y * s, zf, 1),
+ Vector4(-x * s, y * s, zf, 1),
+ Vector4(-x * s, -y * s, zf, 1),
+ Vector4( x * s, -y * s, zf, 1));
+ }
+
+ Frustum::Face face;
+
+ // Near plane (wind backwards so normal faces into frustum)
+ // Recall that nearPlane, farPlane are positive numbers, so
+ // we need to negate them to produce actual z values.
+ face.plane = Plane(Vector3(0,0,-1), Vector3(0,0,m_nearPlaneZ));
+ face.vertexIndex[0] = 3;
+ face.vertexIndex[1] = 2;
+ face.vertexIndex[2] = 1;
+ face.vertexIndex[3] = 0;
+ fr.faceArray.append(face);
+
+ // Right plane
+ face.plane = Plane(Vector3(xx, 0, zz), Vector3::zero());
+ face.vertexIndex[0] = 0;
+ face.vertexIndex[1] = 4;
+ face.vertexIndex[2] = 7;
+ face.vertexIndex[3] = 3;
+ fr.faceArray.append(face);
+
+ // Left plane
+ face.plane = Plane(Vector3(-fr.faceArray.last().plane.normal().x, 0, fr.faceArray.last().plane.normal().z), Vector3::zero());
+ face.vertexIndex[0] = 5;
+ face.vertexIndex[1] = 1;
+ face.vertexIndex[2] = 2;
+ face.vertexIndex[3] = 6;
+ fr.faceArray.append(face);
+
+ // Top plane
+ face.plane = Plane(Vector3(0, yy, zz), Vector3::zero());
+ face.vertexIndex[0] = 1;
+ face.vertexIndex[1] = 5;
+ face.vertexIndex[2] = 4;
+ face.vertexIndex[3] = 0;
+ fr.faceArray.append(face);
+
+ // Bottom plane
+ face.plane = Plane(Vector3(0, -fr.faceArray.last().plane.normal().y, fr.faceArray.last().plane.normal().z), Vector3::zero());
+ face.vertexIndex[0] = 2;
+ face.vertexIndex[1] = 3;
+ face.vertexIndex[2] = 7;
+ face.vertexIndex[3] = 6;
+ fr.faceArray.append(face);
+
+ // Far plane
+ if (-m_farPlaneZ < finf()) {
+ face.plane = Plane(Vector3(0, 0, 1), Vector3(0, 0, m_farPlaneZ));
+ face.vertexIndex[0] = 4;
+ face.vertexIndex[1] = 5;
+ face.vertexIndex[2] = 6;
+ face.vertexIndex[3] = 7;
+ fr.faceArray.append(face);
+ }
+
+ // Transform vertices to world space
+ for (int v = 0; v < fr.vertexPos.size(); ++v) {
+ fr.vertexPos[v] = m_cframe.toWorldSpace(fr.vertexPos[v]);
+ }
+
+ // Transform planes to world space
+ for (int p = 0; p < fr.faceArray.size(); ++p) {
+ // Since there is no scale factor, we don't have to
+ // worry about the inverse transpose of the normal.
+ Vector3 normal;
+ float d;
+
+ fr.faceArray[p].plane.getEquation(normal, d);
+
+ Vector3 newNormal = m_cframe.rotation * normal;
+
+ if (isFinite(d)) {
+ d = (newNormal * -d + m_cframe.translation).dot(newNormal);
+ fr.faceArray[p].plane = Plane(newNormal, newNormal * d);
+ } else {
+ // When d is infinite, we can't multiply 0's by it without
+ // generating NaNs.
+ fr.faceArray[p].plane = Plane::fromEquation(newNormal.x, newNormal.y, newNormal.z, d);
+ }
+ }
+}
+
+void GCamera::getNearViewportCorners
+(const Rect2D& viewport,
+ Vector3& outUR,
+ Vector3& outUL,
+ Vector3& outLL,
+ Vector3& outLR) const {
+
+ // Must be kept in sync with getFrustum()
+ const float w = viewportWidth(viewport) / 2.0f;
+ const float h = viewportHeight(viewport) / 2.0f;
+ const float z = nearPlaneZ();
+
+ // Compute the points
+ outUR = Vector3( w, h, z);
+ outUL = Vector3(-w, h, z);
+ outLL = Vector3(-w, -h, z);
+ outLR = Vector3( w, -h, z);
+
+ // Take to world space
+ outUR = m_cframe.pointToWorldSpace(outUR);
+ outUL = m_cframe.pointToWorldSpace(outUL);
+ outLR = m_cframe.pointToWorldSpace(outLR);
+ outLL = m_cframe.pointToWorldSpace(outLL);
+}
+
+void GCamera::getFarViewportCorners(
+ const Rect2D& viewport,
+ Vector3& outUR,
+ Vector3& outUL,
+ Vector3& outLL,
+ Vector3& outLR) const {
+
+ // Must be kept in sync with getFrustum()
+ const float w = viewportWidth(viewport) * m_farPlaneZ / m_nearPlaneZ;
+ const float h = viewportHeight(viewport) * m_farPlaneZ / m_nearPlaneZ;
+ const float z = m_farPlaneZ;
+
+ // Compute the points
+ outUR = Vector3( w/2, h/2, z);
+ outUL = Vector3(-w/2, h/2, z);
+ outLL = Vector3(-w/2, -h/2, z);
+ outLR = Vector3( w/2, -h/2, z);
+
+ // Take to world space
+ outUR = m_cframe.pointToWorldSpace(outUR);
+ outUL = m_cframe.pointToWorldSpace(outUL);
+ outLR = m_cframe.pointToWorldSpace(outLR);
+ outLL = m_cframe.pointToWorldSpace(outLL);
+}
+
+
+
+void GCamera::setPosition(const Vector3& t) {
+ m_cframe.translation = t;
+}
+
+
+void GCamera::lookAt(const Vector3& position, const Vector3& up) {
+ m_cframe.lookAt(position, up);
+}
+
+
+void GCamera::serialize(BinaryOutput& bo) const {
+ bo.writeFloat32(m_fieldOfView);
+ bo.writeFloat32(imagePlaneDepth());
+ debugAssert(nearPlaneZ() < 0.0f);
+ bo.writeFloat32(nearPlaneZ());
+ debugAssert(farPlaneZ() < 0.0f);
+ bo.writeFloat32(farPlaneZ());
+ m_cframe.serialize(bo);
+ bo.writeInt8(m_direction);
+}
+
+
+void GCamera::deserialize(BinaryInput& bi) {
+ m_fieldOfView = bi.readFloat32();
+ m_nearPlaneZ = bi.readFloat32();
+ debugAssert(m_nearPlaneZ < 0.0f);
+ m_farPlaneZ = bi.readFloat32();
+ debugAssert(m_farPlaneZ < 0.0f);
+ m_cframe.deserialize(bi);
+ m_direction = (FOVDirection)bi.readInt8();
+}
+
+
+Vector3 GCamera::convertFromUnitToNormal(const Vector3& in, const Rect2D& viewport) const{
+ return (in + Vector3(1,1,1)) * 0.5 * Vector3(viewport.width(), -viewport.height(), 1) +
+ Vector3(viewport.x0(), viewport.y1(), 0);
+}
+} // namespace
diff --git a/dep/src/g3dlite/GImage.cpp b/dep/src/g3dlite/GImage.cpp
new file mode 100644
index 00000000000..9527e96cf67
--- /dev/null
+++ b/dep/src/g3dlite/GImage.cpp
@@ -0,0 +1,1166 @@
+/**
+ \file GImage.cpp
+ \author Morgan McGuire, http://graphics.cs.williams.edu
+ Copyright 2002-2010, Morgan McGuire
+
+ \created 2002-05-27
+ \edited 2010-01-04
+ */
+#include "G3D/platform.h"
+#include "G3D/GImage.h"
+#include "G3D/debug.h"
+#include "G3D/stringutils.h"
+#include "G3D/TextInput.h"
+#include "G3D/TextOutput.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Log.h"
+#include "G3D/fileutils.h"
+
+#ifdef G3D_LINUX
+# include <png.h>
+#else
+# include "png.h"
+#endif
+
+#include <sys/stat.h>
+#include <assert.h>
+#include <sys/types.h>
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace G3D {
+
+void GImage::LtoRGBA(
+ const uint8* in,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = 0; i < numPixels; ++i) {
+ int v = in[i];
+ int i4 = i * 4;
+
+ out[i4 + 0] = v;
+ out[i4 + 1] = v;
+ out[i4 + 2] = v;
+ out[i4 + 3] = 255;
+ }
+}
+
+
+void GImage::LtoRGB(
+ const uint8* in,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = 0; i < numPixels; ++i) {
+ int v = in[i];
+ int i3 = i * 3;
+
+ out[i3 + 0] = v;
+ out[i3 + 1] = v;
+ out[i3 + 2] = v;
+ }
+}
+
+
+void GImage::RGBtoRGBA(
+ const uint8* in,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = 0; i < numPixels; ++i) {
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ out[i4 + 0] = in[i3 + 0];
+ out[i4 + 1] = in[i3 + 1];
+ out[i4 + 2] = in[i3 + 2];
+ out[i4 + 3] = 255;
+ }
+}
+
+
+void GImage::RGBAtoRGB(
+ const uint8* in,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = 0; i < numPixels; ++i) {
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ out[i3 + 0] = in[i4 + 0];
+ out[i3 + 1] = in[i4 + 1];
+ out[i3 + 2] = in[i4 + 2];
+ }
+}
+
+
+void GImage::RGBtoBGRA(
+ const uint8* in,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = 0; i < numPixels; ++i) {
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ out[i4 + 2] = in[i3 + 0];
+ out[i4 + 1] = in[i3 + 1];
+ out[i4 + 0] = in[i3 + 2];
+ out[i4 + 3] = 255;
+ }
+}
+
+
+
+void GImage::RGBtoBGR(
+ const uint8* in,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = 0; i < numPixels; ++i) {
+ int i3 = i * 3;
+
+ int r = in[i3 + 0];
+ int g = in[i3 + 1];
+ int b = in[i3 + 2];
+
+ out[i3 + 2] = r;
+ out[i3 + 1] = g;
+ out[i3 + 0] = b;
+ }
+}
+
+
+void GImage::RGBxRGBtoRGBA(
+ const uint8* colorRGB,
+ const uint8* alphaRGB,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = numPixels - 1; i >= 0; --i) {
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ out[i4 + 0] = colorRGB[i3 + 0];
+ out[i4 + 1] = colorRGB[i3 + 1];
+ out[i4 + 2] = colorRGB[i3 + 2];
+ out[i4 + 3] = alphaRGB[i3 + 0];
+ }
+}
+
+
+void GImage::RGBtoARGB(
+ const uint8* in,
+ uint8* out,
+ int numPixels) {
+
+ for (int i = 0; i < numPixels; ++i) {
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ out[i4 + 0] = 255;
+ out[i4 + 1] = in[i3 + 0];
+ out[i4 + 2] = in[i3 + 1];
+ out[i4 + 3] = in[i3 + 2];
+ }
+}
+
+
+void GImage::flipRGBVertical(
+ const uint8* in,
+ uint8* out,
+ int width,
+ int height) {
+
+
+ // Allocate a temp row so the operation
+ // is still safe if in == out
+ uint8* temp = (uint8*)System::malloc(width * 3);
+ alwaysAssertM(temp != NULL, "Out of memory");
+
+ int oneRow = width * 3;
+ int N = height / 2;
+
+ // if height is an odd value, don't swap odd middle row
+ for (int i = 0; i < N; ++i) {
+ int topOff = i * oneRow;
+ int botOff = (height - i - 1) * oneRow;
+ System::memcpy(temp, in + topOff, oneRow);
+ System::memcpy(out + topOff, in + botOff, oneRow);
+ System::memcpy(out + botOff, temp, oneRow);
+ }
+
+ System::free(temp);
+}
+
+
+void GImage::flipRGBAVertical(
+ const uint8* in,
+ uint8* out,
+ int width,
+ int height) {
+
+
+ // Allocate a temp row so the operation
+ // is still safe if in == out
+ uint8* temp = (uint8*)System::malloc(width * 4);
+ alwaysAssertM(temp != NULL, "Out of memory");
+
+ int oneRow = width * 4;
+
+ // if height is an odd value, don't swap odd middle row
+ for (int i = 0; i < height / 2; ++i) {
+ int topOff = i * oneRow;
+ int botOff = (height - i - 1) * oneRow;
+ System::memcpy(temp, in + topOff, oneRow);
+ System::memcpy(out + topOff, in + botOff, oneRow);
+ System::memcpy(out + botOff, temp, oneRow);
+ }
+
+ System::free(temp);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+void GImage::decode(
+ BinaryInput& input,
+ Format format) {
+
+ switch (format) {
+ case PPM_ASCII:
+ decodePPMASCII(input);
+ break;
+
+ case PPM_BINARY:
+ decodePPM(input);
+ break;
+
+ case PNG:
+ decodePNG(input);
+ break;
+
+ case JPEG:
+ decodeJPEG(input);
+ break;
+
+ case TGA:
+ decodeTGA(input);
+ break;
+
+ case BMP:
+ decodeBMP(input);
+ break;
+
+ case ICO:
+ decodeICO(input);
+ break;
+
+ case PCX:
+ decodePCX(input);
+ break;
+
+ default:
+ debugAssert(false);
+ }
+
+ debugAssert(m_width >= 0);
+ debugAssert(m_height >= 0);
+ debugAssert(m_channels == 1 || m_channels == 3 || m_channels == 4);
+ debugAssert(m_byte != NULL);
+}
+
+
+void GImage::decodePCX(
+ BinaryInput& input) {
+
+ uint8 manufacturer = input.readUInt8();
+ uint8 version = input.readUInt8();
+ uint8 encoding = input.readUInt8();
+ uint8 bitsPerPixel = input.readUInt8();
+
+ uint16 xmin = input.readUInt16();
+ uint16 ymin = input.readUInt16();
+ uint16 xmax = input.readUInt16();
+ uint16 ymax = input.readUInt16();
+
+ uint16 horizDPI = input.readUInt16();
+ uint16 vertDPI = input.readUInt16();
+
+ Color3uint8 colorMap[16];
+ input.readBytes(colorMap, 48);
+
+ input.skip(1);
+
+ uint8 planes = input.readUInt8();
+ uint16 bytesPerLine = input.readUInt16();
+ uint16 paletteType = input.readUInt16();
+ input.skip(4 + 54);
+
+ (void)bytesPerLine;
+
+ m_width = xmax - xmin + 1;
+ m_height = ymax - ymin + 1;
+ m_channels = 3;
+
+ if ((manufacturer != 0x0A) || (encoding != 0x01)) {
+ throw GImage::Error("PCX file is corrupted", input.getFilename());
+ }
+
+ (void)version;
+ (void)vertDPI;
+ (void)horizDPI;
+
+ if ((bitsPerPixel != 8) || ((planes != 1) && (planes != 3))) {
+ throw GImage::Error("Only 8-bit paletted and 24-bit PCX files supported.", input.getFilename());
+ }
+
+ // Prepare the pointer object for the pixel data
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * 3);
+
+ if ((paletteType == 1) && (planes == 3)) {
+
+ Color3uint8* pixel = pixel3();
+
+ // Iterate over each scan line
+ for (int row = 0; row < m_height; ++row) {
+ // Read each scan line once per plane
+ for (int plane = 0; plane < planes; ++plane) {
+ int p = row * m_width;
+ int p1 = p + m_width;
+ while (p < p1) {
+ uint8 value = input.readUInt8();
+ int length = 1;
+
+ if (value >= 192) {
+ // This is the length, not the value. Mask off
+ // the two high bits and read the true index.
+ length = value & 0x3F;
+ value = input.readUInt8();
+ }
+
+ // Set the whole run
+ for (int i = length - 1; i >= 0; --i, ++p) {
+ debugAssert(p < m_width * m_height);
+ pixel[p][plane] = value;
+ }
+ }
+ }
+ }
+
+ } else if (planes == 1) {
+
+ Color3uint8 palette[256];
+
+ int imageBeginning = input.getPosition();
+ int paletteBeginning = input.getLength() - 769;
+
+ input.setPosition(paletteBeginning);
+
+ uint8 dummy = input.readUInt8();
+
+ if (dummy != 12) {
+ Log::common()->println("\n*********************");
+ Log::common()->printf("Warning: Corrupted PCX file (palette marker byte was missing) \"%s\"\nLoading anyway\n\n", input.getFilename().c_str());
+ }
+
+ input.readBytes(palette, sizeof(palette));
+ input.setPosition(imageBeginning);
+
+ Color3uint8* pixel = pixel3();
+
+ // The palette indices are run length encoded.
+ int p = 0;
+ while (p < m_width * m_height) {
+ uint8 index = input.readUInt8();
+ uint8 length = 1;
+
+ if (index >= 192) {
+ // This is the length, not the index. Mask off
+ // the two high bits and read the true index.
+ length = index & 0x3F;
+ index = input.readUInt8();
+ }
+
+ Color3uint8 color = palette[index];
+
+ // Set the whole run
+ for (int i = length - 1; i >= 0; --i, ++p) {
+ if (p > m_width * m_height) {
+ break;
+ }
+ pixel[p] = color;
+ }
+
+ }
+
+ } else {
+ throw GImage::Error("Unsupported PCX file type.", input.getFilename());
+ }
+}
+
+
+GImage::Format GImage::resolveFormat(const std::string& filename) {
+ BinaryInput b(filename, G3D_LITTLE_ENDIAN);
+ if (b.size() <= 0) {
+ throw Error("File not found.", filename);
+ }
+
+ return resolveFormat(filename, b.getCArray(), b.size(), AUTODETECT);
+}
+
+
+GImage::Format GImage::resolveFormat(
+ const std::string& filename,
+ const uint8* data,
+ int dataLen,
+ Format maybeFormat) {
+
+ // Return the provided format if it is specified.
+ if (maybeFormat != AUTODETECT) {
+ return maybeFormat;
+ }
+
+ std::string extension = toUpper(filenameExt(filename));
+
+ if ((extension == "PPM") || (extension == "PGM") || (extension == "PBM")) {
+ // There are two PPM formats (binary and ASCII); we handle them differently
+ if (dataLen > 3) {
+ if (!memcmp(data, "P6", 2) || !memcmp(data, "P5", 2)) {
+ return PPM_BINARY;
+ } else {
+ return PPM_ASCII;
+ }
+ }
+ }
+
+ Format tmp = stringToFormat(extension);
+ if ((tmp != AUTODETECT) && (tmp != UNKNOWN)) {
+ return tmp;
+ }
+
+ // Try and autodetect from the file itself by looking at the first
+ // character.
+
+ // We can't look at the character if it is null.
+ debugAssert(data != NULL);
+
+ if ((dataLen > 3) && (! memcmp(data, "P3", 2) || (! memcmp(data, "P2", 2)) || (! memcmp(data, "P1", 2)))) {
+ return PPM_ASCII;
+ }
+
+ if ((dataLen > 3) && (!memcmp(data, "P6", 2) ||!memcmp(data, "P5", 2))) {
+ return PPM_BINARY;
+ }
+
+ if (dataLen > 8) {
+ if (!png_sig_cmp((png_bytep)data, 0, 8)) {
+ return PNG;
+ }
+ }
+
+ if ((dataLen > 0) && (data[0] == 'B')) {
+ return BMP;
+ }
+
+ if (dataLen > 10) {
+ if ((dataLen > 11) && (data[0] == 0xFF) &&
+ (memcmp(&data[6], "JFIF", 4) == 0)) {
+ return JPEG;
+ }
+ }
+
+ if (dataLen > 40) {
+ if (memcmp(&data[dataLen - 18], "TRUEVISION-XFILE", 16) == 0) {
+ return TGA;
+ }
+ }
+
+ if ((dataLen > 4) && (data[0] == 0) && (data[1] == 0) && (data[2] == 0) && (data[3] == 1)) {
+ return ICO;
+ }
+
+ if ((dataLen > 0) && (data[0] == 10)) {
+ return PCX;
+ }
+
+ return UNKNOWN;
+}
+
+
+GImage::GImage(
+ const std::string& filename,
+ Format format,
+ const MemoryManager::Ref& m) :
+ m_memMan(m),
+ m_byte(NULL),
+ m_channels(0),
+ m_width(0),
+ m_height(0) {
+
+ load(filename, format);
+}
+
+
+void GImage::load(
+ const std::string& filename,
+ Format format) {
+
+ clear();
+
+ try {
+ BinaryInput b(filename, G3D_LITTLE_ENDIAN);
+ if (b.size() <= 0) {
+ throw Error("File not found.", filename);
+ }
+
+ alwaysAssertM(this != NULL, "Corrupt GImage");
+ decode(b, resolveFormat(filename, b.getCArray(), b.size(), format));
+ } catch (const std::string& error) {
+ throw Error(error, filename);
+ }
+}
+
+
+GImage::GImage(
+ const uint8* data,
+ int length,
+ Format format,
+ const MemoryManager::Ref& m) :
+ m_memMan(m),
+ m_byte(NULL),
+ m_channels(0),
+ m_width(0),
+ m_height(0) {
+
+ BinaryInput b(data, length, G3D_LITTLE_ENDIAN);
+ // It is safe to cast away the const because we
+ // know we don't corrupt the data.
+
+ decode(b, resolveFormat("", data, length, format));
+}
+
+
+GImage::GImage(
+ int width,
+ int height,
+ int channels,
+ const MemoryManager::Ref& mem) :
+ m_memMan(mem),
+ m_byte(0),
+ m_channels(0),
+ m_width(0),
+ m_height(0) {
+
+ resize(width, height, channels);
+}
+
+
+void GImage::resize(
+ int width,
+ int height,
+ int channels,
+ bool zero) {
+
+ debugAssert(width >= 0);
+ debugAssert(height >= 0);
+ debugAssert(channels >= 1);
+
+ clear();
+
+ m_width = width;
+ m_height = height;
+ m_channels = channels;
+ size_t sz = width * height * channels;
+
+ if (sz > 0) {
+ m_byte = (uint8*)m_memMan->alloc(sz);
+ if (zero) {
+ System::memset(m_byte, 0, sz);
+ }
+ debugAssert(isValidHeapPointer(m_byte));
+ }
+}
+
+
+void GImage::_copy(
+ const GImage& other) {
+
+ clear();
+
+ m_width = other.m_width;
+ m_height = other.m_height;
+ m_channels = other.m_channels;
+ int s = m_width * m_height * m_channels * sizeof(uint8);
+ m_byte = (uint8*)m_memMan->alloc(s);
+ debugAssert(isValidHeapPointer(m_byte));
+ memcpy(m_byte, other.m_byte, s);
+}
+
+
+void GImage::flipHorizontal() {
+ uint8 temp[4];
+ int rowBytes = m_width * m_channels;
+ for (int y = 0; y < m_height; ++y) {
+ uint8* row = m_byte + y * rowBytes;
+ for (int x = 0; x < m_width / 2; ++x) {
+ System::memcpy(temp, row + x * m_channels, m_channels);
+ System::memcpy(row + x * m_channels, row + (m_width - x - 1) * m_channels, m_channels);
+ System::memcpy(row + (m_width - x - 1) * m_channels, temp, m_channels);
+ }
+ }
+}
+
+
+void GImage::flipVertical() {
+ uint8* old = m_byte;
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * m_channels);
+
+ // We could do this with only a single-row temp buffer, but then
+ // we'd have to copy twice as much data.
+ int rowBytes = m_width * m_channels;
+ for (int y = 0; y < m_height; ++y) {
+ System::memcpy(m_byte + y * rowBytes, old + (m_height - y - 1) * rowBytes, rowBytes);
+ }
+
+ m_memMan->free(old);
+}
+
+
+void GImage::rotate90CW(int numTimes) {
+
+ uint8* old = NULL;
+ numTimes = iWrap(numTimes, 4);
+ if (numTimes > 0) {
+ (uint8*)m_memMan->alloc(m_width * m_height * m_channels);
+ }
+ for (int j = 0; j < numTimes; ++j) {
+ {
+ uint8* temp = old;
+ uint8* old = m_byte;
+ m_byte = temp;
+ }
+
+ {
+ int temp = m_width;
+ m_width = m_height;
+ m_height = temp;
+ }
+
+ int rowBytes = m_width * m_channels;
+ for (int y = 0; y < m_height; ++y) {
+ for (int x = 0; x < m_width; ++x) {
+ uint8* dst = m_byte + x + y * rowBytes;
+ uint8* src = old + y + (m_height - x - 1) * rowBytes;
+ System::memcpy(dst, src, m_channels);
+ }
+ }
+ }
+ m_memMan->free(old);
+}
+
+
+
+GImage::GImage(
+ const GImage& other,
+ const MemoryManager::Ref& m) : m_memMan(m), m_byte(NULL) {
+
+ _copy(other);
+}
+
+
+GImage::~GImage() {
+ clear();
+}
+
+
+void GImage::clear() {
+ m_width = 0;
+ m_height = 0;
+ m_memMan->free(m_byte);
+ m_byte = NULL;
+}
+
+
+GImage& GImage::operator=(const GImage& other) {
+ _copy(other);
+ return *this;
+}
+
+
+bool GImage::copySubImage(
+ GImage & dest, const GImage & src,
+ int srcX, int srcY, int srcWidth, int srcHeight) {
+ if ((src.m_width < srcX + srcWidth) ||
+ (src.m_height < srcY + srcHeight) ||
+ (srcY < 0) ||
+ (srcX < 0)) {
+
+ return false;
+ }
+
+ dest.resize(srcWidth, srcHeight, src.m_channels);
+
+ bool ret;
+ ret = pasteSubImage(dest, src, 0, 0, srcX, srcY, srcWidth, srcHeight);
+ debugAssert(ret);
+
+ return true;
+}
+
+
+bool GImage::pasteSubImage(
+ GImage & dest, const GImage & src,
+ int destX, int destY,
+ int srcX, int srcY, int srcWidth, int srcHeight) {
+
+ if ((src.m_width < srcX + srcWidth) ||
+ (src.m_height < srcY + srcHeight) ||
+ (dest.m_width < destX + srcWidth) ||
+ (dest.m_height < destY + srcHeight) ||
+ (srcY < 0) ||
+ (srcX < 0) ||
+ (destY < 0) ||
+ (destX < 0) ||
+ (src.channels() != dest.channels())) {
+
+ return false;
+ }
+
+ for (int i = 0; i < srcHeight; i++) {
+ const uint8* srcRow = src.byte() +
+ ((i + srcY) * src.m_width + srcX) * src.channels();
+ uint8* destRow = dest.byte() +
+ ((i + destY) * dest.width() + destX) * dest.channels();
+ memcpy(destRow, srcRow, srcWidth * src.m_channels);
+ }
+
+ return true;
+}
+
+
+bool GImage::supportedFormat(
+ const std::string& format) {
+
+ return (stringToFormat(format) != UNKNOWN);
+}
+
+
+GImage::Format GImage::stringToFormat(
+ const std::string& format) {
+
+ std::string extension = toUpper(format);
+
+ if ((extension == "JPG") || (extension == "JPEG")) {
+ return JPEG;
+ } else if (extension == "TGA") {
+ return TGA;
+ } else if (extension == "BMP") {
+ return BMP;
+ } else if (extension == "PCX") {
+ return PCX;
+ } else if (extension == "ICO") {
+ return ICO;
+ } else if (extension == "PNG") {
+ return PNG;
+ } else {
+ return UNKNOWN;
+ }
+ // Don't put PPM here, since it has two versions
+}
+
+
+void GImage::save(
+ const std::string& filename,
+ Format format) const {
+
+ BinaryOutput b(filename, G3D_LITTLE_ENDIAN);
+ encode(resolveFormat(filename, NULL, 0, format), b);
+ b.commit(false);
+}
+
+
+void GImage::encode(
+ Format format,
+ uint8*& outData,
+ int& outLength) const {
+
+ BinaryOutput out;
+
+ encode(format, out);
+
+ outData = (uint8*)System::malloc(out.size());
+ debugAssert(outData);
+ outLength = out.size();
+
+ out.commit(outData);
+}
+
+
+void GImage::encode(
+ Format format,
+ BinaryOutput& out) const {
+
+ switch (format) {
+ case PPM_ASCII:
+ encodePPMASCII(out);
+ break;
+
+ case PPM_BINARY:
+ encodePPM(out);
+ break;
+
+ case PNG:
+ encodePNG(out);
+ break;
+
+ case JPEG:
+ encodeJPEG(out);
+ break;
+
+ case BMP:
+ encodeBMP(out);
+ break;
+
+ case TGA:
+ encodeTGA(out);
+ break;
+
+ default:
+ debugAssert(false);
+ }
+}
+
+
+void GImage::insertRedAsAlpha(const GImage& alpha, GImage& output) const {
+ debugAssert(alpha.width() == width());
+ debugAssert(alpha.height() == height());
+
+ // make sure output GImage is valid
+ if (output.width() != width() || output.height() != height() || output.channels() != 4) {
+ output.resize(width(), height(), 4);
+ }
+
+ int N = m_width * m_height;
+ for (int i = 0; i < N; ++i) {
+ output.byte()[i * 4 + 0] = byte()[i * m_channels + 0];
+ output.byte()[i * 4 + 1] = byte()[i * m_channels + 1];
+ output.byte()[i * 4 + 2] = byte()[i * m_channels + 2];
+ output.byte()[i * 4 + 3] = alpha.byte()[i * alpha.m_channels];
+ }
+}
+
+
+void GImage::stripAlpha(GImage& output) const {
+
+ if (output.m_width != m_width || output.m_height != m_height || output.m_channels != 3) {
+ output.resize(m_width, m_height, 3);
+ }
+
+ int N = m_width * m_height;
+ for (int i = 0; i < N; ++i) {
+ output.byte()[i * 3 + 0] = byte()[i * m_channels + 0];
+ output.byte()[i * 3 + 1] = byte()[i * m_channels + 1];
+ output.byte()[i * 3 + 2] = byte()[i * m_channels + 2];
+ }
+}
+
+
+int GImage::sizeInMemory() const {
+ return sizeof(GImage) + m_width * m_height * m_channels;
+}
+
+
+void GImage::computeNormalMap(
+ const GImage& bump,
+ GImage& normal,
+ const BumpMapPreprocess& preprocess) {
+ computeNormalMap(bump.m_width, bump.m_height, bump.m_channels,
+ bump.byte(), normal, preprocess);
+}
+
+void GImage::computeNormalMap(
+ int width,
+ int height,
+ int channels,
+ const uint8* src,
+ GImage& normal,
+ const BumpMapPreprocess& preprocess) {
+
+ float whiteHeightInPixels = preprocess.zExtentPixels;
+ bool lowPassBump = preprocess.lowPassFilter;
+ bool scaleHeightByNz = preprocess.scaleZByNz;
+
+ if (whiteHeightInPixels < 0.0f) {
+ // Default setting scales so that a gradient ramp
+ // over the whole image becomes a 45-degree angle
+
+ // Account for potentially non-square aspect ratios
+ whiteHeightInPixels = max(width, height) * -whiteHeightInPixels;
+ }
+
+ debugAssert(whiteHeightInPixels >= 0);
+
+ const int w = width;
+ const int h = height;
+ const int stride = channels;
+
+ normal.resize(w, h, 4);
+
+ const uint8* const B = src;
+ Color4uint8* const N = normal.pixel4();
+
+ // 1/s for the scale factor that each ELEVATION should be multiplied by.
+ // We avoid actually multiplying by this and instead just divide it out of z.
+ float elevationInvScale = 255.0f / whiteHeightInPixels;
+
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ // Index into normal map pixel
+ int i = x + y * w;
+
+ // Index into bump map *byte*
+ int j = stride * i;
+
+ Vector3 delta;
+
+ // Get a value from B (with wrapping lookup) relative to (x, y)
+ // and divide by 255
+ #define ELEVATION(DX, DY) ((int)B[(((DX + x + w) % w) + \
+ ((DY + y + h) % h) * w) * stride])
+
+
+ // Sobel filter to compute the normal.
+ //
+ // Y Filter (X filter is the transpose)
+ // [ -1 -2 -1 ]
+ // [ 0 0 0 ]
+ // [ 1 2 1 ]
+
+ // Write the Y value directly into the x-component so we don't have
+ // to explicitly compute a cross product at the end. Does not
+ // go out of bounds because the above is computed mod (width, height)
+ delta.y = -( ELEVATION(-1, -1) * 1 + ELEVATION( 0, -1) * 2 + ELEVATION( 1, -1) * 1 +
+ -ELEVATION(-1, 1) * 1 + -ELEVATION( 0, 1) * 2 + -ELEVATION( 1, 1) * 1);
+
+ delta.x = -(-ELEVATION(-1, -1) * 1 + ELEVATION( 1, -1) * 1 +
+ -ELEVATION(-1, 0) * 2 + ELEVATION( 1, 0) * 2 +
+ -ELEVATION(-1, 1) * 1 + ELEVATION( 1, 1) * 1);
+
+ // The scale of each filter row is 4, the filter width is two pixels,
+ // and the "normal" range is 0-255.
+ delta.z = 4 * 2 * elevationInvScale;
+
+ // Delta is now scaled in pixels; normalize
+ delta = delta.direction();
+
+ // Copy over the bump value into the alpha channel.
+ float H = B[j] / 255.0f;
+
+ if (lowPassBump) {
+ H = (ELEVATION(-1, -1) + ELEVATION( 0, -1) + ELEVATION(1, -1) +
+ ELEVATION(-1, 0) + ELEVATION( 0, 0) + ELEVATION(1, 0) +
+ ELEVATION(-1, 1) + ELEVATION( 0, 1) + ELEVATION(1, 1)) / (255.0f * 9.0f);
+ }
+# undef ELEVATION
+
+ if (scaleHeightByNz) {
+ // delta.z can't possibly be negative, so we avoid actually
+ // computing the absolute value.
+ H *= delta.z;
+ }
+
+ N[i].a = iRound(H * 255.0f);
+
+ // Pack into byte range
+ delta = delta * 127.5f + Vector3(127.5f, 127.5f, 127.5f);
+ N[i].r = iClamp(iRound(delta.x), 0, 255);
+ N[i].g = iClamp(iRound(delta.y), 0, 255);
+ N[i].b = iClamp(iRound(delta.z), 0, 255);
+ }
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void GImage::convertToL8() {
+ switch (m_channels) {
+ case 1:
+ return;
+
+ case 3:
+ {
+ // Average
+ Color3uint8* src = (Color3uint8*)m_byte;
+ m_byte = NULL;
+ resize(m_width, m_height, 1);
+ for (int i = m_width * m_height - 1; i >= 0; --i) {
+ const Color3uint8 s = src[i];
+ uint8& d = m_byte[i];
+ d = ((int)s.r + (int)s.g + (int)s.b) / 3;
+ }
+ m_memMan->free(src);
+ }
+ break;
+
+ case 4:
+ {
+ // Average
+ Color4uint8* src = (Color4uint8*)m_byte;
+ m_byte = NULL;
+ resize(m_width, m_height, 1);
+ for (int i = m_width * m_height - 1; i >= 0; --i) {
+ const Color4uint8 s = src[i];
+ uint8& d = m_byte[i];
+ d = ((int)s.r + (int)s.g + (int)s.b) / 3;
+ }
+ m_memMan->free(src);
+ }
+ return;
+
+ default:
+ alwaysAssertM(false, "Bad number of channels in input image");
+ }
+}
+
+
+void GImage::convertToRGBA() {
+ switch (m_channels) {
+ case 1:
+ {
+ // Spread
+ uint8* old = m_byte;
+ m_byte = NULL;
+ resize(m_width, m_height, 4);
+ for (int i = m_width * m_height - 1; i >= 0; --i) {
+ const uint8 s = old[i];
+ Color4uint8& d = ((Color4uint8*)m_byte)[i];
+ d.r = d.g = d.b = s;
+ d.a = 255;
+ }
+ m_memMan->free(m_byte);
+ }
+ break;
+
+ case 3:
+ {
+ // Add alpha
+ Color3uint8* old = (Color3uint8*)m_byte;
+ m_byte = NULL;
+ resize(m_width, m_height, 4);
+ for (int i = m_width * m_height - 1; i >= 0; --i) {
+ const Color3uint8 s = old[i];
+ Color4uint8& d = ((Color4uint8*)m_byte)[i];
+ d.r = s.r;
+ d.g = s.g;
+ d.b = s.b;
+ d.a = 255;
+ }
+ m_memMan->free(old);
+ }
+ break;
+
+ case 4:
+ // Already RGBA
+ return;
+
+ default:
+ alwaysAssertM(false, "Bad number of channels in input image");
+ }
+}
+
+
+void GImage::convertToRGB() {
+ switch (m_channels) {
+ case 1:
+ {
+ // Spread
+ uint8* old = m_byte;
+ m_byte = NULL;
+ resize(m_width, m_height, 3);
+ for (int i = m_width * m_height - 1; i >= 0; --i) {
+ const uint8 s = old[i];
+ Color3uint8& d = ((Color3uint8*)m_byte)[i];
+ d.r = d.g = d.b = s;
+ }
+ m_memMan->free(old);
+ }
+ break;
+
+ case 3:
+ return;
+
+ case 4:
+ // Strip alpha
+ {
+ Color4uint8* old = (Color4uint8*)m_byte;
+ m_byte = NULL;
+ resize(m_width, m_height, 3);
+ for (int i = m_width * m_height - 1; i >= 0; --i) {
+ const Color4uint8 s = old[i];
+ Color3uint8& d = ((Color3uint8*)m_byte)[i];
+ d.r = s.r;
+ d.g = s.g;
+ d.b = s.b;
+ }
+ m_memMan->free(old);
+ }
+ break;
+
+ default:
+ alwaysAssertM(false, "Bad number of channels in input image");
+ }
+}
+
+
+void GImage::R8G8B8_to_Y8U8V8(int width, int height, const uint8* _in, uint8* _out) {
+ const Color3uint8* in = reinterpret_cast<const Color3uint8*>(_in);
+ Color3uint8* out = reinterpret_cast<Color3uint8*>(_out);
+
+ Color3uint8 p;
+ for (int i = width * height - 1; i >= 0; --i) {
+ p.r = iClamp(iRound(in->r * 0.229 + in->g * 0.587 + in->b * 0.114), 0, 255);
+ p.g = iClamp(iRound(in->r * -0.147 + in->g * -0.289 + in->b * 0.436) + 127, 0, 255);
+ p.b = iClamp(iRound(in->r * 0.615 + in->g * -0.515 + in->b * -0.100) + 127, 0, 255);
+ *out = p;
+ ++in;
+ ++out;
+ }
+}
+
+
+
+void GImage::Y8U8V8_to_R8G8B8(int width, int height, const uint8* _in, uint8* _out) {
+ const Color3uint8* in = reinterpret_cast<const Color3uint8*>(_in);
+ Color3uint8* out = reinterpret_cast<Color3uint8*>(_out);
+
+ Color3uint8 p;
+ for (int i = width * height - 1; i >= 0; --i) {
+ p.r = iClamp(iRound(in->r * 1.0753 + (in->b - 127) * 1.2256), 0, 255);
+ p.g = iClamp(iRound(in->r * 1.0753 + (in->g - 127) * -0.3946 + (in->b - 127) * -0.4947), 0, 255);
+ p.b = iClamp(iRound(in->r * 1.0753 + (in->g - 127) * 2.0320 + (in->b - 127) * 0.0853), 0, 255);
+ *out = p;
+ ++in;
+ ++out;
+ }
+}
+
+
+void GImage::makeCheckerboard(GImage& im, int checkerSize, const Color4uint8& A, const Color4uint8& B) {
+ for (int y = 0; y < im.m_height; ++y) {
+ for (int x = 0; x < im.m_width; ++x) {
+ bool checker = isOdd((x / checkerSize) + (y / checkerSize));
+ const Color4uint8& color = checker ? A : B;
+ for (int c = 0; c < im.m_channels; ++c) {
+ uint8* v = im.byte() + (x + y * im.m_width) * im.m_channels + c;
+ *v = color[c];
+ }
+ }
+ }
+}
+
+}
+
diff --git a/dep/src/g3dlite/GImage_bayer.cpp b/dep/src/g3dlite/GImage_bayer.cpp
new file mode 100644
index 00000000000..3d08e8ade5f
--- /dev/null
+++ b/dep/src/g3dlite/GImage_bayer.cpp
@@ -0,0 +1,298 @@
+/**
+ @file GImage_bayer.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-05-27
+ @edited 2006-05-10
+ */
+#include "G3D/platform.h"
+#include "G3D/GImage.h"
+
+namespace G3D {
+
+void GImage::BAYER_G8B8_R8G8_to_Quarter_R8G8B8(int width, int height, const uint8* in, uint8* out) {
+ debugAssert(in != out);
+
+ int halfHeight = height / 2;
+ int halfWidth = width / 2;
+
+ int dst_off = 0;
+ for (int y = 0; y < halfHeight; ++y) {
+ for (int x = 0; x < halfWidth; ++x) {
+ // GBRG
+ int src_off = x*2 + y*2*width;
+ out[dst_off] = in[src_off+width]; // red
+ out[dst_off+1] = ((int)in[src_off] + (int)in[src_off+width+1])/2; // green
+ out[dst_off+2] = in[src_off+1]; // blue
+
+ dst_off = dst_off + 3;
+ }
+ }
+}
+
+
+void GImage::Quarter_R8G8B8_to_BAYER_G8B8_R8G8(int inWidth, int inHeight, const uint8* in, uint8* out) {
+ // Undo quarter-size Bayer as best we can. This code isn't very efficient, but it
+ // also isn't used very frequently.
+
+ debugAssert(out != in);
+
+ int outWidth = 2 * inWidth;
+ int outHeight = 2 * inHeight;
+
+ for (int y = 0; y < outHeight; ++y) {
+ for (int x = 0; x < outWidth; ++x) {
+ const Color3uint8* inp = ((const Color3uint8*)in) + ((x/2) + (y/2)* inWidth);
+ uint8* outp = out + x + y * outWidth;
+
+ if (isEven(y)) {
+ // GB row
+ if (isEven(x)) {
+ // Green
+ *outp = inp->g;
+ } else {
+ // Blue
+ *outp = inp->b;
+ }
+ } else {
+ // RG row
+ if (isEven(x)) {
+ // Red
+ *outp = inp->r;
+ } else {
+ // Green
+ *outp = inp->g;
+ }
+ }
+ }
+ }
+}
+
+
+/** Applies a 5x5 filter to monochrome image I (wrapping at the boundaries) */
+static uint8 applyFilter(
+ const uint8* I,
+ int x,
+ int y,
+ int w,
+ int h,
+ const float filter[5][5]) {
+
+ debugAssert(isEven(w));
+ debugAssert(isEven(h));
+
+ float sum = 0.0f;
+ float denom = 0.0f;
+
+ for (int dy = 0; dy < 5; ++dy) {
+ int offset = ((y + dy + h - 2) % h) * w;
+
+ for (int dx = 0; dx < 5; ++dx) {
+ float f = filter[dy][dx];
+ sum += f * I[((x + dx + w - 2) % w) + offset];
+ denom += f;
+ }
+ }
+
+ return (uint8)iClamp(iRound(sum / denom), 0, 255);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Bayer conversions
+//
+
+// There are two kinds of rows (GR and BG).
+// In each row, there are two kinds of pixels (G/R, B/G).
+// We express the four kinds of INPUT pixels as:
+// GRG, GRG, BGB, BGG
+//
+// There are three kinds of OUTPUT pixels: R, G, B.
+// Thus there are nominally 12 different I/O combinations,
+// but several are impulses because needed output at that
+// location *is* the input (e.g., G_GRG and G_BGG).
+//
+// The following 5x5 row-major filters are named as output_input.
+
+// Green
+static const float G_GRR[5][5] =
+{{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
+{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+{ -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
+{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
+
+static const float G_BGB[5][5] =
+{{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
+{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+{ -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
+{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
+
+// Red
+//(the caption in the paper is wrong for this case:
+// "R row B column really means R row G column"
+static const float R_GRG[5][5] =
+{{ 0.0f, 0.0f, 0.5f, 0.0f, 0.0f},
+{ 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
+{ -1.0f, 4.0f, 5.0f, 4.0f, -1.0f},
+{ 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
+{ 0.0f, 0.0f, 0.5f, 0.0f, 0.0f}};
+
+static const float R_BGG[5][5] =
+{{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
+{ 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
+{ 0.5f, 0.0f, 5.0f, 0.0f, 0.5f},
+{ 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
+{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
+
+static const float R_BGB[5][5] =
+{{ 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f},
+{ 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
+{-3.0f/2.0f, 0.0f, 6.0f, 0.0f, -3.0f/2.0f},
+{ 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
+{ 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f}};
+
+
+// Blue
+//(the caption in the paper is wrong for this case:
+// "B row R column really means B row G column")
+#define B_BGG R_GRG
+#define B_GRG R_BGG
+#define B_GRR R_BGB
+
+
+void GImage::BAYER_R8G8_G8B8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
+ debugAssert(in != _out);
+
+ Color3uint8* out = (Color3uint8*)_out;
+
+ for (int y = 0; y < h; ++y) {
+
+ // Row beginning in the input array.
+ int offset = y * w;
+
+ // RG row
+ for (int x = 0; x < w; ++x, ++out) {
+ // R pixel
+ {
+ out->r = in[x + offset];
+ out->g = applyFilter(in, x, y, w, h, G_GRR);
+ out->b = applyFilter(in, x, y, w, h, B_GRR);
+ }
+ ++x; ++out;
+
+ // G pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_GRG);
+ out->g = in[x + offset];
+ out->b = applyFilter(in, x, y, w, h, B_GRG);
+ }
+ }
+
+ ++y;
+ offset += w;
+
+ // GB row
+ for (int x = 0; x < w; ++x, ++out) {
+ // G pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGG);
+ out->g = in[x + offset];
+ out->b = applyFilter(in, x, y, w, h, B_BGG);
+ }
+ ++x; ++out;
+
+ // B pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGB);
+ out->g = applyFilter(in, x, y, w, h, G_BGB);
+ out->b = in[x + offset];
+ }
+ }
+ }
+}
+
+static void swapRedAndBlue(int N, Color3uint8* out) {
+ for (int i = N - 1; i >= 0; --i) {
+ uint8 tmp = out[i].r;
+ out[i].r = out[i].b;
+ out[i].b = tmp;
+ }
+}
+
+void GImage::BAYER_G8R8_B8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
+ // Run the equivalent function for red
+ BAYER_G8B8_R8G8_to_R8G8B8_MHC(w, h, in, _out);
+
+ // Now swap red and blue
+ swapRedAndBlue(w * h, (Color3uint8*)_out);
+}
+
+
+void GImage::BAYER_B8G8_G8R8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
+ // Run the equivalent function for red
+ BAYER_R8G8_G8B8_to_R8G8B8_MHC(w, h, in, _out);
+
+ // Now swap red and blue
+ swapRedAndBlue(w * h, (Color3uint8*)_out);
+}
+
+
+void GImage::BAYER_G8B8_R8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
+
+ debugAssert(in != _out);
+
+ Color3uint8* out = (Color3uint8*)_out;
+
+ for (int y = 0; y < h; ++y) {
+
+ // Row beginning in the input array.
+ int offset = y * w;
+
+ // GB row
+ for (int x = 0; x < w; ++x, ++out) {
+ // G pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGG);
+ out->g = in[x + offset];
+ out->b = applyFilter(in, x, y, w, h, B_BGG);
+ }
+ ++x; ++out;
+
+ // B pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGB);
+ out->g = applyFilter(in, x, y, w, h, G_BGB);
+ out->b = in[x + offset];
+ }
+ }
+
+ ++y;
+ offset += w;
+
+ // RG row
+ for (int x = 0; x < w; ++x, ++out) {
+ // R pixel
+ {
+ out->r = in[x + offset];
+ out->g = applyFilter(in, x, y, w, h, G_GRR);
+ out->b = applyFilter(in, x, y, w, h, B_GRR);
+ }
+ ++x; ++out;
+
+ // G pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_GRG);
+ out->g = in[x + offset];
+ out->b = applyFilter(in, x, y, w, h, B_GRG);
+ }
+ }
+ }
+
+}
+
+#undef B_BGG
+#undef B_GRG
+#undef B_GRR
+
+}
diff --git a/dep/src/g3dlite/GImage_bmp.cpp b/dep/src/g3dlite/GImage_bmp.cpp
new file mode 100644
index 00000000000..425a7e1a1d2
--- /dev/null
+++ b/dep/src/g3dlite/GImage_bmp.cpp
@@ -0,0 +1,717 @@
+/**
+ @file GImage_bmp.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-05-27
+ @edited 2006-05-10
+ */
+#include "G3D/platform.h"
+#include "G3D/GImage.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Log.h"
+
+namespace G3D {
+
+#ifndef G3D_WIN32
+/**
+ This is used by the Windows bitmap I/O.
+ */
+static const int BI_RGB = 0;
+#endif
+
+void GImage::encodeBMP(
+ BinaryOutput& out) const {
+
+ debugAssert(m_channels == 1 || m_channels == 3);
+ out.setEndian(G3D_LITTLE_ENDIAN);
+
+ uint8 red;
+ uint8 green;
+ uint8 blue;
+ int pixelBufferSize = m_width * m_height * 3;
+ int fileHeaderSize = 14;
+ int infoHeaderSize = 40;
+ int BMScanWidth;
+ int BMPadding;
+
+ // First write the BITMAPFILEHEADER
+ //
+ // WORD bfType;
+ // DWORD bfSize;
+ // WORD bfReserved1;
+ // WORD bfReserved2;
+ // DWORD bfOffBits;
+
+ // Type
+ out.writeUInt8('B');
+ out.writeUInt8('M');
+
+ // File size
+ out.writeUInt32(fileHeaderSize + infoHeaderSize + pixelBufferSize);
+
+ // Two reserved fields set to zero
+ out.writeUInt16(0);
+ out.writeUInt16(0);
+
+ // The offset, in bytes, from the BITMAPFILEHEADER structure
+ // to the bitmap bits.
+ out.writeUInt32(infoHeaderSize + fileHeaderSize);
+
+ // Now the BITMAPINFOHEADER
+ //
+ // DWORD biSize;
+ // LONG biWidth;
+ // LONG biHeight;
+ // WORD biPlanes;
+ // WORD biBitCount
+ // DWORD biCompression;
+ // DWORD biSizeImage;
+ // LONG biXPelsPerMeter;
+ // LONG biYPelsPerMeter;
+ // DWORD biClrUsed;
+ // DWORD biClrImportant;
+
+ // Size of the info header
+ out.writeUInt32(infoHeaderSize);
+
+ // Width and height of the image
+ out.writeUInt32(m_width);
+ out.writeUInt32(m_height);
+
+ // Planes ("must be set to 1")
+ out.writeUInt16(1);
+
+ // BitCount and CompressionType
+ out.writeUInt16(24);
+ out.writeUInt32(BI_RGB);
+
+ // Image size ("may be zero for BI_RGB bitmaps")
+ out.writeUInt32(0);
+
+ // biXPelsPerMeter
+ out.writeUInt32(0);
+ // biYPelsPerMeter
+ out.writeUInt32(0);
+
+ // biClrUsed
+ out.writeUInt32(0);
+
+ // biClrImportant
+ out.writeUInt32(0);
+
+ BMScanWidth = m_width * 3;
+
+ if (BMScanWidth & 3) {
+ BMPadding = 4 - (BMScanWidth & 3);
+ } else {
+ BMPadding = 0;
+ }
+
+ int hStart = m_height - 1;
+ int hEnd = -1;
+ int hDir = -1;
+ int dest;
+
+ // Write the pixel data
+ for (int h = hStart; h != hEnd; h += hDir) {
+ dest = m_channels * h * m_width;
+ for (int w = 0; w < m_width; ++w) {
+
+ if (m_channels == 3) {
+ red = m_byte[dest];
+ green = m_byte[dest + 1];
+ blue = m_byte[dest + 2];
+ } else {
+ red = m_byte[dest];
+ green = m_byte[dest];
+ blue = m_byte[dest];
+ }
+
+ out.writeUInt8(blue);
+ out.writeUInt8(green);
+ out.writeUInt8(red);
+
+ dest += m_channels;
+ }
+
+ if (BMPadding > 0) {
+ out.skip(BMPadding);
+ }
+ }
+}
+
+
+void GImage::decodeBMP(
+ BinaryInput& input) {
+
+ // The BMP decoding uses these flags.
+ static const uint16 PICTURE_NONE = 0x0000;
+ static const uint16 PICTURE_BITMAP = 0x1000;
+
+ // Compression Flags
+ static const uint16 PICTURE_UNCOMPRESSED = 0x0100;
+ static const uint16 PICTURE_MONOCHROME = 0x0001;
+ static const uint16 PICTURE_4BIT = 0x0002;
+ static const uint16 PICTURE_8BIT = 0x0004;
+ static const uint16 PICTURE_16BIT = 0x0008;
+ static const uint16 PICTURE_24BIT = 0x0010;
+ static const uint16 PICTURE_32BIT = 0x0020;
+
+ (void)PICTURE_16BIT;
+ (void)PICTURE_32BIT;
+
+ // This is a simple BMP loader that can handle uncompressed BMP files.
+ // Verify this is a BMP file by looking for the BM tag.
+ input.reset();
+ std::string tag = input.readString(2);
+ if (tag != "BM") {
+ throw Error("Not a BMP file", input.getFilename());
+ }
+
+ m_channels = 3;
+ // Skip to the BITMAPINFOHEADER's width and height
+ input.skip(16);
+
+ m_width = input.readUInt32();
+ m_height = input.readUInt32();
+
+ // Skip to the bit count and compression type
+ input.skip(2);
+
+ uint16 bitCount = input.readUInt16();
+ uint32 compressionType = input.readUInt32();
+
+ uint8 red;
+ uint8 green;
+ uint8 blue;
+ uint8 blank;
+
+ // Only uncompressed bitmaps are supported by this code
+ if ((int32)compressionType != BI_RGB) {
+ throw Error("BMP images must be uncompressed", input.getFilename());
+ }
+
+ uint8* palette = NULL;
+
+ // Create the palette if needed
+ if (bitCount <= 8) {
+
+ // Skip to the palette color count in the header
+ input.skip(12);
+
+ int numColors = input.readUInt32();
+
+ palette = (uint8*)System::malloc(numColors * 3);
+ debugAssert(palette);
+
+ // Skip past the end of the header to the palette info
+ input.skip(4);
+
+ int c;
+ for(c = 0; c < numColors * 3; c += 3) {
+ // Palette information in bitmaps is stored in BGR_ format.
+ // That means it's blue-green-red-blank, for each entry.
+ blue = input.readUInt8();
+ green = input.readUInt8();
+ red = input.readUInt8();
+ blank = input.readUInt8();
+
+ palette[c] = red;
+ palette[c + 1] = green;
+ palette[c + 2] = blue;
+ }
+ }
+
+ int hStart = 0;
+ int hEnd = 0;
+ int hDir = 0;
+
+ if (m_height < 0) {
+ m_height = -m_height;
+ hStart = 0;
+ hEnd = m_height;
+ hDir = 1;
+ } else {
+ //height = height;
+ hStart = m_height - 1;
+ hEnd = -1;
+ hDir = -1;
+ }
+
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * 3);
+ debugAssert(m_byte);
+
+ int BMScanWidth;
+ int BMPadding;
+ uint8 BMGroup;
+ uint8 BMPixel8;
+ int currPixel;
+ int dest;
+ int flags = PICTURE_NONE;
+
+ if (bitCount == 1) {
+ // Note that this file is not necessarily grayscale, since it's possible
+ // the palette is blue-and-white, or whatever. But of course most image
+ // programs only write 1-bit images if they're black-and-white.
+ flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_MONOCHROME;
+
+ // For bitmaps, each scanline is dword-aligned.
+ BMScanWidth = (m_width + 7) >> 3;
+ if (BMScanWidth & 3) {
+ BMScanWidth += 4 - (BMScanWidth & 3);
+ }
+
+ // Powers of 2
+ int pow2[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+
+ for (int h = hStart; h != hEnd; h += hDir) {
+
+ currPixel = 0;
+ dest = 3 * h * m_width;
+
+ for (int w = 0; w < BMScanWidth; ++w) {
+
+ BMGroup = input.readUInt8();
+
+ // Now we read the pixels. Usually there are eight pixels per byte,
+ // since each pixel is represented by one bit, but if the width
+ // is not a multiple of eight, the last byte will have some bits
+ // set, with the others just being extra. Plus there's the
+ // dword-alignment padding. So we keep checking to see if we've
+ // already read "width" number of pixels.
+ for (int i = 7; i >= 0; --i) {
+ if (currPixel < m_width) {
+ int src = 3 * ((BMGroup & pow2[i]) >> i);
+
+ m_byte[dest] = palette[src];
+ m_byte[dest + 1] = palette[src + 1];
+ m_byte[dest + 2] = palette[src + 2];
+
+ ++currPixel;
+ dest += 3;
+ }
+ }
+ }
+ }
+
+ } else if (bitCount == 4) {
+
+ flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_4BIT;
+
+ // For bitmaps, each scanline is dword-aligned.
+ int BMScanWidth = (m_width + 1) >> 1;
+ if (BMScanWidth & 3) {
+ BMScanWidth += 4 - (BMScanWidth & 3);
+ }
+
+ for (int h = hStart; h != hEnd; h += hDir) {
+
+ currPixel = 0;
+ dest = 3 * h * m_width;
+
+ for (int w = 0; w < BMScanWidth; w++) {
+
+ BMGroup = input.readUInt8();
+ int src[2];
+ src[0] = 3 * ((BMGroup & 0xF0) >> 4);
+ src[1] = 3 * (BMGroup & 0x0F);
+
+ // Now we read the pixels. Usually there are two pixels per byte,
+ // since each pixel is represented by four bits, but if the width
+ // is not a multiple of two, the last byte will have only four bits
+ // set, with the others just being extra. Plus there's the
+ // dword-alignment padding. So we keep checking to see if we've
+ // already read "Width" number of pixels.
+
+ for (int i = 0; i < 2; ++i) {
+ if (currPixel < m_width) {
+ int tsrc = src[i];
+
+ m_byte[dest] = palette[tsrc];
+ m_byte[dest + 1] = palette[tsrc + 1];
+ m_byte[dest + 2] = palette[tsrc + 2];
+
+ ++currPixel;
+ dest += 3;
+ }
+ }
+ }
+ }
+
+ } else if (bitCount == 8) {
+
+ flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_8BIT;
+
+ // For bitmaps, each scanline is dword-aligned.
+ BMScanWidth = m_width;
+ if (BMScanWidth & 3) {
+ BMScanWidth += 4 - (BMScanWidth & 3);
+ }
+
+ for (int h = hStart; h != hEnd; h += hDir) {
+
+ currPixel = 0;
+
+ for (int w = 0; w < BMScanWidth; ++w) {
+
+ BMPixel8 = input.readUInt8();
+
+ if (currPixel < m_width) {
+ dest = 3 * ((h * m_width) + currPixel);
+ int src = 3 * BMPixel8;
+
+ m_byte[dest] = palette[src];
+ m_byte[dest + 1] = palette[src + 1];
+ m_byte[dest + 2] = palette[src + 2];
+
+ ++currPixel;
+ }
+ }
+ }
+
+ } else if (bitCount == 16) {
+
+ m_memMan->free(m_byte);
+ m_byte = NULL;
+ System::free(palette);
+ palette = NULL;
+ throw Error("16-bit bitmaps not supported", input.getFilename());
+
+ } else if (bitCount == 24) {
+ input.skip(20);
+
+ flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_24BIT;
+
+ // For bitmaps, each scanline is dword-aligned.
+ BMScanWidth = m_width * 3;
+
+ if (BMScanWidth & 3) {
+ BMPadding = 4 - (BMScanWidth & 3);
+ } else {
+ BMPadding = 0;
+ }
+
+ for (int h = hStart; h != hEnd; h += hDir) {
+ dest = 3 * h * m_width;
+ for (int w = 0; w < m_width; ++w) {
+
+ blue = input.readUInt8();
+ green = input.readUInt8();
+ red = input.readUInt8();
+
+ m_byte[dest] = red;
+ m_byte[dest + 1] = green;
+ m_byte[dest + 2] = blue;
+
+ dest += 3;
+ }
+
+ if (BMPadding) {
+ input.skip(2);
+ }
+ }
+
+ } else if (bitCount == 32) {
+
+ m_memMan->free(m_byte);
+ m_byte = NULL;
+ System::free(palette);
+ palette = NULL;
+ throw Error("32 bit bitmaps not supported", input.getFilename());
+
+ } else {
+ // We support all possible bit depths, so if the
+ // code gets here, it's not even a real bitmap.
+ m_memMan->free(m_byte);
+ m_byte = NULL;
+ throw Error("Not a bitmap!", input.getFilename());
+ }
+
+ System::free(palette);
+ palette = NULL;
+}
+
+
+void GImage::decodeICO(
+ BinaryInput& input) {
+
+ // Header
+ uint16 r = input.readUInt16();
+ debugAssert(r == 0);
+ r = input.readUInt16();
+ debugAssert(r == 1);
+
+ // Read the number of icons, although we'll only load the
+ // first one.
+ int count = input.readUInt16();
+
+ m_channels = 4;
+
+ debugAssert(count > 0);
+
+ const uint8* headerBuffer = input.getCArray() + input.getPosition();
+ int maxWidth = 0, maxHeight = 0;
+ int maxHeaderNum = 0;
+ for (int currentHeader = 0; currentHeader < count; ++currentHeader) {
+
+ const uint8* curHeaderBuffer = headerBuffer + (currentHeader * 16);
+ int tmpWidth = curHeaderBuffer[0];
+ int tmpHeight = curHeaderBuffer[1];
+ // Just in case there is a non-square icon, checking area
+ if ((tmpWidth * tmpHeight) > (maxWidth * maxHeight)) {
+ maxWidth = tmpWidth;
+ maxHeight = tmpHeight;
+ maxHeaderNum = currentHeader;
+ }
+ }
+
+ input.skip(maxHeaderNum * 16);
+
+ m_width = input.readUInt8();
+ m_height = input.readUInt8();
+ int numColors = input.readUInt8();
+
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * m_channels);
+ debugAssert(m_byte);
+
+ // Bit mask for packed bits
+ int mask = 0;
+
+ int bitsPerPixel = 8;
+
+ switch (numColors) {
+ case 2:
+ mask = 0x01;
+ bitsPerPixel = 1;
+ break;
+
+ case 16:
+ mask = 0x0F;
+ bitsPerPixel = 4;
+ break;
+
+ case 0:
+ numColors = 256;
+ mask = 0xFF;
+ bitsPerPixel = 8;
+ break;
+
+ default:
+ throw Error("Unsupported ICO color count.", input.getFilename());
+ }
+
+ input.skip(5);
+ // Skip 'size' unused
+ input.skip(4);
+
+ int offset = input.readUInt32();
+
+ // Skip over any other icon descriptions
+ input.setPosition(offset);
+
+ // Skip over bitmap header; it is redundant
+ input.skip(40);
+
+ Array<Color4uint8> palette;
+ palette.resize(numColors, true);
+ for (int c = 0; c < numColors; ++c) {
+ palette[c].b = input.readUInt8();
+ palette[c].g = input.readUInt8();
+ palette[c].r = input.readUInt8();
+ palette[c].a = input.readUInt8();
+ }
+
+ // The actual image and mask follow
+
+ // The XOR Bitmap is stored as 1-bit, 4-bit or 8-bit uncompressed Bitmap
+ // using the same encoding as BMP files. The AND Bitmap is stored in as
+ // 1-bit uncompressed Bitmap.
+ //
+ // Pixels are stored bottom-up, left-to-right. Pixel lines are padded
+ // with zeros to end on a 32bit (4byte) boundary. Every line will have the
+ // same number of bytes. Color indices are zero based, meaning a pixel color
+ // of 0 represents the first color table entry, a pixel color of 255 (if there
+ // are that many) represents the 256th entry.
+/*
+ int bitsPerRow = width * bitsPerPixel;
+ int bytesPerRow = iCeil((double)bitsPerRow / 8);
+ // Rows are padded to 32-bit boundaries
+ bytesPerRow += bytesPerRow % 4;
+
+ // Read the XOR values into the color channel
+ for (int y = height - 1; y >= 0; --y) {
+ int x = 0;
+ // Read the row
+ for (int i = 0; i < bytesPerRow; ++i) {
+ uint8 byte = input.readUInt8();
+ for (int j = 0; (j < 8) && (x < width); ++x, j += bitsPerPixel) {
+ int bit = ((byte << j) >> (8 - bitsPerPixel)) & mask;
+ pixel4(x, y) = colorTable[bit];
+ }
+ }
+ }
+*/
+ int hStart = 0;
+ int hEnd = 0;
+ int hDir = 0;
+
+ if (m_height < 0) {
+ m_height = -m_height;
+ hStart = 0;
+ hEnd = m_height;
+ hDir = 1;
+ } else {
+ //height = height;
+ hStart = m_height - 1;
+ hEnd = -1;
+ hDir = -1;
+ }
+
+ int BMScanWidth;
+ uint8 BMGroup;
+ uint8 BMPixel8;
+ int currPixel;
+ int dest;
+
+ if (bitsPerPixel == 1) {
+ // Note that this file is not necessarily grayscale, since it's possible
+ // the palette is blue-and-white, or whatever. But of course most image
+ // programs only write 1-bit images if they're black-and-white.
+
+ // For bitmaps, each scanline is dword-aligned.
+ BMScanWidth = (m_width + 7) >> 3;
+ if (BMScanWidth & 3) {
+ BMScanWidth += 4 - (BMScanWidth & 3);
+ }
+
+ // Powers of 2
+ int pow2[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+
+ for (int h = hStart; h != hEnd; h += hDir) {
+
+ currPixel = 0;
+ dest = 3 * h * m_width;
+
+ for (int w = 0; w < BMScanWidth; ++w) {
+
+ BMGroup = input.readUInt8();
+
+ // Now we read the pixels. Usually there are eight pixels per byte,
+ // since each pixel is represented by one bit, but if the width
+ // is not a multiple of eight, the last byte will have some bits
+ // set, with the others just being extra. Plus there's the
+ // dword-alignment padding. So we keep checking to see if we've
+ // already read "width" number of pixels.
+ for (int i = 7; i >= 0; --i) {
+ if (currPixel < m_width) {
+ int src = ((BMGroup & pow2[i]) >> i);
+
+ m_byte[dest] = palette[src].r;
+ m_byte[dest + 1] = palette[src].g;
+ m_byte[dest + 2] = palette[src].b;
+
+ ++currPixel;
+ dest += 4;
+ }
+ }
+ }
+ }
+
+ } else if (bitsPerPixel == 4) {
+
+ // For bitmaps, each scanline is dword-aligned.
+ int BMScanWidth = (m_width + 1) >> 1;
+ if (BMScanWidth & 3) {
+ BMScanWidth += 4 - (BMScanWidth & 3);
+ }
+
+ for (int h = hStart; h != hEnd; h += hDir) {
+
+ currPixel = 0;
+ dest = 4 * h * m_width;
+
+ for (int w = 0; w < BMScanWidth; w++) {
+
+ BMGroup = input.readUInt8();
+ int src[2];
+ src[0] = ((BMGroup & 0xF0) >> 4);
+ src[1] = (BMGroup & 0x0F);
+
+ // Now we read the pixels. Usually there are two pixels per byte,
+ // since each pixel is represented by four bits, but if the width
+ // is not a multiple of two, the last byte will have only four bits
+ // set, with the others just being extra. Plus there's the
+ // dword-alignment padding. So we keep checking to see if we've
+ // already read "Width" number of pixels.
+
+ for (int i = 0; i < 2; ++i) {
+ if (currPixel < m_width) {
+ int tsrc = src[i];
+
+ m_byte[dest] = palette[tsrc].r;
+ m_byte[dest + 1] = palette[tsrc].g;
+ m_byte[dest + 2] = palette[tsrc].b;
+
+ ++currPixel;
+ dest += 4;
+ }
+ }
+ }
+ }
+
+ } else if (bitsPerPixel == 8) {
+
+ // For bitmaps, each scanline is dword-aligned.
+ BMScanWidth = m_width;
+ if (BMScanWidth & 3) {
+ BMScanWidth += 4 - (BMScanWidth & 3);
+ }
+
+ for (int h = hStart; h != hEnd; h += hDir) {
+
+ currPixel = 0;
+
+ for (int w = 0; w < BMScanWidth; ++w) {
+
+ BMPixel8 = input.readUInt8();
+
+ if (currPixel < m_width) {
+ dest = 4 * ((h * m_width) + currPixel);
+ int src = BMPixel8;
+
+ m_byte[dest] = palette[src].r;
+ m_byte[dest + 1] = palette[src].g;
+ m_byte[dest + 2] = palette[src].b;
+
+ ++currPixel;
+ }
+ }
+ }
+ }
+
+ // Read the mask into the alpha channel
+ int bitsPerRow = m_width;
+ int bytesPerRow = iCeil((double)bitsPerRow / 8);
+
+ // For bitmaps, each scanline is dword-aligned.
+ //BMScanWidth = (width + 1) >> 1;
+ if (bytesPerRow & 3) {
+ bytesPerRow += 4 - (bytesPerRow & 3);
+ }
+
+ for (int y = m_height - 1; y >= 0; --y) {
+ int x = 0;
+ // Read the row
+ for (int i = 0; i < bytesPerRow; ++i) {
+ uint8 byte = input.readUInt8();
+ for (int j = 0; (j < 8) && (x < m_width); ++x, ++j) {
+ int bit = (byte >> (7 - j)) & 0x01;
+ pixel4(x, y).a = (1 - bit) * 0xFF;
+ }
+ }
+ }
+
+}
+
+
+}
diff --git a/dep/src/g3dlite/GImage_jpeg.cpp b/dep/src/g3dlite/GImage_jpeg.cpp
new file mode 100644
index 00000000000..0b0521f31e7
--- /dev/null
+++ b/dep/src/g3dlite/GImage_jpeg.cpp
@@ -0,0 +1,446 @@
+/**
+ @file GImage_jpeg.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-05-27
+ @edited 2009-04-20
+ */
+#include "G3D/platform.h"
+#include "G3D/GImage.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+#include <cstring>
+
+extern "C" {
+#ifdef G3D_LINUX
+# include <jconfig.h>
+# include <jpeglib.h>
+#else
+# include "jconfig.h"
+# include "jpeglib.h"
+#endif
+}
+
+namespace G3D {
+
+
+const int jpegQuality = 96;
+
+/**
+ The IJG library needs special setup for compress/decompressing
+ from memory. These classes provide them.
+
+ The format of this class is defined by the IJG library; do not
+ change it.
+ */
+class memory_destination_mgr {
+public:
+ struct jpeg_destination_mgr pub;
+ JOCTET* buffer;
+ int size;
+ int count;
+};
+
+typedef memory_destination_mgr* mem_dest_ptr;
+
+/**
+ Signature dictated by IJG.
+ */
+static void init_destination (
+ j_compress_ptr cinfo) {
+
+ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = dest->size;
+ dest->count=0;
+}
+
+/**
+ Signature dictated by IJG.
+ */
+static boolean empty_output_buffer (
+ j_compress_ptr cinfo) {
+
+ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = dest->size;
+
+ return TRUE;
+}
+
+/**
+ Signature dictated by IJG.
+ */
+static void term_destination (
+ j_compress_ptr cinfo) {
+
+ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+ dest->count = dest->size - dest->pub.free_in_buffer;
+}
+
+/**
+ Signature dictated by IJG.
+ */
+static void jpeg_memory_dest (
+ j_compress_ptr cinfo,
+ JOCTET* buffer,
+ int size) {
+
+ mem_dest_ptr dest;
+
+ if (cinfo->dest == NULL) {
+ // First time for this JPEG object; call the
+ // IJG allocator to get space.
+ cinfo->dest = (struct jpeg_destination_mgr*)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
+ JPOOL_PERMANENT,
+ sizeof(memory_destination_mgr));
+ }
+
+ dest = (mem_dest_ptr) cinfo->dest;
+ dest->size = size;
+ dest->buffer = buffer;
+ dest->pub.init_destination = init_destination;
+ dest->pub.empty_output_buffer = empty_output_buffer;
+ dest->pub.term_destination = term_destination;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+#define INPUT_BUF_SIZE 4096
+
+/**
+ Structure dictated by IJG.
+ */
+class memory_source_mgr {
+public:
+ struct jpeg_source_mgr pub;
+ int source_size;
+ unsigned char* source_data;
+ boolean start_of_data;
+ JOCTET* buffer;
+};
+
+
+typedef memory_source_mgr* mem_src_ptr;
+
+
+/**
+ Signature dictated by IJG.
+ */
+static void init_source(
+ j_decompress_ptr cinfo) {
+
+ mem_src_ptr src = (mem_src_ptr) cinfo->src;
+
+ src->start_of_data = TRUE;
+}
+
+
+/**
+ Signature dictated by IJG.
+ */
+static boolean fill_input_buffer(
+ j_decompress_ptr cinfo) {
+
+ mem_src_ptr src = (mem_src_ptr) cinfo->src;
+
+ size_t bytes_read = 0;
+
+ if (src->source_size > INPUT_BUF_SIZE)
+ bytes_read = INPUT_BUF_SIZE;
+ else
+ bytes_read = src->source_size;
+
+ memcpy (src->buffer, src->source_data, bytes_read);
+
+ src->source_data += bytes_read;
+ src->source_size -= bytes_read;
+
+ src->pub.next_input_byte = src->buffer;
+ src->pub.bytes_in_buffer = bytes_read;
+ src->start_of_data = FALSE;
+
+
+ return TRUE;
+}
+
+
+/**
+ Signature dictated by IJG.
+ */
+static void skip_input_data(
+ j_decompress_ptr cinfo,
+ long num_bytes) {
+
+ mem_src_ptr src = (mem_src_ptr)cinfo->src;
+
+ if (num_bytes > 0) {
+ while (num_bytes > (long) src->pub.bytes_in_buffer) {
+ num_bytes -= (long) src->pub.bytes_in_buffer;
+ boolean s = fill_input_buffer(cinfo);
+ debugAssert(s); (void)s;
+ }
+
+ src->pub.next_input_byte += (size_t) num_bytes;
+ src->pub.bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+
+
+/**
+ Signature dictated by IJG.
+ */
+static void term_source (
+ j_decompress_ptr cinfo) {
+ (void)cinfo;
+ // Intentionally empty
+}
+
+
+/**
+ Signature dictated by IJG.
+ */
+static void jpeg_memory_src (
+ j_decompress_ptr cinfo,
+ JOCTET* buffer,
+ int size) {
+
+ mem_src_ptr src;
+
+ if (cinfo->src == NULL) {
+ // First time for this JPEG object
+ cinfo->src = (struct jpeg_source_mgr*)
+ (*cinfo->mem->alloc_small)(
+ (j_common_ptr) cinfo,
+ JPOOL_PERMANENT,
+ sizeof(memory_source_mgr));
+
+ src = (mem_src_ptr)cinfo->src;
+
+ src->buffer = (JOCTET*)
+ (*cinfo->mem->alloc_small)(
+ (j_common_ptr) cinfo,
+ JPOOL_PERMANENT,
+ INPUT_BUF_SIZE * sizeof(JOCTET));
+ }
+
+ src = (mem_src_ptr)cinfo->src;
+ src->pub.init_source = init_source;
+ src->pub.fill_input_buffer = fill_input_buffer;
+ src->pub.skip_input_data = skip_input_data;
+
+ // use default method
+ src->pub.resync_to_restart = jpeg_resync_to_restart;
+ src->pub.term_source = term_source;
+ src->source_data = buffer;
+ src->source_size = size;
+
+ // forces fill_input_buffer on first read
+ src->pub.bytes_in_buffer = 0;
+
+ // until buffer loaded
+ src->pub.next_input_byte = NULL;
+}
+
+
+void GImage::encodeJPEG(
+ BinaryOutput& out) const {
+
+ if (m_channels != 3) {
+ // Convert to three channel
+ GImage tmp = *this;
+ tmp.convertToRGB();
+ tmp.encodeJPEG(out);
+ return;
+ }
+
+ debugAssert(m_channels == 3);
+ out.setEndian(G3D_LITTLE_ENDIAN);
+
+ // Allocate and initialize a compression object
+ jpeg_compress_struct cinfo;
+ jpeg_error_mgr jerr;
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ // Specify the destination for the compressed data.
+ // (Overestimate the size)
+ int buffer_size = m_width * m_height * 3 + 200;
+ JOCTET* compressed_data = (JOCTET*)System::malloc(buffer_size);
+ jpeg_memory_dest(&cinfo, compressed_data, buffer_size);
+
+
+ cinfo.image_width = m_width;
+ cinfo.image_height = m_height;
+
+ // # of color components per pixel
+ cinfo.input_components = 3;
+
+ // colorspace of input image
+ cinfo.in_color_space = JCS_RGB;
+ cinfo.input_gamma = 1.0;
+
+ // Set parameters for compression, including image size & colorspace
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, jpegQuality, false);
+ cinfo.smoothing_factor = 0;
+ cinfo.optimize_coding = TRUE;
+// cinfo.dct_method = JDCT_FLOAT;
+ cinfo.dct_method = JDCT_ISLOW;
+ cinfo.jpeg_color_space = JCS_YCbCr;
+
+ // Initialize the compressor
+ jpeg_start_compress(&cinfo, TRUE);
+
+ // Iterate over all scanlines from top to bottom
+ // pointer to a single row
+ JSAMPROW row_pointer[1];
+
+ // JSAMPLEs per row in image_buffer
+ int row_stride = cinfo.image_width * 3;
+ while (cinfo.next_scanline < cinfo.image_height) {
+ row_pointer[0] = &(m_byte[cinfo.next_scanline * row_stride]);
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ // Shut down the compressor
+ jpeg_finish_compress(&cinfo);
+
+ // Figure out how big the result was.
+ int outLength = ((mem_dest_ptr)cinfo.dest)->count;
+
+ // Release the JPEG compression object
+ jpeg_destroy_compress(&cinfo);
+
+ // Copy into an appropriately sized output buffer.
+ out.writeBytes(compressed_data, outLength);
+
+ // Free the conservative buffer.
+ System::free(compressed_data);
+ compressed_data = NULL;
+}
+
+
+void GImage::decodeJPEG(
+ BinaryInput& input) {
+
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ int loc = 0;
+
+ m_channels = 3;
+ // We have to set up the error handler, in case initialization fails.
+ cinfo.err = jpeg_std_error(&jerr);
+
+ // Initialize the JPEG decompression object.
+ jpeg_create_decompress(&cinfo);
+
+ // Specify data source (eg, a file, for us, memory)
+ jpeg_memory_src(&cinfo, const_cast<uint8*>(input.getCArray()), input.size());
+
+ // Read the parameters with jpeg_read_header()
+ jpeg_read_header(&cinfo, TRUE);
+
+ // Set parameters for decompression
+ // (We do nothing here since the defaults are fine)
+
+ // Start decompressor
+ jpeg_start_decompress(&cinfo);
+
+ // Get and set the values of interest to this object
+ m_width = cinfo.output_width;
+ m_height = cinfo.output_height;
+
+ // Prepare the pointer object for the pixel data
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * 3);
+
+ // JSAMPLEs per row in output buffer
+ int bpp = cinfo.output_components;
+ int row_stride = cinfo.output_width * bpp;
+
+ // Make a one-row-high sample array that will go away when done with image
+ JSAMPARRAY temp = (*cinfo.mem->alloc_sarray)
+ ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+
+ // Read data on a scanline by scanline basis
+ while (cinfo.output_scanline < cinfo.output_height) {
+
+ // We may need to adjust the output based on the
+ // number of channels it has.
+ switch (bpp) {
+ case 1:
+ // Grayscale; decompress to temp.
+ jpeg_read_scanlines(&cinfo, temp, 1);
+
+ // Expand to three channels
+ {
+ uint8* scan = &(m_byte[loc * 3]);
+ uint8* endScan = scan + (m_width * 3);
+ uint8* t = *temp;
+
+ while (scan < endScan) {
+ uint8 value = t[0];
+
+ // Spread the value 3x.
+ scan[0] = value;
+ scan[1] = value;
+ scan[2] = value;
+
+ scan += 3;
+ t += 1;
+ }
+ }
+ break;
+
+ case 3:
+ // Read directly into the array
+ {
+ // Need one extra level of indirection.
+ uint8* scan = m_byte + loc;
+ JSAMPARRAY ptr = &scan;
+ jpeg_read_scanlines(&cinfo, ptr, 1);
+ }
+ break;
+
+ case 4:
+ // RGBA; decompress to temp.
+ jpeg_read_scanlines(&cinfo, temp, 1);
+
+ // Drop the 3rd channel
+ {
+ uint8* scan = &(m_byte[loc * 3]);
+ uint8* endScan = scan + m_width * 3;
+ uint8* t = *temp;
+
+ while (scan < endScan) {
+ scan[0] = t[0];
+ scan[1] = t[1];
+ scan[2] = t[2];
+
+ scan += 3;
+ t += 4;
+ }
+ }
+ break;
+
+ default:
+ throw Error("Unexpected number of channels.", input.getFilename());
+ }
+
+ loc += row_stride;
+ }
+
+ // Finish decompression
+ jpeg_finish_decompress(&cinfo);
+
+ alwaysAssertM(this, "Corrupt GImage");
+ // Release JPEG decompression object
+ jpeg_destroy_decompress(&cinfo);
+}
+
+
+}
diff --git a/dep/src/g3dlite/GImage_png.cpp b/dep/src/g3dlite/GImage_png.cpp
new file mode 100644
index 00000000000..0a515bf7ed2
--- /dev/null
+++ b/dep/src/g3dlite/GImage_png.cpp
@@ -0,0 +1,266 @@
+/**
+ @file GImage_png.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-05-27
+ @edited 2009-04-20
+ */
+#include "G3D/platform.h"
+#include "G3D/GImage.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Log.h"
+#include <png.h>
+
+namespace G3D {
+
+
+//libpng required function signature
+static void png_read_data(
+ png_structp png_ptr,
+ png_bytep data,
+ png_size_t length) {
+
+
+ debugAssert( png_ptr->io_ptr != NULL );
+ debugAssert( length >= 0 );
+ debugAssert( data != NULL );
+
+ ((BinaryInput*)png_ptr->io_ptr)->readBytes(data, length);
+}
+
+//libpng required function signature
+static void png_write_data(png_structp png_ptr,
+ png_bytep data,
+ png_size_t length) {
+
+ debugAssert( png_ptr->io_ptr != NULL );
+ debugAssert( data != NULL );
+
+ ((BinaryOutput*)png_ptr->io_ptr)->writeBytes(data, length);
+}
+
+//libpng required function signature
+static void png_flush_data(
+ png_structp png_ptr) {
+ (void)png_ptr;
+ //Do nothing.
+}
+
+//libpng required function signature
+static void png_error(
+ png_structp png_ptr,
+ png_const_charp error_msg) {
+
+ (void)png_ptr;
+ debugAssert( error_msg != NULL );
+ throw GImage::Error(error_msg, "PNG");
+}
+
+
+//libpng required function signature
+void png_warning(
+ png_structp png_ptr,
+ png_const_charp warning_msg) {
+
+ (void)png_ptr;
+ debugAssert( warning_msg != NULL );
+ Log::common()->println(warning_msg);
+}
+
+
+void GImage::encodePNG(
+ BinaryOutput& out) const {
+
+ debugAssert( m_channels == 1 || m_channels == 3 || m_channels == 4 );
+
+ if (m_height > (int)(PNG_UINT_32_MAX / png_sizeof(png_bytep)))
+ throw GImage::Error("Unsupported PNG height.", out.getFilename());
+
+ out.setEndian(G3D_LITTLE_ENDIAN);
+
+ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error, png_warning);
+ if (! png_ptr) {
+ throw GImage::Error("Unable to initialize PNG encoder.", out.getFilename());
+ }
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (! info_ptr) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ throw GImage::Error("Unable to initialize PNG encoder.", out.getFilename());
+ }
+
+ //setup libpng write handler so can use BinaryOutput
+ png_set_write_fn(png_ptr, (void*)&out, png_write_data, png_flush_data);
+ png_color_8_struct sig_bit;
+
+ switch (m_channels) {
+ case 1:
+ png_set_IHDR(png_ptr, info_ptr, m_width, m_height, 8, PNG_COLOR_TYPE_GRAY,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ sig_bit.red = 0;
+ sig_bit.green = 0;
+ sig_bit.blue = 0;
+ sig_bit.alpha = 0;
+ sig_bit.gray = 8;
+ break;
+
+ case 3:
+ png_set_IHDR(png_ptr, info_ptr, m_width, m_height, 8, PNG_COLOR_TYPE_RGB,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ sig_bit.red = 8;
+ sig_bit.green = 8;
+ sig_bit.blue = 8;
+ sig_bit.alpha = 0;
+ sig_bit.gray = 0;
+ break;
+
+ case 4:
+ png_set_IHDR(png_ptr, info_ptr, m_width, m_height, 8, PNG_COLOR_TYPE_RGBA,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ sig_bit.red = 8;
+ sig_bit.green = 8;
+ sig_bit.blue = 8;
+ sig_bit.alpha = 8;
+ sig_bit.gray = 0;
+ break;
+
+ default:
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ throw GImage::Error("Unsupported number of channels for PNG.", out.getFilename());
+ }
+
+
+ png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+ //write the png header
+ png_write_info(png_ptr, info_ptr);
+
+ png_bytepp row_pointers = new png_bytep[m_height];
+
+ for (int i=0; i < m_height; ++i) {
+ row_pointers[i] = (png_bytep)&m_byte[m_width * m_channels * i];
+ }
+
+ png_write_image(png_ptr, row_pointers);
+
+ png_write_end(png_ptr, info_ptr);
+
+ delete[] row_pointers;
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+}
+
+
+void GImage::decodePNG(
+ BinaryInput& input) {
+
+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_error, png_warning);
+ if (png_ptr == NULL) {
+ throw GImage::Error("Unable to initialize PNG decoder.", input.getFilename());
+ }
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ throw GImage::Error("Unable to initialize PNG decoder.", input.getFilename());
+ }
+
+ png_infop end_info = png_create_info_struct(png_ptr);
+ if (end_info == NULL) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ throw GImage::Error("Unable to initialize PNG decoder.", input.getFilename());
+ }
+
+ // now that the libpng structures are setup, change the error handlers and read routines
+ // to use G3D functions so that BinaryInput can be used.
+
+ png_set_read_fn(png_ptr, (png_voidp)&input, png_read_data);
+
+ // read in sequentially so that three copies of the file are not in memory at once
+ png_read_info(png_ptr, info_ptr);
+
+ png_uint_32 png_width, png_height;
+ int bit_depth, color_type, interlace_type;
+ // this will validate the data it extracts from info_ptr
+ png_get_IHDR(png_ptr, info_ptr, &png_width, &png_height, &bit_depth, &color_type,
+ &interlace_type, int_p_NULL, int_p_NULL);
+
+ if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ throw GImage::Error("Unsupported PNG color type - PNG_COLOR_TYPE_GRAY_ALPHA.", input.getFilename());
+ }
+
+ m_width = static_cast<uint32>(png_width);
+ m_height = static_cast<uint32>(png_height);
+
+ //swap bytes of 16 bit files to least significant byte first
+ png_set_swap(png_ptr);
+
+ png_set_strip_16(png_ptr);
+
+ //Expand paletted colors into true RGB triplets
+ if (color_type == PNG_COLOR_TYPE_PALETTE) {
+ png_set_palette_to_rgb(png_ptr);
+ }
+
+ //Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel
+ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
+ png_set_gray_1_2_4_to_8(png_ptr);
+ }
+
+ //Expand paletted or RGB images with transparency to full alpha channels
+ //so the data will be available as RGBA quartets.
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ png_set_tRNS_to_alpha(png_ptr);
+ }
+
+ // Fix sub-8 bit_depth to 8bit
+ if (bit_depth < 8) {
+ png_set_packing(png_ptr);
+ }
+
+ if ((color_type == PNG_COLOR_TYPE_RGBA) ||
+ ((color_type == PNG_COLOR_TYPE_PALETTE) && (png_ptr->num_trans > 0)) ) {
+
+ m_channels = 4;
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * 4);
+
+ } else if ((color_type == PNG_COLOR_TYPE_RGB) ||
+ (color_type == PNG_COLOR_TYPE_PALETTE)) {
+
+ m_channels = 3;
+ m_byte = (uint8*)System::malloc(m_width * m_height * 3);
+
+ } else if (color_type == PNG_COLOR_TYPE_GRAY) {
+
+ m_channels = 1;
+
+ // Round up to the nearest 8 rows to avoid a bug in the PNG decoder
+ int h = iCeil(m_height / 8) * 8;
+ int sz = m_width * h;
+ m_byte = (uint8*)m_memMan->alloc(sz);
+
+ } else {
+ throw GImage::Error("Unsupported PNG bit-depth or type.", input.getFilename());
+ }
+
+ //since we are reading row by row, required to handle interlacing
+ uint32 number_passes = png_set_interlace_handling(png_ptr);
+
+ png_read_update_info(png_ptr, info_ptr);
+
+ for (uint32 pass = 0; pass < number_passes; ++pass) {
+ for (uint32 y = 0; y < (uint32)m_height; ++y) {
+ png_bytep rowPointer = &m_byte[m_width * m_channels * y];
+ png_read_rows(png_ptr, &rowPointer, png_bytepp_NULL, 1);
+ }
+ }
+
+// png_read_image(png_ptr, &_byte);
+ png_read_end(png_ptr, info_ptr);
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+}
+
+}
diff --git a/dep/src/g3dlite/GImage_ppm.cpp b/dep/src/g3dlite/GImage_ppm.cpp
new file mode 100644
index 00000000000..28f8cdf9ab0
--- /dev/null
+++ b/dep/src/g3dlite/GImage_ppm.cpp
@@ -0,0 +1,217 @@
+/**
+ @file GImage_ppm.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-05-27
+ @edited 2006-05-10
+ */
+#include "G3D/platform.h"
+#include "G3D/GImage.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/TextInput.h"
+#include "G3D/TextOutput.h"
+#include "G3D/Log.h"
+
+namespace G3D {
+
+void GImage::encodePPMASCII(
+ BinaryOutput& out) const {
+
+ TextOutput::Settings ppmOptions;
+ ppmOptions.convertNewlines = false;
+ ppmOptions.numColumns = 70;
+ ppmOptions.wordWrap = TextOutput::Settings::WRAP_WITHOUT_BREAKING;
+ TextOutput ppm(ppmOptions);
+
+ switch (m_channels) {
+ case 1:
+ {
+ ppm.printf("P2\n%d %d\n255\n", m_width, m_height);
+
+ const Color1uint8* c = this->pixel1();
+ // Insert newlines every 70 characters max
+ for (uint32 i = 0; i < (uint32)(m_width * m_height); ++i) {
+ ppm.printf("%d%c", c[i].value, (i % (70/4) == 0) ? '\n' : ' ');
+ }
+ }
+ break;
+
+ case 3:
+ {
+ ppm.printf("P3\n%d %d\n255\n", m_width, m_height);
+
+ const Color3uint8* c = this->pixel3();
+ // Insert newlines every 70 characters max
+ for (uint32 i = 0; i < (uint32)(m_width * m_height); ++i) {
+ ppm.printf("%d %d %d%c", c[i].r, c[i].g, c[i].b,
+ (i % (70/12) == 0) ?
+ '\n' : ' ');
+ }
+ }
+ break;
+ default:
+ alwaysAssertM(false, "PPM requires either 1 or 3 channels exactly.");
+ }
+
+ const std::string& s = ppm.commitString();
+ out.writeBytes(s.c_str(), s.length());
+}
+
+
+void GImage::encodePPM(
+ BinaryOutput& out) const {
+
+ // http://netpbm.sourceforge.net/doc/ppm.html
+ if (m_channels == 3) {
+ std::string header = format("P6 %d %d 255 ", m_width, m_height);
+ out.writeBytes(header.c_str(), header.size());
+ out.writeBytes(this->pixel3(), m_width * m_height * 3);
+ } else if (m_channels == 1) {
+ std::string header = format("P5 %d %d 255 ", m_width, m_height);
+ out.writeBytes(header.c_str(), header.size());
+ out.writeBytes(this->pixel1(), m_width * m_height);
+ } else {
+ alwaysAssertM(false, "PPM requires either 1 or 3 channels exactly.");
+ }
+}
+
+
+void GImage::decodePPMASCII(
+ BinaryInput& input) {
+
+ int ppmWidth;
+ int ppmHeight;
+
+ double maxColor;
+
+ // Create a TextInput object to parse ascii format
+ // Mixed binary/ascii formats will require more
+
+ const std::string inputStr = input.readString();
+
+ TextInput::Settings ppmOptions;
+ ppmOptions.cppLineComments = false;
+ ppmOptions.otherCommentCharacter = '#';
+ ppmOptions.signedNumbers = true;
+ ppmOptions.singleQuotedStrings = false;
+
+ TextInput ppmInput(TextInput::FROM_STRING, inputStr, ppmOptions);
+
+ //Skip first line in header P#
+ std::string ppmType = ppmInput.readSymbol();
+
+ ppmWidth = (int)ppmInput.readNumber();
+ ppmHeight = (int)ppmInput.readNumber();
+
+ // Everything but a PBM will have a max color value
+ if (ppmType != "P2") {
+ maxColor = ppmInput.readNumber();
+ } else {
+ maxColor = 255;
+ }
+
+ if ((ppmWidth < 0) ||
+ (ppmHeight < 0) ||
+ (maxColor <= 0)) {
+ throw GImage::Error("Invalid PPM Header.", input.getFilename());
+ }
+
+ // I don't think it's proper to scale values less than 255
+ if (maxColor <= 255.0) {
+ maxColor = 255.0;
+ }
+
+ m_width = ppmWidth;
+ m_height = ppmHeight;
+ m_channels = 3;
+ // always scale down to 1 byte per channel
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * 3);
+
+ // Read in the image data. I am not validating if the values match the maxColor
+ // requirements. I only scale if needed to fit within the byte available.
+ for (uint32 i = 0; i < (uint32)(m_width * m_height); ++i) {
+ // read in color and scale to max pixel defined in header
+ // A max color less than 255 might need to be left alone and not scaled.
+ Color3uint8& curPixel = *(pixel3() + i);
+
+ if (ppmType == "P3") {
+ curPixel.r = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
+ curPixel.g = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
+ curPixel.b = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
+ } else if (ppmType == "P2") {
+ uint8 pixel = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
+ curPixel.r = pixel;
+ curPixel.g = pixel;
+ curPixel.b = pixel;
+ } else if (ppmType == "P1") {
+ int pixel = (uint8)(ppmInput.readNumber() * maxColor);
+ curPixel.r = pixel;
+ curPixel.g = pixel;
+ curPixel.b = pixel;
+ }
+ }
+}
+
+/** Consumes whitespace up to and including a number, but not the following character */
+static int scanUInt(BinaryInput& input) {
+ char c = input.readUInt8();
+ while (isWhiteSpace(c)) {
+ c = input.readUInt8();
+ }
+
+ std::string s;
+ s += c;
+ c = input.readUInt8();
+ while (!isWhiteSpace(c)) {
+ s += c;
+ c = input.readUInt8();
+ }
+
+ // Back up one to avoid consuming the last character
+ input.setPosition(input.getPosition() - 1);
+
+ int x;
+ sscanf(s.c_str(), "%d", &x);
+ return x;
+}
+
+
+void GImage::decodePPM(
+ BinaryInput& input) {
+
+ char head[2];
+ int w, h;
+
+ input.readBytes(head, 2);
+ if (head[0] != 'P' || (head[1] != '6') && (head[1] != '5')) {
+ throw GImage::Error("Invalid PPM Header.", input.getFilename());
+ }
+
+ w = scanUInt(input);
+ h = scanUInt(input);
+
+ // Skip the max color specifier
+ scanUInt(input);
+
+ if ((w < 0) ||
+ (h < 0) ||
+ (w > 100000) ||
+ (h > 100000)) {
+ throw GImage::Error("Invalid PPM size in header.", input.getFilename());
+ }
+
+ // Trailing whitespace
+ input.readUInt8();
+
+ if (head[1] == '6') {
+ // 3 channel
+ resize(w, h, 3);
+ input.readBytes(m_byte, m_width * m_height * 3);
+ } else if (head[1] == '5') {
+ // 1 channel
+ resize(w, h, 1);
+ input.readBytes(m_byte, m_width * m_height);
+ }
+}
+
+}
diff --git a/dep/src/g3dlite/GImage_tga.cpp b/dep/src/g3dlite/GImage_tga.cpp
new file mode 100644
index 00000000000..9785f879a1f
--- /dev/null
+++ b/dep/src/g3dlite/GImage_tga.cpp
@@ -0,0 +1,193 @@
+/**
+ @file GImage_tga.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2002-05-27
+ @edited 2009-05-10
+ */
+#include "G3D/platform.h"
+#include "G3D/GImage.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Log.h"
+
+namespace G3D {
+
+void GImage::encodeTGA(
+ BinaryOutput& out) const {
+
+ out.setEndian(G3D_LITTLE_ENDIAN);
+
+ // ID length
+ out.writeUInt8(0);
+
+ // Color map Type
+ out.writeUInt8(0);
+
+ // Type
+ out.writeUInt8(2);
+
+ // Color map
+ out.skip(5);
+
+ // x, y offsets
+ out.writeUInt16(0);
+ out.writeUInt16(0);
+
+ // Width & height
+ out.writeUInt16(m_width);
+ out.writeUInt16(m_height);
+
+ // Color depth
+ if (m_channels == 1) {
+ // Force RGB mode
+ out.writeUInt8(8 * 3);
+ } else {
+ out.writeUInt8(8 * m_channels);
+ }
+
+ // Image descriptor
+ if (m_channels < 4) {
+ // 0 alpha bits
+ out.writeUInt8(0);
+ } else {
+ // 8 alpha bits
+ out.writeUInt8(8);
+ }
+
+ // Image ID (zero length)
+
+ if (m_channels == 1) {
+ // Pixels are upside down in BGR format.
+ for (int y = m_height - 1; y >= 0; --y) {
+ for (int x = 0; x < m_width; ++x) {
+ uint8 p = (m_byte[(y * m_width + x)]);
+ out.writeUInt8(p);
+ out.writeUInt8(p);
+ out.writeUInt8(p);
+ }
+ }
+ } else if (m_channels == 3) {
+ // Pixels are upside down in BGR format.
+ for (int y = m_height - 1; y >= 0; --y) {
+ for (int x = 0; x < m_width; ++x) {
+ uint8* p = &(m_byte[3 * (y * m_width + x)]);
+ out.writeUInt8(p[2]);
+ out.writeUInt8(p[1]);
+ out.writeUInt8(p[0]);
+ }
+ }
+ } else {
+ // Pixels are upside down in BGRA format.
+ for (int y = m_height - 1; y >= 0; --y) {
+ for (int x = 0; x < m_width; ++x) {
+ uint8* p = &(m_byte[4 * (y * m_width + x)]);
+ out.writeUInt8(p[2]);
+ out.writeUInt8(p[1]);
+ out.writeUInt8(p[0]);
+ out.writeUInt8(p[3]);
+ }
+ }
+ }
+
+ // Write "TRUEVISION-XFILE " 18 bytes from the end
+ // (with null termination)
+ out.writeString("TRUEVISION-XFILE ");
+}
+
+
+void GImage::decodeTGA(
+ BinaryInput& input) {
+
+ // This is a simple TGA loader that can handle uncompressed
+ // truecolor TGA files (TGA type 2).
+ // Verify this is a TGA file by looking for the TRUEVISION tag.
+ int pos = input.getPosition();
+ input.setPosition(input.size() - 18);
+ std::string tag = input.readString(16);
+ if (tag != "TRUEVISION-XFILE") {
+ throw Error("Not a TGA file", input.getFilename());
+ }
+
+ input.setPosition(pos);
+
+ int IDLength = input.readUInt8();
+ int colorMapType = input.readUInt8();
+ int imageType = input.readUInt8();
+
+ (void)colorMapType;
+
+ // 2 is the type supported by this routine.
+ if (imageType != 2) {
+ throw Error("TGA images must be type 2 (Uncompressed truecolor)", input.getFilename());
+ }
+
+ // Color map specification
+ input.skip(5);
+
+ // Image specification
+
+ // Skip x and y offsets
+ input.skip(4);
+
+ m_width = input.readInt16();
+ m_height = input.readInt16();
+
+ int colorDepth = input.readUInt8();
+
+ if ((colorDepth != 24) && (colorDepth != 32)) {
+ throw Error("TGA files must be 24 or 32 bit.", input.getFilename());
+ }
+
+ if (colorDepth == 32) {
+ m_channels = 4;
+ } else {
+ m_channels = 3;
+ }
+
+ // Image descriptor contains overlay data as well
+ // as data indicating where the origin is
+ int imageDescriptor = input.readUInt8();
+ (void)imageDescriptor;
+
+ // Image ID
+ input.skip(IDLength);
+
+ m_byte = (uint8*)m_memMan->alloc(m_width * m_height * m_channels);
+ debugAssert(m_byte);
+
+ // Pixel data
+ int x;
+ int y;
+
+ if (m_channels == 3) {
+ for (y = m_height - 1; y >= 0; --y) {
+ for (x = 0; x < m_width; ++x) {
+ int b = input.readUInt8();
+ int g = input.readUInt8();
+ int r = input.readUInt8();
+
+ int i = (x + y * m_width) * 3;
+ m_byte[i + 0] = r;
+ m_byte[i + 1] = g;
+ m_byte[i + 2] = b;
+ }
+ }
+ } else {
+ for (y = m_height - 1; y >= 0; --y) {
+ for (x = 0; x < m_width; ++x) {
+ int b = input.readUInt8();
+ int g = input.readUInt8();
+ int r = input.readUInt8();
+ int a = input.readUInt8();
+
+ int i = (x + y * m_width) * 4;
+ m_byte[i + 0] = r;
+ m_byte[i + 1] = g;
+ m_byte[i + 2] = b;
+ m_byte[i + 3] = a;
+ }
+ }
+ }
+}
+
+}
diff --git a/dep/src/g3dlite/GLight.cpp b/dep/src/g3dlite/GLight.cpp
new file mode 100644
index 00000000000..37c8054ff3d
--- /dev/null
+++ b/dep/src/g3dlite/GLight.cpp
@@ -0,0 +1,267 @@
+/**
+ @file GLight.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-11-12
+ @edited 2009-11-16
+*/
+#include "G3D/GLight.h"
+#include "G3D/Sphere.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+GLight::GLight(const Any& any) {
+ any.verifyName("GLight");
+
+ if (any.type() == Any::TABLE) {
+ *this = GLight();
+ for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
+ const std::string& key = toLower(it->key);
+ if (key == "position") {
+ position = it->value;
+ } else if (key == "rightdirection") {
+ rightDirection = it->value;
+ } else if (key == "spotdirection") {
+ spotDirection = it->value;
+ } else if (key == "spotcutoff") {
+ spotCutoff = it->value.number();
+ } else if (key == "spotsquare") {
+ spotSquare = it->value.boolean();
+ } else if (key == "attenuation") {
+ attenuation[0] = it->value[0].number();
+ attenuation[1] = it->value[1].number();
+ attenuation[2] = it->value[2].number();
+ } else if (key == "color") {
+ color = it->value;
+ } else if (key == "enabled") {
+ enabled = it->value.boolean();
+ } else if (key == "specular") {
+ specular = it->value.boolean();
+ } else if (key == "diffuse") {
+ diffuse = it->value.boolean();
+ } else {
+ any.verify(false, "Illegal key: " + it->key);
+ }
+ }
+ } else if (toLower(any.name()) == "glight::directional") {
+
+ *this = directional(any[0], any[1],
+ (any.size() > 2) ? any[2] : Any(true),
+ (any.size() > 3) ? any[3] : Any(true));
+
+ } else if (toLower(any.name()) == "glight::point") {
+
+ *this = point(any[0], any[1],
+ (any.size() > 2) ? any[2] : Any(1),
+ (any.size() > 3) ? any[3] : Any(0),
+ (any.size() > 4) ? any[4] : Any(0.5f),
+ (any.size() > 5) ? any[5] : Any(true),
+ (any.size() > 6) ? any[6] : Any(true));
+
+ } else if (toLower(any.name()) == "glight::spot") {
+
+ *this = spot(any[0], any[1], any[2], any[3],
+ (any.size() > 4) ? any[4] : Any(1),
+ (any.size() > 5) ? any[5] : Any(0),
+ (any.size() > 6) ? any[6] : Any(0.5f),
+ (any.size() > 7) ? any[5] : Any(true),
+ (any.size() > 8) ? any[6] : Any(true));
+ } else {
+ any.verify(false, "Unrecognized name");
+ }
+}
+
+
+GLight::operator Any() const {
+ Any a(Any::TABLE, "GLight");
+ a.set("position", position.operator Any());
+ a.set("rightDirection", rightDirection.operator Any());
+ a.set("spotDirection", spotDirection.operator Any());
+ a.set("spotCutoff", spotCutoff);
+ a.set("spotSquare", spotSquare);
+
+ Any att(Any::ARRAY);
+ att.append(attenuation[0], attenuation[1], attenuation[2]);
+ a.set("attenuation", att);
+ a.set("color", color.operator Any());
+ a.set("enabled", enabled);
+ a.set("specular", specular);
+ a.set("diffuse", diffuse);
+ return a;
+}
+
+
+GLight::GLight() :
+ position(0, 0, 0, 0),
+ rightDirection(0,0,0),
+ spotDirection(0, 0, -1),
+ spotCutoff(180),
+ spotSquare(false),
+ color(Color3::white()),
+ enabled(false),
+ specular(true),
+ diffuse(true) {
+
+ attenuation[0] = 1.0;
+ attenuation[1] = 0.0;
+ attenuation[2] = 0.0;
+}
+
+
+GLight GLight::directional(const Vector3& toLight, const Color3& color, bool s, bool d) {
+ GLight L;
+ L.position = Vector4(toLight.direction(), 0);
+ L.color = color;
+ L.specular = s;
+ L.diffuse = d;
+ return L;
+}
+
+
+GLight GLight::point(const Vector3& pos, const Color3& color, float constAtt, float linAtt, float quadAtt, bool s, bool d) {
+ GLight L;
+ L.position = Vector4(pos, 1);
+ L.color = color;
+ L.attenuation[0] = constAtt;
+ L.attenuation[1] = linAtt;
+ L.attenuation[2] = quadAtt;
+ L.specular = s;
+ L.diffuse = d;
+ return L;
+}
+
+
+GLight GLight::spot(const Vector3& pos, const Vector3& pointDirection, float cutOffAngleDegrees, const Color3& color, float constAtt, float linAtt, float quadAtt, bool s, bool d) {
+ GLight L;
+ L.position = Vector4(pos, 1.0f);
+ L.spotDirection = pointDirection.direction();
+ debugAssert(cutOffAngleDegrees <= 90);
+ L.spotCutoff = cutOffAngleDegrees;
+ L.color = color;
+ L.attenuation[0] = constAtt;
+ L.attenuation[1] = linAtt;
+ L.attenuation[2] = quadAtt;
+ L.specular = s;
+ L.diffuse = d;
+ return L;
+}
+
+
+bool GLight::operator==(const GLight& other) const {
+ return (position == other.position) &&
+ (rightDirection == other.rightDirection) &&
+ (spotDirection == other.spotDirection) &&
+ (spotCutoff == other.spotCutoff) &&
+ (spotSquare == other.spotSquare) &&
+ (attenuation[0] == other.attenuation[0]) &&
+ (attenuation[1] == other.attenuation[1]) &&
+ (attenuation[2] == other.attenuation[2]) &&
+ (color == other.color) &&
+ (enabled == other.enabled) &&
+ (specular == other.specular) &&
+ (diffuse == other.diffuse);
+}
+
+
+bool GLight::operator!=(const GLight& other) const {
+ return !(*this == other);
+}
+
+
+Sphere GLight::effectSphere(float cutoff) const {
+ if (position.w == 0) {
+ // Directional light
+ return Sphere(Vector3::zero(), finf());
+ } else {
+ // Avoid divide by zero
+ cutoff = max(cutoff, 0.00001f);
+ float maxIntensity = max(color.r, max(color.g, color.b));
+
+ float radius = finf();
+
+ if (attenuation[2] != 0) {
+
+ // Solve I / attenuation.dot(1, r, r^2) < cutoff for r
+ //
+ // a[0] + a[1] r + a[2] r^2 > I/cutoff
+ //
+
+ float a = attenuation[2];
+ float b = attenuation[1];
+ float c = attenuation[0] - maxIntensity / cutoff;
+
+ float discrim = square(b) - 4 * a * c;
+
+ if (discrim >= 0) {
+ discrim = sqrt(discrim);
+
+ float r1 = (-b + discrim) / (2 * a);
+ float r2 = (-b - discrim) / (2 * a);
+
+ if (r1 < 0) {
+ if (r2 > 0) {
+ radius = r2;
+ }
+ } else if (r2 > 0) {
+ radius = min(r1, r2);
+ } else {
+ radius = r1;
+ }
+ }
+
+ } else if (attenuation[1] != 0) {
+
+ // Solve I / attenuation.dot(1, r) < cutoff for r
+ //
+ // r * a[1] + a[0] = I / cutoff
+ // r = (I / cutoff - a[0]) / a[1]
+
+ float radius = (maxIntensity / cutoff - attenuation[0]) / attenuation[1];
+ radius = max(radius, 0.0f);
+ }
+
+ return Sphere(position.xyz(), radius);
+
+ }
+}
+
+
+CoordinateFrame GLight::frame() const {
+ CoordinateFrame f;
+ if (rightDirection == Vector3::zero()) {
+ // No specified right direction; choose one automatically
+ if (position.w == 0) {
+ // Directional light
+ f.lookAt(-position.xyz());
+ } else {
+ // Spot light
+ f.lookAt(spotDirection);
+ }
+ } else {
+ const Vector3& Z = -spotDirection.direction();
+ Vector3 X = rightDirection.direction();
+
+ // Ensure the vectors are not too close together
+ while (abs(X.dot(Z)) > 0.9f) {
+ X = Vector3::random();
+ }
+
+ // Ensure perpendicular
+ X -= Z * Z.dot(X);
+ const Vector3& Y = Z.cross(X);
+
+ f.rotation.setColumn(Vector3::X_AXIS, X);
+ f.rotation.setColumn(Vector3::Y_AXIS, Y);
+ f.rotation.setColumn(Vector3::Z_AXIS, Z);
+ }
+ f.translation = position.xyz();
+
+ return f;
+}
+
+
+} // G3D
diff --git a/dep/src/g3dlite/GThread.cpp b/dep/src/g3dlite/GThread.cpp
new file mode 100644
index 00000000000..607e4b3572f
--- /dev/null
+++ b/dep/src/g3dlite/GThread.cpp
@@ -0,0 +1,229 @@
+/**
+ @file GThread.cpp
+
+ GThread class.
+
+ @created 2005-09-24
+ @edited 2005-10-22
+ */
+
+#include "G3D/GThread.h"
+#include "G3D/System.h"
+#include "G3D/debugAssert.h"
+#include "G3D/GMutex.h"
+
+namespace G3D {
+
+namespace _internal {
+
+class BasicThread: public GThread {
+public:
+ BasicThread(const std::string& name, void (*proc)(void*), void* param):
+ GThread(name), m_wrapperProc(proc), m_param(param) { }
+protected:
+ virtual void threadMain() {
+ m_wrapperProc(m_param);
+ }
+
+private:
+ void (*m_wrapperProc)(void*);
+
+ void* m_param;
+};
+
+} // namespace _internal
+
+
+GThread::GThread(const std::string& name):
+ m_status(STATUS_CREATED),
+ m_name(name) {
+
+#ifdef G3D_WIN32
+ m_event = NULL;
+#endif
+
+ // system-independent clear of handle
+ System::memset(&m_handle, 0, sizeof(m_handle));
+}
+
+GThread::~GThread() {
+#ifdef _MSC_VER
+# pragma warning( push )
+# pragma warning( disable : 4127 )
+#endif
+ alwaysAssertM(m_status != STATUS_RUNNING, "Deleting thread while running.");
+#ifdef _MSC_VER
+# pragma warning( pop )
+#endif
+
+#ifdef G3D_WIN32
+ if (m_event) {
+ ::CloseHandle(m_event);
+ }
+#endif
+}
+
+GThreadRef GThread::create(const std::string& name, void (*proc)(void*), void* param) {
+ return new _internal::BasicThread(name, proc, param);
+}
+
+
+bool GThread::started() const {
+ return m_status != STATUS_CREATED;
+}
+
+bool GThread::start(SpawnBehavior behavior) {
+
+ debugAssertM(! started(), "Thread has already executed.");
+ if (started()) {
+ return false;
+ }
+
+ m_status = STATUS_STARTED;
+
+ if (behavior == USE_CURRENT_THREAD) {
+ // Run on this thread
+ m_status = STATUS_RUNNING;
+ threadMain();
+ m_status = STATUS_COMPLETED;
+ return true;
+ }
+
+# ifdef G3D_WIN32
+ DWORD threadId;
+
+ m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ debugAssert(m_event);
+
+ m_handle = ::CreateThread(NULL, 0, &internalThreadProc, this, 0, &threadId);
+
+ if (m_handle == NULL) {
+ ::CloseHandle(m_event);
+ m_event = NULL;
+ }
+
+ return (m_handle != NULL);
+# else
+ if (!pthread_create(&m_handle, NULL, &internalThreadProc, this)) {
+ return true;
+ } else {
+ // system-independent clear of handle
+ System::memset(&m_handle, 0, sizeof(m_handle));
+
+ return false;
+ }
+# endif
+}
+
+void GThread::terminate() {
+ if (m_handle) {
+# ifdef G3D_WIN32
+ ::TerminateThread(m_handle, 0);
+# else
+ pthread_kill(m_handle, SIGSTOP);
+# endif
+ // system-independent clear of handle
+ System::memset(&m_handle, 0, sizeof(m_handle));
+ }
+}
+
+
+bool GThread::running() const{
+ return (m_status == STATUS_RUNNING);
+}
+
+
+bool GThread::completed() const {
+ return (m_status == STATUS_COMPLETED);
+}
+
+
+void GThread::waitForCompletion() {
+ if (m_status == STATUS_COMPLETED) {
+ // Must be done
+ return;
+ }
+
+# ifdef G3D_WIN32
+ debugAssert(m_event);
+ ::WaitForSingleObject(m_event, INFINITE);
+# else
+ debugAssert(m_handle);
+ pthread_join(m_handle, NULL);
+# endif
+}
+
+
+#ifdef G3D_WIN32
+DWORD WINAPI GThread::internalThreadProc(LPVOID param) {
+ GThread* current = reinterpret_cast<GThread*>(param);
+ debugAssert(current->m_event);
+ current->m_status = STATUS_RUNNING;
+ current->threadMain();
+ current->m_status = STATUS_COMPLETED;
+ ::SetEvent(current->m_event);
+ return 0;
+}
+#else
+void* GThread::internalThreadProc(void* param) {
+ GThread* current = reinterpret_cast<GThread*>(param);
+ current->m_status = STATUS_RUNNING;
+ current->threadMain();
+ current->m_status = STATUS_COMPLETED;
+ return (void*)NULL;
+}
+#endif
+
+
+
+//GMutex implementation
+GMutex::GMutex() {
+#ifdef G3D_WIN32
+ ::InitializeCriticalSection(&m_handle);
+#else
+ int ret = pthread_mutexattr_init(&m_attr);
+ debugAssert(ret == 0);
+ ret = pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE);
+ debugAssert(ret == 0);
+ ret = pthread_mutex_init(&m_handle, &m_attr);
+ debugAssert(ret == 0);
+#endif
+}
+
+GMutex::~GMutex() {
+ //TODO: Debug check for locked
+#ifdef G3D_WIN32
+ ::DeleteCriticalSection(&m_handle);
+#else
+ int ret = pthread_mutex_destroy(&m_handle);
+ debugAssert(ret == 0);
+ ret = pthread_mutexattr_destroy(&m_attr);
+ debugAssert(ret == 0);
+#endif
+}
+
+bool GMutex::tryLock() {
+#ifdef G3D_WIN32
+ return (::TryEnterCriticalSection(&m_handle) != 0);
+#else
+ return (pthread_mutex_trylock(&m_handle) == 0);
+#endif
+}
+
+void GMutex::lock() {
+#ifdef G3D_WIN32
+ ::EnterCriticalSection(&m_handle);
+#else
+ pthread_mutex_lock(&m_handle);
+#endif
+}
+
+void GMutex::unlock() {
+#ifdef G3D_WIN32
+ ::LeaveCriticalSection(&m_handle);
+#else
+ pthread_mutex_unlock(&m_handle);
+#endif
+}
+
+} // namespace G3D
diff --git a/dep/src/g3dlite/GUniqueID.cpp b/dep/src/g3dlite/GUniqueID.cpp
new file mode 100644
index 00000000000..84c853e0e31
--- /dev/null
+++ b/dep/src/g3dlite/GUniqueID.cpp
@@ -0,0 +1,78 @@
+/**
+ @file GUniqueID.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ */
+#include "G3D/GUniqueID.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/TextInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/TextOutput.h"
+#include "G3D/NetworkDevice.h"
+
+namespace G3D {
+
+void GUniqueID::serialize(BinaryOutput& b) const {
+ b.writeUInt64(id);
+}
+
+
+void GUniqueID::deserialize(BinaryInput& b) {
+ id = b.readUInt64();
+}
+
+void GUniqueID::serialize(TextOutput& t) const {
+ t.writeSymbol("(");
+ t.writeNumber((double)(id >> 32));
+ t.writeNumber((double)(id & 0xFFFFFFFF));
+ t.writeSymbol(")");
+}
+
+void GUniqueID::deserialize(TextInput& t) {
+ t.readSymbol("(");
+ id = (((uint64)t.readNumber()) << 32) + (uint64)t.readNumber();
+ t.readSymbol(")");
+}
+
+
+GUniqueID GUniqueID::create(uint16 tag) {
+ static uint64 counter = 0;
+ static uint64 systemID = 0;
+
+ if (systemID == 0) {
+ // Create a unique ID for this machine/program instance
+
+ // TODO: see ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr)
+ Array<NetAddress> addr;
+ NetworkDevice::instance()->localHostAddresses(addr);
+ if (addr.size() > 0) {
+ systemID |= addr[0].ip();
+ }
+
+ union {
+ float64 ft;
+ uint64 ut;
+ };
+ ft = System::time();
+ systemID = ut << 22;
+ systemID ^= ((uint64)iRandom(0, 32768)) << 8;
+
+ systemID &= ~((uint64)1023 << 54);
+
+ // Ensure that the systemID is non-zero (vanishingly small probability)
+ if (systemID == 0) {
+ systemID = 1;
+ }
+ }
+
+ // No need for modulo; we'll all be dead before this counter
+ // overflows 54 bits
+ ++counter;
+
+ GUniqueID i;
+
+ i.id = (((uint64)(tag & 1023)) << 54) | (counter ^ systemID);
+
+ return i;
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/Image1.cpp b/dep/src/g3dlite/Image1.cpp
new file mode 100644
index 00000000000..a61f7faa633
--- /dev/null
+++ b/dep/src/g3dlite/Image1.cpp
@@ -0,0 +1,224 @@
+/**
+ @file Image1.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+
+#include "G3D/Image1.h"
+#include "G3D/Image1uint8.h"
+#include "G3D/GImage.h"
+#include "G3D/Color4.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/Color1.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/ImageFormat.h"
+
+namespace G3D {
+
+Image1::Image1(int w, int h, WrapMode wrap) : Map2D<Color1, Color1>(w, h, wrap) {
+ setAll(Color1(0.0f));
+}
+
+
+Image1::Ref Image1::fromGImage(const GImage& im, WrapMode wrap) {
+ switch (im.channels()) {
+ case 1:
+ return fromArray(im.pixel1(), im.width(), im.height(), wrap);
+
+ case 3:
+ return fromArray(im.pixel3(), im.width(), im.height(), wrap);
+
+ case 4:
+ return fromArray(im.pixel4(), im.width(), im.height(), wrap);
+
+ default:
+ debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
+ return NULL;
+ }
+}
+
+
+Image1::Ref Image1::fromImage1uint8(const ReferenceCountedPointer<Image1uint8>& im) {
+ Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
+ out->resize(im->width(), im->height());
+
+ int N = im->width() * im->height();
+ const Color1uint8* src = reinterpret_cast<Color1uint8*>(im->getCArray());
+ for (int i = 0; i < N; ++i) {
+ out->data[i] = Color1(src[i]);
+ }
+
+ return out;
+}
+
+
+Image1::Ref Image1::createEmpty(int width, int height, WrapMode wrap) {
+ return new Type(width, height, wrap);
+}
+
+
+Image1::Ref Image1::createEmpty(WrapMode wrap) {
+ return createEmpty(0, 0, wrap);
+}
+
+
+Image1::Ref Image1::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
+ Ref out = createEmpty(wrap);
+ out->load(filename, fmt);
+ return out;
+}
+
+
+void Image1::load(const std::string& filename, GImage::Format fmt) {
+ copyGImage(GImage(filename, fmt));
+ setChanged(true);
+}
+
+
+Image1::Ref Image1::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1::Ref Image1::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1::Ref Image1::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1::Ref Image1::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1::Ref Image1::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1::Ref Image1::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+void Image1::copyGImage(const GImage& im) {
+ switch (im.channels()) {
+ case 1:
+ copyArray(im.pixel1(), im.width(), im.height());
+ break;
+
+ case 3:
+ copyArray(im.pixel3(), im.width(), im.height());
+ break;
+
+ case 4:
+ copyArray(im.pixel4(), im.width(), im.height());
+ break;
+ }
+}
+
+
+void Image1::copyArray(const Color3uint8* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color1* dst = data.getCArray();
+ // Convert int8 -> float
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1(Color3(src[i]).average());
+ }
+}
+
+
+void Image1::copyArray(const Color4uint8* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color1* dst = data.getCArray();
+
+ // Strip alpha and convert
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1(Color3(src[i].rgb()).average());
+ }
+}
+
+
+void Image1::copyArray(const Color1* src, int w, int h) {
+ resize(w, h);
+ System::memcpy(getCArray(), src, w * h * sizeof(Color1));
+}
+
+
+void Image1::copyArray(const Color4* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color1* dst = data.getCArray();
+
+ // Strip alpha
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1(src[i].rgb().average());
+ }
+}
+
+
+void Image1::copyArray(const Color1uint8* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color1* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i]= Color1(src[i]);
+ }
+}
+
+
+void Image1::copyArray(const Color3* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color1* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1(src[i].average());
+ }
+}
+
+
+/** Saves in any of the formats supported by G3D::GImage. */
+void Image1::save(const std::string& filename, GImage::Format fmt) {
+ GImage im(width(), height(), 1);
+
+ int N = im.width() * im.height();
+ Color1uint8* dst = im.pixel1();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1uint8(data[i]);
+ }
+
+ im.save(filename, fmt);
+}
+
+
+const ImageFormat* Image1::format() const {
+ return ImageFormat::L32F();
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/Image1uint8.cpp b/dep/src/g3dlite/Image1uint8.cpp
new file mode 100644
index 00000000000..de2cbbc130b
--- /dev/null
+++ b/dep/src/g3dlite/Image1uint8.cpp
@@ -0,0 +1,212 @@
+/**
+ @file Image1uint8.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2008-01-13
+*/
+
+#include "G3D/Image1uint8.h"
+#include "G3D/Image3uint8.h"
+#include "G3D/Image1.h"
+#include "G3D/GImage.h"
+#include "G3D/Color1.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/Color4.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/ImageFormat.h"
+
+namespace G3D {
+
+Image1uint8::Image1uint8(int w, int h, WrapMode wrap) : Map2D<Color1uint8, Color1>(w, h, wrap) {
+ setAll(Color1uint8(0));
+}
+
+
+Image1uint8::Ref Image1uint8::fromImage3uint8(const ReferenceCountedPointer<class Image3uint8>& im) {
+ return fromArray(im->getCArray(), im->width(), im->height(), im->wrapMode());
+}
+
+
+Image1uint8::Ref Image1uint8::fromGImage(const GImage& im, WrapMode wrap) {
+ switch (im.channels()) {
+ case 1:
+ return fromArray(im.pixel1(), im.width(), im.height(), wrap);
+
+ case 3:
+ return fromArray(im.pixel3(), im.width(), im.height(), wrap);
+
+ case 4:
+ return fromArray(im.pixel4(), im.width(), im.height(), wrap);
+
+ default:
+ debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
+ return NULL;
+ }
+}
+
+
+Image1uint8::Ref Image1uint8::fromImage1(const ReferenceCountedPointer<Image1>& im) {
+ Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
+ out->copyArray(im->getCArray(), im->width(), im->height());
+
+ return out;
+}
+
+
+Image1uint8::Ref Image1uint8::createEmpty(int width, int height, WrapMode wrap) {
+ return new Type(width, height, wrap);
+}
+
+
+Image1uint8::Ref Image1uint8::createEmpty(WrapMode wrap) {
+ return createEmpty(0, 0, wrap);
+}
+
+
+Image1uint8::Ref Image1uint8::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
+ Ref out = createEmpty(wrap);
+ out->load(filename, fmt);
+ return out;
+}
+
+
+Image1uint8::Ref Image1uint8::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1uint8::Ref Image1uint8::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1uint8::Ref Image1uint8::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1uint8::Ref Image1uint8::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1uint8::Ref Image1uint8::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image1uint8::Ref Image1uint8::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+void Image1uint8::load(const std::string& filename, GImage::Format fmt) {
+ copyGImage(GImage(filename, fmt));
+ setChanged(true);
+}
+
+
+void Image1uint8::copyGImage(const GImage& im) {
+ switch (im.channels()) {
+ case 1:
+ copyArray(im.pixel1(), im.width(), im.height());
+ break;
+
+ case 3:
+ copyArray(im.pixel3(), im.width(), im.height());
+ break;
+
+ case 4:
+ copyArray(im.pixel4(), im.width(), im.height());
+ break;
+ }
+}
+
+
+void Image1uint8::copyArray(const Color3uint8* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color1uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].value = (src[i].r + src[i].g + src[i].b) / 3;
+ }
+}
+
+void Image1uint8::copyArray(const Color3* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color1uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1uint8(Color1(src[i].average()));
+ }
+}
+
+
+void Image1uint8::copyArray(const Color1uint8* ptr, int w, int h) {
+ resize(w, h);
+ System::memcpy(getCArray(), ptr, w * h);
+}
+
+
+void Image1uint8::copyArray(const Color1* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color1uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1uint8(src[i]);
+ }
+}
+
+
+void Image1uint8::copyArray(const Color4uint8* ptr, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color1uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].value = (ptr[i].r + ptr[i].g + ptr[i].b) / 3;
+ }
+}
+
+
+void Image1uint8::copyArray(const Color4* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color1uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color1uint8(Color1(src[i].rgb().average()));
+ }
+}
+
+
+/** Saves in any of the formats supported by G3D::GImage. */
+void Image1uint8::save(const std::string& filename, GImage::Format fmt) {
+ GImage im(width(), height(), 1);
+ System::memcpy(im.byte(), getCArray(), width() * height());
+ im.save(filename, fmt);
+}
+
+
+const ImageFormat* Image1uint8::format() const {
+ return ImageFormat::L8();
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/Image3.cpp b/dep/src/g3dlite/Image3.cpp
new file mode 100644
index 00000000000..0d85bdf45da
--- /dev/null
+++ b/dep/src/g3dlite/Image3.cpp
@@ -0,0 +1,225 @@
+/**
+ @file Image3.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2007-01-31
+*/
+
+
+#include "G3D/Image3.h"
+#include "G3D/Image3uint8.h"
+#include "G3D/GImage.h"
+#include "G3D/Color4.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/Color1.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/ImageFormat.h"
+
+namespace G3D {
+
+Image3::Image3(int w, int h, WrapMode wrap) : Map2D<Color3, Color3>(w, h, wrap) {
+ setAll(Color3::black());
+}
+
+
+Image3::Ref Image3::fromGImage(const GImage& im, WrapMode wrap) {
+ switch (im.channels()) {
+ case 1:
+ return fromArray(im.pixel1(), im.width(), im.height(), wrap);
+
+ case 3:
+ return fromArray(im.pixel3(), im.width(), im.height(), wrap);
+
+ case 4:
+ return fromArray(im.pixel4(), im.width(), im.height(), wrap);
+
+ default:
+ debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
+ return NULL;
+ }
+}
+
+
+Image3::Ref Image3::fromImage3uint8(const ReferenceCountedPointer<Image3uint8>& im) {
+ Ref out = createEmpty(im->wrapMode());
+ out->resize(im->width(), im->height());
+
+ int N = im->width() * im->height();
+ const Color3uint8* src = reinterpret_cast<Color3uint8*>(im->getCArray());
+ for (int i = 0; i < N; ++i) {
+ out->data[i] = Color3(src[i]);
+ }
+
+ return out;
+}
+
+
+Image3::Ref Image3::createEmpty(int width, int height, WrapMode wrap) {
+ return new Image3(width, height, wrap);
+}
+
+
+Image3::Ref Image3::createEmpty(WrapMode wrap) {
+ return createEmpty(0, 0, wrap);
+}
+
+
+Image3::Ref Image3::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
+ Ref out = createEmpty(wrap);
+ out->load(filename, fmt);
+ return out;
+}
+
+
+void Image3::load(const std::string& filename, GImage::Format fmt) {
+ copyGImage(GImage(filename, fmt));
+ setChanged(true);
+}
+
+
+Image3::Ref Image3::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3::Ref Image3::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3::Ref Image3::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3::Ref Image3::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3::Ref Image3::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3::Ref Image3::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+void Image3::copyGImage(const GImage& im) {
+ switch (im.channels()) {
+ case 1:
+ copyArray(im.pixel1(), im.width(), im.height());
+ break;
+
+ case 3:
+ copyArray(im.pixel3(), im.width(), im.height());
+ break;
+
+ case 4:
+ copyArray(im.pixel4(), im.width(), im.height());
+ break;
+ }
+}
+
+
+void Image3::copyArray(const Color3uint8* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color3* dst = data.getCArray();
+ // Convert int8 -> float
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color3(src[i]);
+ }
+}
+
+
+void Image3::copyArray(const Color4uint8* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color3* dst = data.getCArray();
+
+ // Strip alpha and convert
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color3(src[i].rgb());
+ }
+}
+
+
+void Image3::copyArray(const Color3* src, int w, int h) {
+ resize(w, h);
+ System::memcpy(getCArray(), src, w * h * sizeof(Color3));
+}
+
+
+void Image3::copyArray(const Color4* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color3* dst = data.getCArray();
+
+ // Strip alpha
+ for (int i = 0; i < N; ++i) {
+ dst[i] = src[i].rgb();
+ }
+}
+
+
+void Image3::copyArray(const Color1uint8* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color3* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = Color1(src[i]).value;
+ }
+}
+
+
+void Image3::copyArray(const Color1* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color3* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = src[i].value;
+ }
+}
+
+
+/** Saves in any of the formats supported by G3D::GImage. */
+void Image3::save(const std::string& filename, GImage::Format fmt) {
+ GImage im(width(), height(), 3);
+
+ int N = im.width() * im.height();
+ Color3uint8* dst = im.pixel3();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color3uint8(data[i]);
+ }
+
+ im.save(filename, fmt);
+}
+
+
+const ImageFormat* Image3::format() const {
+ return ImageFormat::RGB32F();
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/Image3uint8.cpp b/dep/src/g3dlite/Image3uint8.cpp
new file mode 100644
index 00000000000..86595bbd1f6
--- /dev/null
+++ b/dep/src/g3dlite/Image3uint8.cpp
@@ -0,0 +1,225 @@
+/**
+ @file Image3uint8.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2008-01-08
+*/
+
+#include "G3D/Image1uint8.h"
+#include "G3D/Image3uint8.h"
+#include "G3D/Image3.h"
+#include "G3D/GImage.h"
+#include "G3D/Color1.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/Color4.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/ImageFormat.h"
+
+namespace G3D {
+
+Image3uint8::Ref Image3uint8::fromImage1uint8(const ReferenceCountedPointer<class Image1uint8>& im) {
+ return fromArray(im->getCArray(), im->width(), im->height(), im->wrapMode());
+}
+
+
+Image3uint8::Image3uint8(int w, int h, WrapMode wrap) : Map2D<Color3uint8>(w, h, wrap) {
+ setAll(Color3::black());
+}
+
+
+Image3uint8::Ref Image3uint8::fromGImage(const GImage& im, WrapMode wrap) {
+ switch (im.channels()) {
+ case 1:
+ return fromArray(im.pixel1(), im.width(), im.height(), wrap);
+
+ case 3:
+ return fromArray(im.pixel3(), im.width(), im.height(), wrap);
+
+ case 4:
+ return fromArray(im.pixel4(), im.width(), im.height(), wrap);
+
+ default:
+ debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
+ return NULL;
+ }
+}
+
+
+Image3uint8::Ref Image3uint8::fromImage3(const ReferenceCountedPointer<Image3>& im) {
+ Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
+ out->copyArray(im->getCArray(), im->width(), im->height());
+
+ return out;
+}
+
+
+Image3uint8::Ref Image3uint8::createEmpty(int width, int height, WrapMode wrap) {
+ return new Type(width, height, wrap);
+}
+
+
+Image3uint8::Ref Image3uint8::createEmpty(WrapMode wrap) {
+ return createEmpty(0, 0, wrap);
+}
+
+
+Image3uint8::Ref Image3uint8::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
+ Ref out = createEmpty(wrap);
+ out->load(filename, fmt);
+ return out;
+}
+
+
+Image3uint8::Ref Image3uint8::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3uint8::Ref Image3uint8::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3uint8::Ref Image3uint8::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3uint8::Ref Image3uint8::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3uint8::Ref Image3uint8::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image3uint8::Ref Image3uint8::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+void Image3uint8::load(const std::string& filename, GImage::Format fmt) {
+ copyGImage(GImage(filename, fmt));
+ setChanged(true);
+}
+
+
+void Image3uint8::copyGImage(const GImage& im) {
+ switch (im.channels()) {
+ case 1:
+ copyArray(im.pixel1(), im.width(), im.height());
+ break;
+
+ case 3:
+ copyArray(im.pixel3(), im.width(), im.height());
+ break;
+
+ case 4:
+ copyArray(im.pixel4(), im.width(), im.height());
+ break;
+ }
+}
+
+
+void Image3uint8::copyArray(const Color1uint8* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color3uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = src[i].value;
+ }
+}
+
+void Image3uint8::copyArray(const Color1* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color3uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = Color1uint8(src[i]).value;
+ }
+}
+
+
+void Image3uint8::copyArray(const Color3uint8* ptr, int w, int h) {
+ resize(w, h);
+ System::memcpy(getCArray(), ptr, w * h * 3);
+}
+
+
+void Image3uint8::copyArray(const Color3* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color3uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color3uint8(src[i]);
+ }
+}
+
+
+void Image3uint8::copyArray(const Color4uint8* ptr, int w, int h) {
+ resize(w, h);
+
+ // Copy 3/4 bytes
+ GImage::RGBAtoRGB((const uint8*)ptr, (uint8*)getCArray(), w * h);
+}
+
+
+void Image3uint8::copyArray(const Color4* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color3uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color3uint8(src[i].rgb());
+ }
+}
+
+
+/** Saves in any of the formats supported by G3D::GImage. */
+void Image3uint8::save(const std::string& filename, GImage::Format fmt) {
+ GImage im(width(), height(), 3);
+ System::memcpy(im.byte(), getCArray(), width() * height() * 3);
+ im.save(filename, fmt);
+}
+
+
+ReferenceCountedPointer<class Image1uint8> Image3uint8::getChannel(int c) const {
+ debugAssert(c >= 0 && c <= 2);
+
+ Image1uint8Ref dst = Image1uint8::createEmpty(width(), height(), wrapMode());
+ const Color3uint8* srcArray = getCArray();
+ Color1uint8* dstArray = dst->getCArray();
+
+ const int N = width() * height();
+ for (int i = 0; i < N; ++i) {
+ dstArray[i] = Color1uint8(srcArray[i][c]);
+ }
+
+ return dst;
+}
+
+
+const ImageFormat* Image3uint8::format() const {
+ return ImageFormat::RGB8();
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/Image4.cpp b/dep/src/g3dlite/Image4.cpp
new file mode 100644
index 00000000000..c6f2b10640d
--- /dev/null
+++ b/dep/src/g3dlite/Image4.cpp
@@ -0,0 +1,226 @@
+/**
+ @file Image4.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2008-07-27
+*/
+
+
+#include "G3D/Image4.h"
+#include "G3D/Image4uint8.h"
+#include "G3D/GImage.h"
+#include "G3D/Color3.h"
+#include "G3D/Color3uint8.h"
+#include "G3D/Color1.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/ImageFormat.h"
+
+namespace G3D {
+
+Image4::Image4(int w, int h, WrapMode wrap) : Map2D<Color4, Color4>(w, h, wrap) {
+ setAll(Color4::zero());
+}
+
+
+Image4::Ref Image4::fromGImage(const GImage& im, WrapMode wrap) {
+ switch (im.channels()) {
+ case 1:
+ return fromArray(im.pixel1(), im.width(), im.height(), wrap);
+
+ case 3:
+ return fromArray(im.pixel3(), im.width(), im.height(), wrap);
+
+ case 4:
+ return fromArray(im.pixel4(), im.width(), im.height(), wrap);
+
+ default:
+ debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
+ return NULL;
+ }
+}
+
+
+Image4::Ref Image4::fromImage4uint8(const ReferenceCountedPointer<Image4uint8>& im) {
+ Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
+ out->resize(im->width(), im->height());
+
+ int N = im->width() * im->height();
+ const Color4uint8* src = reinterpret_cast<Color4uint8*>(im->getCArray());
+ for (int i = 0; i < N; ++i) {
+ out->data[i] = Color4(src[i]);
+ }
+
+ return out;
+}
+
+
+Image4::Ref Image4::createEmpty(int width, int height, WrapMode wrap) {
+ return new Type(width, height, wrap);
+}
+
+
+Image4::Ref Image4::createEmpty(WrapMode wrap) {
+ return createEmpty(0, 0, wrap);
+}
+
+
+Image4::Ref Image4::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
+ Ref out = createEmpty(wrap);
+ out->load(filename);
+ return out;
+}
+
+
+void Image4::load(const std::string& filename, GImage::Format fmt) {
+ copyGImage(GImage(filename, fmt));
+ setChanged(true);
+}
+
+
+Image4::Ref Image4::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4::Ref Image4::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4::Ref Image4::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4::Ref Image4::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4::Ref Image4::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4::Ref Image4::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+void Image4::copyGImage(const GImage& im) {
+ switch (im.channels()) {
+ case 1:
+ copyArray(im.pixel1(), im.width(), im.height());
+ break;
+
+ case 3:
+ copyArray(im.pixel3(), im.width(), im.height());
+ break;
+
+ case 4:
+ copyArray(im.pixel4(), im.width(), im.height());
+ break;
+ }
+}
+
+
+void Image4::copyArray(const Color4uint8* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color4* dst = data.getCArray();
+ // Convert int8 -> float
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color4(src[i]);
+ }
+}
+
+
+void Image4::copyArray(const Color3uint8* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color4* dst = data.getCArray();
+
+ // Add alpha and convert
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color4(Color3(src[i]), 1.0f);
+ }
+}
+
+
+void Image4::copyArray(const Color4* src, int w, int h) {
+ resize(w, h);
+ System::memcpy(getCArray(), src, w * h * sizeof(Color4));
+}
+
+
+void Image4::copyArray(const Color3* src, int w, int h) {
+ resize(w, h);
+
+ int N = w * h;
+ Color4* dst = data.getCArray();
+
+ // Add alpha
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color4(src[i], 1.0f);
+ }
+}
+
+
+void Image4::copyArray(const Color1uint8* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color4* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = Color1(src[i]).value;
+ dst[i].a = 1.0f;
+ }
+}
+
+
+void Image4::copyArray(const Color1* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color4* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = src[i].value;
+ dst[i].a = 1.0f;
+ }
+}
+
+
+/** Saves in any of the formats supported by G3D::GImage. */
+void Image4::save(const std::string& filename, GImage::Format fmt) {
+ GImage im(width(), height(), 4);
+
+ int N = im.width() * im.height();
+ Color4uint8* dst = im.pixel4();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color4uint8(data[i]);
+ }
+
+ im.save(filename, fmt);
+}
+
+const ImageFormat* Image4::format() const {
+ return ImageFormat::RGBA32F();
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/Image4uint8.cpp b/dep/src/g3dlite/Image4uint8.cpp
new file mode 100644
index 00000000000..a94ddb12d03
--- /dev/null
+++ b/dep/src/g3dlite/Image4uint8.cpp
@@ -0,0 +1,222 @@
+/**
+ @file Image4uint8.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-01-31
+ @edited 2008-07-31
+*/
+
+#include "G3D/Image4uint8.h"
+#include "G3D/Image4.h"
+#include "G3D/Image3uint8.h"
+#include "G3D/Image3.h"
+#include "G3D/GImage.h"
+#include "G3D/Color1.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/Color4.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/ImageFormat.h"
+
+namespace G3D {
+
+Image4uint8::Image4uint8(int w, int h, WrapMode wrap) : Map2D<Color4uint8, Color4>(w, h, wrap) {
+ setAll(Color4::zero());
+}
+
+
+Image4uint8::Ref Image4uint8::fromGImage(const GImage& im, WrapMode wrap) {
+ switch (im.channels()) {
+ case 1:
+ return fromArray(im.pixel1(), im.width(), im.height(), wrap);
+
+ case 3:
+ return fromArray(im.pixel3(), im.width(), im.height(), wrap);
+
+ case 4:
+ return fromArray(im.pixel4(), im.width(), im.height(), wrap);
+
+ default:
+ debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
+ return NULL;
+ }
+}
+
+
+Image4uint8::Ref Image4uint8::fromImage4(const ReferenceCountedPointer<Image4>& im) {
+ Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
+ out->copyArray(im->getCArray(), im->width(), im->height());
+
+ return out;
+}
+
+
+Image4uint8::Ref Image4uint8::createEmpty(int width, int height, WrapMode wrap) {
+ return new Type(width, height, wrap);
+}
+
+
+Image4uint8::Ref Image4uint8::createEmpty(WrapMode wrap) {
+ return createEmpty(0, 0, wrap);
+}
+
+
+Image4uint8::Ref Image4uint8::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
+ Ref out = createEmpty(wrap);
+ out->load(filename, fmt);
+ return out;
+}
+
+
+Image4uint8::Ref Image4uint8::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4uint8::Ref Image4uint8::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4uint8::Ref Image4uint8::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4uint8::Ref Image4uint8::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4uint8::Ref Image4uint8::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+Image4uint8::Ref Image4uint8::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
+ Ref out = createEmpty(wrap);
+ out->copyArray(ptr, w, h);
+ return out;
+}
+
+
+void Image4uint8::load(const std::string& filename, GImage::Format fmt) {
+ copyGImage(GImage(filename, fmt));
+ setChanged(true);
+}
+
+
+void Image4uint8::copyGImage(const GImage& im) {
+ switch (im.channels()) {
+ case 1:
+ copyArray(im.pixel1(), im.width(), im.height());
+ break;
+
+ case 3:
+ copyArray(im.pixel3(), im.width(), im.height());
+ break;
+
+ case 4:
+ copyArray(im.pixel4(), im.width(), im.height());
+ break;
+ }
+}
+
+
+void Image4uint8::copyArray(const Color1uint8* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color4uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = src[i].value;
+ dst[i].a = 255;
+ }
+}
+
+void Image4uint8::copyArray(const Color1* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color4uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i].r = dst[i].g = dst[i].b = Color1uint8(src[i]).value;
+ dst[i].a = 255;
+ }
+}
+
+
+void Image4uint8::copyArray(const Color4uint8* ptr, int w, int h) {
+ resize(w, h);
+ System::memcpy(getCArray(), ptr, w * h * 4);
+}
+
+
+void Image4uint8::copyArray(const Color4* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color4uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color4uint8(src[i]);
+ }
+}
+
+
+void Image4uint8::copyArray(const Color3uint8* ptr, int w, int h) {
+ resize(w, h);
+
+ GImage::RGBtoRGBA((const uint8*)ptr, (uint8*)getCArray(), w * h);
+}
+
+
+void Image4uint8::copyArray(const Color3* src, int w, int h) {
+ resize(w, h);
+ int N = w * h;
+
+ Color4uint8* dst = getCArray();
+ for (int i = 0; i < N; ++i) {
+ dst[i] = Color4uint8(Color4(src[i], 1.0f));
+ }
+}
+
+
+/** Saves in any of the formats supported by G3D::GImage. */
+void Image4uint8::save(const std::string& filename, GImage::Format fmt) {
+ GImage im(width(), height(), 4);
+ System::memcpy(im.byte(), getCArray(), width() * height() * 4);
+ im.save(filename, fmt);
+}
+
+
+ReferenceCountedPointer<class Image1uint8> Image4uint8::getChannel(int c) const {
+ debugAssert(c >= 0 && c <= 3);
+
+ Image1uint8Ref dst = Image1uint8::createEmpty(width(), height(), wrapMode());
+ const Color4uint8* srcArray = getCArray();
+ Color1uint8* dstArray = dst->getCArray();
+
+ const int N = width() * height();
+ for (int i = 0; i < N; ++i) {
+ dstArray[i] = Color1uint8(srcArray[i][c]);
+ }
+
+ return dst;
+}
+
+
+const ImageFormat* Image4uint8::format() const {
+ return ImageFormat::RGBA8();
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/ImageFormat.cpp b/dep/src/g3dlite/ImageFormat.cpp
new file mode 100644
index 00000000000..70de878c11e
--- /dev/null
+++ b/dep/src/g3dlite/ImageFormat.cpp
@@ -0,0 +1,567 @@
+/**
+ @file ImageFormat.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-05-23
+ @edited 2009-12-10
+ */
+
+#include "GLG3D/glheaders.h"
+#include "G3D/ImageFormat.h"
+
+namespace G3D {
+
+ImageFormat::ImageFormat(
+ int _numComponents,
+ bool _compressed,
+ int _glFormat,
+ int _glBaseFormat,
+ int _luminanceBits,
+ int _alphaBits,
+ int _redBits,
+ int _greenBits,
+ int _blueBits,
+ int _depthBits,
+ int _stencilBits,
+ int _hardwareBitsPerTexel,
+ int _packedBitsPerTexel,
+ int glDataFormat,
+ bool _opaque,
+ bool _floatingPoint,
+ Code _code,
+ ColorSpace _colorSpace,
+ BayerPattern _bayerPattern) :
+
+ numComponents(_numComponents),
+ compressed(_compressed),
+ code(_code),
+ colorSpace(_colorSpace),
+ bayerPattern(_bayerPattern),
+ openGLFormat(_glFormat),
+ openGLBaseFormat(_glBaseFormat),
+ luminanceBits(_luminanceBits),
+ alphaBits(_alphaBits),
+ redBits(_redBits),
+ greenBits(_greenBits),
+ blueBits(_blueBits),
+ stencilBits(_stencilBits),
+ depthBits(_depthBits),
+ cpuBitsPerPixel(_packedBitsPerTexel),
+ packedBitsPerTexel(_packedBitsPerTexel),
+ openGLBitsPerPixel(_hardwareBitsPerTexel),
+ hardwareBitsPerTexel(_hardwareBitsPerTexel),
+ openGLDataFormat(glDataFormat),
+ opaque(_opaque),
+ floatingPoint(_floatingPoint) {
+
+ debugAssert(_packedBitsPerTexel <= _hardwareBitsPerTexel);
+}
+
+const ImageFormat* ImageFormat::depth(int depthBits) {
+
+ switch (depthBits) {
+ case 16:
+ return DEPTH16();
+
+ case 24:
+ return DEPTH24();
+
+ case 32:
+ return DEPTH32();
+
+ default:
+ debugAssertM(false, "Depth must be 16, 24, or 32.");
+ return DEPTH32();
+ }
+}
+
+
+const ImageFormat* ImageFormat::stencil(int bits) {
+ switch (bits) {
+ case 1:
+ return STENCIL1();
+
+ case 4:
+ return STENCIL4();
+
+ case 8:
+ return STENCIL8();
+
+ case 16:
+ return STENCIL16();
+
+ default:
+ debugAssertM(false, "Stencil must be 1, 4, 8 or 16.");
+ return STENCIL16();
+ }
+}
+
+
+ static const std::string nameArray[] =
+ {
+ "L8",
+ "L16",
+ "L16F",
+ "L32F",
+
+ "A8",
+ "A16",
+ "A16F",
+ "A32F",
+
+ "LA4",
+ "LA8",
+ "LA16",
+ "LA16F",
+ "LA32F",
+
+ "RGB5",
+ "RGB5A1",
+ "RGB8",
+ "RGB10",
+ "RGB10A2",
+ "RGB16",
+ "RGB16F",
+ "RGB32F",
+ "R11G11B10F",
+ "RGB9E10F",
+
+ "RGB8I",
+ "RGB8UI",
+
+ "ARGB8",
+ "BGR8",
+
+ "RG8",
+ "RG8I",
+ "RG8UI",
+
+ "RGBA8",
+ "RGBA16",
+ "RGBA16F",
+ "RGBA32F",
+
+ "RGBA32UI",
+
+ "BAYER_RGGB8",
+ "BAYER_GRBG8",
+ "BAYER_GBRG8",
+ "BAYER_BGGR8",
+ "BAYER_RGGB32F",
+ "BAYER_GRBG32F",
+ "BAYER_GBRG32F",
+ "BAYER_BGGR32F",
+
+ "HSV8",
+ "HSV32F",
+
+ "YUV420_PLANAR",
+ "YUV422",
+ "YUV444",
+
+ "RGB_DXT1",
+ "RGBA_DXT1",
+ "RGBA_DXT3",
+ "RGBA_DXT5",
+
+ "SRGB8",
+ "SRGBA8",
+
+ "SL8",
+ "SLA8",
+
+ "SRGB_DXT1",
+ "SRGBA_DXT1",
+ "SRGBA_DXT3",
+ "SRGBA_DXT5",
+
+ "DEPTH16",
+ "DEPTH24",
+ "DEPTH32",
+ "DEPTH32F",
+
+ "STENCIL1",
+ "STENCIL4",
+ "STENCIL8",
+ "STENCIL16",
+
+ "DEPTH24_STENCIL8",
+ ""
+ };
+
+const std::string& ImageFormat::name() const {
+ debugAssert(code < CODE_NUM);
+ return nameArray[code];
+}
+
+
+const ImageFormat* ImageFormat::fromString(const std::string& s) {
+
+ for (int i = 0; ! nameArray[i].empty(); ++i) {
+ if (s == nameArray[i]) {
+ return fromCode(ImageFormat::Code(i));
+ }
+ }
+ return NULL;
+}
+
+
+const ImageFormat* ImageFormat::fromCode(ImageFormat::Code code) {
+ switch (code) {
+ case ImageFormat::CODE_L8:
+ return ImageFormat::L8();
+
+ case ImageFormat::CODE_L16:
+ return ImageFormat::L16();
+
+ case ImageFormat::CODE_L16F:
+ return ImageFormat::L16F();
+
+ case ImageFormat::CODE_L32F:
+ return ImageFormat::L32F();
+
+ case ImageFormat::CODE_A8:
+ return ImageFormat::A8();
+
+ case ImageFormat::CODE_A16:
+ return ImageFormat::A16();
+
+ case ImageFormat::CODE_A16F:
+ return ImageFormat::A16F();
+
+ case ImageFormat::CODE_A32F:
+ return ImageFormat::A32F();
+
+ case ImageFormat::CODE_LA4:
+ return ImageFormat::LA4();
+
+ case ImageFormat::CODE_LA8:
+ return ImageFormat::LA8();
+
+ case ImageFormat::CODE_LA16:
+ return ImageFormat::LA16();
+
+ case ImageFormat::CODE_LA16F:
+ return ImageFormat::LA16F();
+ break;
+ case ImageFormat::CODE_LA32F:
+ return ImageFormat::LA32F();
+
+ case ImageFormat::CODE_RGB5:
+ return ImageFormat::RGB5();
+
+ case ImageFormat::CODE_RGB5A1:
+ return ImageFormat::RGB5A1();
+
+ case ImageFormat::CODE_RGB8:
+ return ImageFormat::RGB8();
+
+ case ImageFormat::CODE_RGB10:
+ return ImageFormat::RGB10();
+
+ case ImageFormat::CODE_RGB10A2:
+ return ImageFormat::RGB10A2();
+
+ case ImageFormat::CODE_RGB16:
+ return ImageFormat::RGB16();
+
+ case ImageFormat::CODE_RGB32F:
+ return ImageFormat::RGB32F();
+
+ case ImageFormat::CODE_R11G11B10F:
+ return ImageFormat::R11G11B10F();
+
+ case ImageFormat::CODE_RGB9E5F:
+ return ImageFormat::RGB9E5F();
+
+ case ImageFormat::CODE_RGB8I:
+ return ImageFormat::RGB8I();
+
+ case ImageFormat::CODE_RGB8UI:
+ return ImageFormat::RGB8UI();
+
+ case ImageFormat::CODE_ARGB8:
+ return NULL;
+
+ case ImageFormat::CODE_BGR8:
+ return ImageFormat::BGR8();
+
+ case ImageFormat::CODE_RG8:
+ return ImageFormat::RG8();
+
+ case ImageFormat::CODE_RG8I:
+ return ImageFormat::RG8I();
+
+ case ImageFormat::CODE_RG8UI:
+ return ImageFormat::RG8UI();
+
+ case ImageFormat::CODE_RGBA8:
+ return ImageFormat::RGBA8();
+
+ case ImageFormat::CODE_RGBA16:
+ return ImageFormat::RGBA16();
+
+ case ImageFormat::CODE_RGBA16F:
+ return ImageFormat::RGBA16F();
+
+ case ImageFormat::CODE_RGBA32F:
+ return ImageFormat::RGBA32F();
+
+ case ImageFormat::CODE_RGBA32UI:
+ return ImageFormat::RGBA32UI();
+
+ case ImageFormat::CODE_BAYER_RGGB8:
+ // TODO
+ case ImageFormat::CODE_BAYER_GRBG8:
+ // TODO
+ case ImageFormat::CODE_BAYER_GBRG8:
+ // TODO
+ case ImageFormat::CODE_BAYER_BGGR8:
+ // TODO
+ case ImageFormat::CODE_BAYER_RGGB32F:
+ // TODO
+ case ImageFormat::CODE_BAYER_GRBG32F:
+ // TODO
+ case ImageFormat::CODE_BAYER_GBRG32F:
+ // TODO
+ case ImageFormat::CODE_BAYER_BGGR32F:
+ // TODO
+
+ case ImageFormat::CODE_HSV8:
+ // TODO
+ case ImageFormat::CODE_HSV32F:
+ // TODO
+ return NULL;
+ break;
+
+ case ImageFormat::CODE_RGB_DXT1:
+ return ImageFormat::RGB_DXT1();
+ break;
+ case ImageFormat::CODE_RGBA_DXT1:
+ return ImageFormat::RGBA_DXT1();
+ break;
+ case ImageFormat::CODE_RGBA_DXT3:
+ return ImageFormat::RGBA_DXT3();
+ break;
+ case ImageFormat::CODE_RGBA_DXT5:
+ return ImageFormat::RGBA_DXT5();
+ break;
+
+ case ImageFormat::CODE_SRGB8:
+ return ImageFormat::SRGB8();
+ break;
+
+ case ImageFormat::CODE_SRGBA8:
+ return ImageFormat::SRGBA8();
+ break;
+
+ case ImageFormat::CODE_SL8:
+ return ImageFormat::SL8();
+ break;
+
+ case ImageFormat::CODE_SLA8:
+ return ImageFormat::SLA8();
+ break;
+
+ case ImageFormat::CODE_SRGB_DXT1:
+ return ImageFormat::SRGB_DXT1();
+ break;
+
+ case ImageFormat::CODE_SRGBA_DXT1:
+ return ImageFormat::SRGBA_DXT1();
+ break;
+
+ case ImageFormat::CODE_SRGBA_DXT3:
+ return ImageFormat::SRGBA_DXT3();
+ break;
+
+ case ImageFormat::CODE_SRGBA_DXT5:
+ return ImageFormat::SRGBA_DXT5();
+ break;
+
+ case ImageFormat::CODE_DEPTH16:
+ return ImageFormat::DEPTH16();
+ break;
+ case ImageFormat::CODE_DEPTH24:
+ return ImageFormat::DEPTH24();
+ break;
+ case ImageFormat::CODE_DEPTH32:
+ return ImageFormat::DEPTH32();
+ break;
+ case ImageFormat::CODE_DEPTH32F:
+ return ImageFormat::DEPTH32F();
+ break;
+
+ case ImageFormat::CODE_STENCIL1:
+ return ImageFormat::STENCIL1();
+ break;
+ case ImageFormat::CODE_STENCIL4:
+ return ImageFormat::STENCIL4();
+ break;
+ case ImageFormat::CODE_STENCIL8:
+ return ImageFormat::STENCIL8();
+ break;
+ case ImageFormat::CODE_STENCIL16:
+ return ImageFormat::STENCIL16();
+ break;
+
+ case ImageFormat::CODE_DEPTH24_STENCIL8:
+ return ImageFormat::DEPTH24_STENCIL8();
+ break;
+
+ case ImageFormat::CODE_YUV420_PLANAR:
+ return ImageFormat::YUV420_PLANAR();
+ break;
+
+ case ImageFormat::CODE_YUV422:
+ return ImageFormat::YUV422();
+ break;
+
+ case ImageFormat::CODE_YUV444:
+ return ImageFormat::YUV444();
+ break;
+
+ default:
+ return NULL;
+ }
+}
+
+// Helper variables for defining texture formats
+
+// Is floating point format
+static const bool FLOAT_FORMAT = true;
+static const bool INT_FORMAT = false;
+
+// Is opaque format (no alpha)
+static const bool OPAQUE_FORMAT = true;
+static const bool CLEAR_FORMAT = false;
+
+// Is compressed format (not raw component data)
+static const bool COMP_FORMAT = true;
+static const bool UNCOMP_FORMAT = false;
+
+#define DEFINE_TEXTUREFORMAT_METHOD(enumname, cmpnts, cmprssd, glf, glbf, lb, ab, rb, gb, bb, db, sb, hbpt, pbpt, gldf, opq, fp, code, cs) \
+ const ImageFormat* ImageFormat::enumname() { \
+ static const ImageFormat format(cmpnts, cmprssd, glf, glbf, lb, ab, rb, gb, bb, db, sb, hbpt, pbpt, gldf, opq, fp, code, cs); \
+ return &format; }
+
+DEFINE_TEXTUREFORMAT_METHOD(L8, 1, UNCOMP_FORMAT, GL_LUMINANCE8, GL_LUMINANCE, 8, 0, 0, 0, 0, 0, 0, 8, 8, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, CODE_L8, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(L16, 1, UNCOMP_FORMAT, GL_LUMINANCE16, GL_LUMINANCE, 16, 0, 0, 0, 0, 0, 0, 16, 16,GL_UNSIGNED_SHORT, OPAQUE_FORMAT, INT_FORMAT, CODE_L16, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(L16F, 1, UNCOMP_FORMAT, GL_LUMINANCE16F_ARB,GL_LUMINANCE, 16, 0, 0, 0, 0, 0, 0, 16, 16, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, CODE_L16F, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(L32F, 1, UNCOMP_FORMAT, GL_LUMINANCE32F_ARB,GL_LUMINANCE, 32, 0, 0, 0, 0, 0, 0, 32, 32, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, CODE_L32F, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(A8, 1, UNCOMP_FORMAT, GL_ALPHA8, GL_ALPHA, 0, 8, 0, 0, 0, 0, 0, 8, 8, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, CODE_A8, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(A16, 1, UNCOMP_FORMAT, GL_ALPHA16, GL_ALPHA, 0, 16, 0, 0, 0, 0, 0, 16, 16, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, CODE_A16, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(A16F, 1, UNCOMP_FORMAT, GL_ALPHA16F_ARB, GL_ALPHA, 0, 16, 0, 0, 0, 0, 0, 16, 16, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, CODE_A16F, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(A32F, 1, UNCOMP_FORMAT, GL_ALPHA32F_ARB, GL_ALPHA, 0, 32, 0, 0, 0, 0, 0, 32, 32, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, CODE_A32F, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(LA4, 2, UNCOMP_FORMAT, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, 4, 4, 0, 0, 0, 0, 0, 8, 8, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, CODE_LA4, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(LA8, 2, UNCOMP_FORMAT, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, 8, 8, 0, 0, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, CODE_LA8, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(LA16, 2, UNCOMP_FORMAT, GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA, 16, 16, 0, 0, 0, 0, 0, 16*2, 16*2, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, CODE_LA16, COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(LA16F, 2, UNCOMP_FORMAT, GL_LUMINANCE_ALPHA16F_ARB, GL_LUMINANCE_ALPHA, 16, 16, 0, 0, 0, 0, 0, 16*2, 16*2, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_LA16F, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(LA32F, 2, UNCOMP_FORMAT, GL_LUMINANCE_ALPHA32F_ARB, GL_LUMINANCE_ALPHA, 32, 32, 0, 0, 0, 0, 0, 32*2, 32*2, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_LA32F, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(BGR8, 3, UNCOMP_FORMAT, GL_RGB8, GL_BGR, 0, 0, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_BGR8, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RG8, 2, UNCOMP_FORMAT, GL_RG8, GL_RG, 0, 0, 8, 8, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RG8, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RG8I, 2, UNCOMP_FORMAT, GL_RG8I, GL_RG, 0, 0, 8, 8, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RG8I, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RG8UI, 2, UNCOMP_FORMAT, GL_RG8UI, GL_RG, 0, 0, 8, 8, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RG8UI, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB5, 3, UNCOMP_FORMAT, GL_RGB5, GL_RGBA, 0, 0, 5, 5, 5, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB5, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB5A1, 4, UNCOMP_FORMAT, GL_RGB5_A1, GL_RGBA, 0, 1, 5, 5, 5, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB5A1, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB8, 3, UNCOMP_FORMAT, GL_RGB8, GL_RGB, 0, 0, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB8, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB10, 3, UNCOMP_FORMAT, GL_RGB10, GL_RGB, 0, 0, 10, 10, 10, 0, 0, 32, 10*3, GL_UNSIGNED_SHORT, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB10, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB10A2, 4, UNCOMP_FORMAT, GL_RGB10_A2, GL_RGBA, 0, 2, 10, 10, 10, 0, 0, 32, 32, GL_UNSIGNED_INT_10_10_10_2, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB10A2, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB16, 3, UNCOMP_FORMAT, GL_RGB16, GL_RGB, 0, 0, 16, 16, 16, 0, 0, 16*3, 16*3, GL_UNSIGNED_SHORT, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB16, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB16F, 3, UNCOMP_FORMAT, GL_RGB16F_ARB, GL_RGB, 0, 0, 16, 16, 16, 0, 0, 16*3, 16*3, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGB16F, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB32F, 3, UNCOMP_FORMAT, GL_RGB32F_ARB, GL_RGB, 0, 0, 32, 32, 32, 0, 0, 32*3, 32*3, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGB32F, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA8, 4, UNCOMP_FORMAT, GL_RGBA8, GL_RGBA, 0, 8, 8, 8, 8, 0, 0, 32, 32, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA8, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA16, 4, UNCOMP_FORMAT, GL_RGBA16, GL_RGBA, 0, 16, 16, 16, 16, 0, 0, 16*4, 16*4, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA16, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA16F, 4, UNCOMP_FORMAT, GL_RGBA16F_ARB, GL_RGBA, 0, 16, 16, 16, 16, 0, 0, 16*4, 16*4, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGBA16F, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA32F, 4, UNCOMP_FORMAT, GL_RGBA32F_ARB, GL_RGBA, 0, 32, 32, 32, 32, 0, 0, 32*4, 32*4, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGBA32F, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA32UI, 4, UNCOMP_FORMAT, GL_RGBA32UI, GL_RGBA, 0, 32, 32, 32, 32, 0, 0, 32*4, 32*4, GL_UNSIGNED_INT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA32UI, ImageFormat::COLOR_SPACE_RGB);
+
+// Unsigned
+DEFINE_TEXTUREFORMAT_METHOD(R11G11B10F, 3, UNCOMP_FORMAT, GL_R11F_G11F_B10F_EXT, GL_RGB, 0, 0, 11, 11, 10, 0, 0, 32, 32, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_R11G11B10F, ImageFormat::COLOR_SPACE_RGB);
+
+// Unsigned
+DEFINE_TEXTUREFORMAT_METHOD(RGB9E5F, 3, UNCOMP_FORMAT, GL_RGB9_E5_EXT, GL_RGB, 0, 0, 14, 14, 14, 0, 0, 32, 32, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGB9E5F, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB8I, 3, UNCOMP_FORMAT, GL_RGB8I_EXT, GL_RGB, 0, 0, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB8I, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB8UI, 3, UNCOMP_FORMAT, GL_RGB8UI_EXT, GL_RGB, 0, 0, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB8UI, ImageFormat::COLOR_SPACE_RGB);
+
+
+DEFINE_TEXTUREFORMAT_METHOD(RGB_DXT1, 3, COMP_FORMAT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, 0, 0, 0, 0, 0, 0, 0, 64, 64, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB_DXT1, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA_DXT1, 4, COMP_FORMAT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 64, 64, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA_DXT1, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA_DXT3, 4, COMP_FORMAT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 128, 128, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA_DXT3, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(RGBA_DXT5, 4, COMP_FORMAT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 128, 128, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA_DXT5, ImageFormat::COLOR_SPACE_RGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SRGB8, 3, UNCOMP_FORMAT, GL_SRGB8, GL_RGB, 0, 0, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_SRGB8, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SRGBA8, 4, UNCOMP_FORMAT, GL_SRGB8_ALPHA8, GL_RGBA, 0, 8, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_SRGBA8, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SL8, 1, UNCOMP_FORMAT, GL_SLUMINANCE8, GL_LUMINANCE, 8, 0, 0, 0, 0, 0, 0, 8, 8, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_SL8, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SLA8, 2, UNCOMP_FORMAT, GL_SLUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, 8, 8, 0, 0, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_SLA8, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SRGB_DXT1, 3, COMP_FORMAT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_RGB, 0, 0, 0, 0, 0, 0, 0, 64, 64, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_SRGB_DXT1, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SRGBA_DXT1, 4, COMP_FORMAT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 64, 64, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_SRGBA_DXT1, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SRGBA_DXT3, 4, COMP_FORMAT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 128, 128, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_SRGBA_DXT3, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(SRGBA_DXT5, 4, COMP_FORMAT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 128, 128, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_SRGBA_DXT5, ImageFormat::COLOR_SPACE_SRGB);
+
+DEFINE_TEXTUREFORMAT_METHOD(DEPTH16, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT16_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 16, 0, 16, 16, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH16, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(DEPTH24, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 24, 0, 32, 24, GL_UNSIGNED_INT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH24, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(DEPTH32, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 32, 0, 32, 32, GL_UNSIGNED_INT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH32, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(DEPTH32F, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 32, 0, 32, 32, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_DEPTH32F, ImageFormat::COLOR_SPACE_NONE);
+
+// These formats are for use with Renderbuffers only!
+DEFINE_TEXTUREFORMAT_METHOD(STENCIL1, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX1_EXT, GL_STENCIL_INDEX, 0, 0, 0, 0, 0, 0, 1, 1, 1, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL1, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(STENCIL4, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX4_EXT, GL_STENCIL_INDEX, 0, 0, 0, 0, 0, 0, 4, 4, 4, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL4, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(STENCIL8, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX8_EXT, GL_STENCIL_INDEX, 0, 0, 0, 0, 0, 0, 8, 8, 8, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL8, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(STENCIL16, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX16_EXT, GL_STENCIL_INDEX, 0, 0, 0, 0, 0, 0, 16, 16, 16, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL16, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(DEPTH24_STENCIL8, 2, UNCOMP_FORMAT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL_EXT,0, 0, 0, 0, 0, 24, 8, 32, 32, GL_UNSIGNED_INT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH24_STENCIL8, ImageFormat::COLOR_SPACE_NONE);
+
+DEFINE_TEXTUREFORMAT_METHOD(YUV420_PLANAR, 3, UNCOMP_FORMAT, GL_NONE, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 12, 12, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_YUV420_PLANAR, ImageFormat::COLOR_SPACE_YUV);
+DEFINE_TEXTUREFORMAT_METHOD(YUV422, 3, UNCOMP_FORMAT, GL_NONE, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_YUV422, ImageFormat::COLOR_SPACE_YUV);
+DEFINE_TEXTUREFORMAT_METHOD(YUV444, 3, UNCOMP_FORMAT, GL_NONE, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 24, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_YUV444, ImageFormat::COLOR_SPACE_YUV);
+
+}
diff --git a/dep/src/g3dlite/ImageFormat_convert.cpp b/dep/src/g3dlite/ImageFormat_convert.cpp
new file mode 100644
index 00000000000..ecefe6319c7
--- /dev/null
+++ b/dep/src/g3dlite/ImageFormat_convert.cpp
@@ -0,0 +1,1307 @@
+#include "G3D/ImageFormat.h"
+#include "G3D/Color1uint8.h"
+#include "G3D/Color3uint8.h"
+#include "G3D/Color4uint8.h"
+#include "G3D/Color1.h"
+#include "G3D/Color3.h"
+#include "G3D/Color4.h"
+
+
+namespace G3D {
+
+// this is the signature for all conversion routines (same parameters as ImageFormat::convert)
+typedef void (*ConvertFunc)(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg);
+
+// this defines the conversion routines for converting between compatible formats
+static const int NUM_CONVERT_IMAGE_FORMATS = 5;
+struct ConvertAttributes {
+ ConvertFunc m_converter;
+ ImageFormat::Code m_sourceFormats[NUM_CONVERT_IMAGE_FORMATS];
+ ImageFormat::Code m_destFormats[NUM_CONVERT_IMAGE_FORMATS];
+ bool m_handlesSourcePadding;
+ bool m_handlesDestPadding;
+ bool m_handleInvertY;
+};
+
+// forward declare the converters we can use them below
+#define DECLARE_CONVERT_FUNC(name) static void name(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg);
+
+DECLARE_CONVERT_FUNC(l8_to_rgb8);
+DECLARE_CONVERT_FUNC(l32f_to_rgb8);
+DECLARE_CONVERT_FUNC(rgb8_to_rgba8);
+DECLARE_CONVERT_FUNC(rgb8_to_bgr8);
+DECLARE_CONVERT_FUNC(rgb8_to_rgba32f);
+DECLARE_CONVERT_FUNC(bgr8_to_rgb8);
+DECLARE_CONVERT_FUNC(bgr8_to_rgba8);
+DECLARE_CONVERT_FUNC(bgr8_to_rgba32f);
+DECLARE_CONVERT_FUNC(rgba8_to_rgb8);
+DECLARE_CONVERT_FUNC(rgba8_to_bgr8);
+DECLARE_CONVERT_FUNC(rgba8_to_rgba32f);
+DECLARE_CONVERT_FUNC(rgb32f_to_rgba32f);
+DECLARE_CONVERT_FUNC(rgba32f_to_rgb8);
+DECLARE_CONVERT_FUNC(rgba32f_to_rgba8);
+DECLARE_CONVERT_FUNC(rgba32f_to_bgr8);
+DECLARE_CONVERT_FUNC(rgba32f_to_rgb32f);
+DECLARE_CONVERT_FUNC(rgba32f_to_bayer_rggb8);
+DECLARE_CONVERT_FUNC(rgba32f_to_bayer_gbrg8);
+DECLARE_CONVERT_FUNC(rgba32f_to_bayer_grbg8);
+DECLARE_CONVERT_FUNC(rgba32f_to_bayer_bggr8);
+DECLARE_CONVERT_FUNC(bayer_rggb8_to_rgba32f);
+DECLARE_CONVERT_FUNC(bayer_gbrg8_to_rgba32f);
+DECLARE_CONVERT_FUNC(bayer_grbg8_to_rgba32f);
+DECLARE_CONVERT_FUNC(bayer_bggr8_to_rgba32f);
+DECLARE_CONVERT_FUNC(rgb8_to_yuv420p);
+DECLARE_CONVERT_FUNC(rgb8_to_yuv422);
+DECLARE_CONVERT_FUNC(rgb8_to_yuv444);
+DECLARE_CONVERT_FUNC(yuv420p_to_rgb8);
+DECLARE_CONVERT_FUNC(yuv422_to_rgb8);
+DECLARE_CONVERT_FUNC(yuv444_to_rgb8);
+
+// this is the list of mappings between formats and the routines to perform them
+static const ConvertAttributes sConvertMappings[] = {
+
+ // RGB -> RGB color space
+ // L8 ->
+ {l8_to_rgb8, {ImageFormat::CODE_L8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
+
+ // L32F ->
+ {l32f_to_rgb8, {ImageFormat::CODE_L32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
+
+ // RGB8 ->
+ {rgb8_to_rgba8, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, false, false, true},
+ {rgb8_to_bgr8, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, false, false, true},
+ {rgb8_to_rgba32f, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
+
+ // BGR8 ->
+ {bgr8_to_rgb8, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
+ {bgr8_to_rgba8, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, false, false, true},
+ {bgr8_to_rgba32f, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
+
+ // RGBA8 ->
+ {rgba8_to_rgb8, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
+ {rgba8_to_bgr8, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, false, false, true},
+ {rgba8_to_rgba32f, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
+
+ // RGB32F ->
+ {rgb32f_to_rgba32f, {ImageFormat::CODE_RGB32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
+
+ // RGBA32F ->
+ {rgba32f_to_rgb8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, true, true},
+ {rgba32f_to_rgba8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, false, true, true},
+ {rgba32f_to_bgr8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, false, true, true},
+ {rgba32f_to_rgb32f, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB32F, ImageFormat::CODE_NONE}, false, true, true},
+
+ // RGB -> BAYER color space
+ {rgba32f_to_bayer_rggb8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_RGGB8, ImageFormat::CODE_NONE}, false, true, true},
+ {rgba32f_to_bayer_gbrg8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_GBRG8, ImageFormat::CODE_NONE}, false, true, true},
+ {rgba32f_to_bayer_grbg8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_GRBG8, ImageFormat::CODE_NONE}, false, true, true},
+ {rgba32f_to_bayer_bggr8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_BGGR8, ImageFormat::CODE_NONE}, false, true, true},
+
+ // BAYER -> RGB color space
+ {bayer_rggb8_to_rgba32f, {ImageFormat::CODE_BAYER_RGGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
+ {bayer_gbrg8_to_rgba32f, {ImageFormat::CODE_BAYER_GBRG8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
+ {bayer_grbg8_to_rgba32f, {ImageFormat::CODE_BAYER_GRBG8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
+ {bayer_bggr8_to_rgba32f, {ImageFormat::CODE_BAYER_BGGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
+
+ // RGB <-> YUV color space
+ {rgb8_to_yuv420p, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_YUV420_PLANAR, ImageFormat::CODE_NONE}, false, false, false},
+ {rgb8_to_yuv422, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_YUV422, ImageFormat::CODE_NONE}, false, false, false},
+ {rgb8_to_yuv444, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_YUV444, ImageFormat::CODE_NONE}, false, false, false},
+ {yuv420p_to_rgb8, {ImageFormat::CODE_YUV420_PLANAR, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, false},
+ {yuv422_to_rgb8, {ImageFormat::CODE_YUV422, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, false},
+ {yuv444_to_rgb8, {ImageFormat::CODE_YUV444, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, false},
+};
+
+static ConvertFunc findConverter(TextureFormat::Code sourceCode, TextureFormat::Code destCode, bool needsSourcePadding, bool needsDestPadding, bool needsInvertY) {
+ int numRoutines = sizeof(sConvertMappings) / sizeof(ConvertAttributes);
+ for (int routineIndex = 0; routineIndex < numRoutines; ++routineIndex) {
+ int sourceIndex = 0;
+ ConvertAttributes routine = sConvertMappings[routineIndex];
+
+ while (routine.m_sourceFormats[sourceIndex] != ImageFormat::CODE_NONE) {
+ // check for matching source
+ if (routine.m_sourceFormats[sourceIndex] == sourceCode) {
+ int destIndex = 0;
+
+ // now check for matching dest to see if the routine fits
+ while (routine.m_destFormats[destIndex] != ImageFormat::CODE_NONE) {
+
+ // check if dest format matches and padding + invert rules match
+ if ((routine.m_destFormats[destIndex] == destCode) &&
+ (!needsSourcePadding || (routine.m_handlesSourcePadding == needsSourcePadding)) &&
+ (!needsDestPadding || (routine.m_handlesDestPadding == needsDestPadding)) &&
+ (!needsInvertY || (routine.m_handleInvertY == needsInvertY))) {
+
+ // found compatible converter
+ return routine.m_converter;
+ }
+ ++destIndex;
+ }
+ }
+ ++sourceIndex;
+ }
+ }
+
+ return NULL;
+}
+
+bool conversionAvailable(const ImageFormat* srcFormat, int srcRowPadBits, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY = false) {
+ bool conversionAvailable = false;
+
+ // check if a conversion is available
+ if ( (srcFormat->code == dstFormat->code) && (srcRowPadBits == dstRowPadBits) && !invertY) {
+ conversionAvailable = true;
+ } else {
+ ConvertFunc directConverter = findConverter(srcFormat->code, dstFormat->code, srcRowPadBits > 0, dstRowPadBits > 0, invertY);
+
+ conversionAvailable = (directConverter != NULL);
+ }
+
+ return conversionAvailable;
+}
+
+bool ImageFormat::convert(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits,
+ const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits,
+ bool invertY, BayerAlgorithm bayerAlg) {
+
+ bool conversionAvailable = false;
+
+ // Handle direct copy of image to same format
+ if ( (srcFormat->code == dstFormat->code) && (srcRowPadBits == dstRowPadBits) && !invertY) {
+
+ System::memcpy(dstBytes[0], srcBytes[0], iCeil(((srcWidth * srcFormat->cpuBitsPerPixel + srcRowPadBits) * srcHeight) / 8.0f));
+ conversionAvailable = true;
+ } else {
+ // if no direct conversion routine exists,
+ // then look for conversion to intermediate
+ // and then from intermediate to dest.
+ // intermediate format is RGBA32F
+ ConvertFunc directConverter = findConverter(srcFormat->code, dstFormat->code, srcRowPadBits > 0, dstRowPadBits > 0, invertY);
+
+ // if we have a direct converter, use it, otherwise find intermdiate path
+ if (directConverter) {
+ directConverter(srcBytes, srcWidth, srcHeight, srcFormat, srcRowPadBits, dstBytes, dstFormat, dstRowPadBits, invertY, bayerAlg);
+ conversionAvailable = true;
+ } else {
+ ConvertFunc toInterConverter = findConverter(srcFormat->code, ImageFormat::CODE_RGBA32F, srcRowPadBits > 0, false, false);;
+ ConvertFunc fromInterConverter = findConverter(ImageFormat::CODE_RGBA32F, dstFormat->code, false, dstRowPadBits > 0, invertY);;
+
+ if (toInterConverter && fromInterConverter) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * ImageFormat::RGBA32F()->cpuBitsPerPixel * 8));
+
+ toInterConverter(srcBytes, srcWidth, srcHeight, srcFormat, srcRowPadBits, tmp, ImageFormat::RGBA32F(), 0, false, bayerAlg);
+ fromInterConverter(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, dstBytes, dstFormat, dstRowPadBits, invertY, bayerAlg);
+
+ System::free(tmp[0]);
+
+ conversionAvailable = true;
+ }
+ }
+ }
+
+ return conversionAvailable;
+}
+
+
+// *******************
+// RGB -> RGB color space conversions
+// *******************
+
+// L8 ->
+static void l8_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ (void)bayerAlg;
+ (void)dstRowPadBits;
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+ int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
+ int i3 = i * 3;
+
+ dst[i3 + 0] = src[i];
+ dst[i3 + 1] = src[i];
+ dst[i3 + 2] = src[i];
+ }
+ }
+}
+
+// L32F ->
+static void l32f_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ int srcIndex = 0;
+ int dstByteOffset = 0;
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const float* src = static_cast<const float*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ srcIndex = srcWidth * (srcHeight - y - 1);
+ }
+
+ for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3) {
+ Color3uint8& d = *reinterpret_cast<Color3uint8*>(dst + dstByteOffset);
+ float s = src[srcIndex];
+
+ uint8 c = iMin(255, iFloor(s * 256));
+ d = Color3uint8(c, c, c);
+ }
+ }
+}
+
+// RGB8 ->
+static void rgb8_to_rgba8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+ int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ dst[i4 + 0] = src[i3 + 0];
+ dst[i4 + 1] = src[i3 + 1];
+ dst[i4 + 2] = src[i3 + 2];
+ dst[i4 + 3] = 255;
+ }
+ }
+}
+
+static void rgb8_to_bgr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+ int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
+ int i3 = i * 3;
+ dst[i3 + 0] = src[i3 + 2];
+ dst[i3 + 1] = src[i3 + 1];
+ dst[i3 + 2] = src[i3 + 0];
+ }
+ }
+}
+
+static void rgb8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
+
+ int dstIndex = 0;
+ int srcByteOffset = 0;
+ int srcRowPadBytes = srcRowPadBits / 8;
+ Color4* dst = static_cast<Color4*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ dstIndex = srcWidth * (srcHeight - 1 - y);
+ }
+ for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 3) {
+ const Color3uint8& s = *reinterpret_cast<const Color3uint8*>(src + srcByteOffset);
+ dst[dstIndex] = Color4(Color3(s), 1.0f);
+ }
+ srcByteOffset += srcRowPadBytes;
+ }
+}
+
+// BGR8 ->
+static void bgr8_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+ int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
+ int i3 = i * 3;
+ dst[i3 + 0] = src[i3 + 2];
+ dst[i3 + 1] = src[i3 + 1];
+ dst[i3 + 2] = src[i3 + 0];
+ }
+ }
+}
+
+static void bgr8_to_rgba8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+ int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ dst[i4 + 0] = src[i3 + 2];
+ dst[i4 + 1] = src[i3 + 1];
+ dst[i4 + 2] = src[i3 + 0];
+ dst[i4 + 3] = 255;
+ }
+ }
+}
+
+static void bgr8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
+
+ int dstIndex = 0;
+ int srcByteOffset = 0;
+ int srcRowPadBytes = srcRowPadBits / 8;
+ Color4* dst = static_cast<Color4*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ dstIndex = srcWidth * (srcHeight - 1 - y);
+ }
+
+ for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 3) {
+ const Color3uint8& s = *reinterpret_cast<const Color3uint8*>(src + srcByteOffset);
+ dst[dstIndex] = Color4(Color3(s).bgr(), 1.0f);
+ }
+ srcByteOffset += srcRowPadBytes;
+ }
+}
+
+// RGBA8 ->
+static void rgba8_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+ int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ dst[i3 + 0] = src[i4 + 0];
+ dst[i3 + 1] = src[i4 + 1];
+ dst[i3 + 2] = src[i4 + 2];
+ }
+ }
+}
+
+static void rgba8_to_bgr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+ int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
+ int i3 = i * 3;
+ int i4 = i3 + i;
+
+ dst[i3 + 0] = src[i4 + 2];
+ dst[i3 + 1] = src[i4 + 1];
+ dst[i3 + 2] = src[i4 + 0];
+ }
+ }
+}
+
+static void rgba8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
+
+ int dstIndex = 0;
+ int srcByteOffset = 0;
+ int srcRowPadBytes = srcRowPadBits / 8;
+ Color4* dst = static_cast<Color4*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ dstIndex = srcWidth * (srcHeight - 1 - y);
+ }
+
+ for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 4) {
+ const Color4uint8& s = *reinterpret_cast<const Color4uint8*>(src + srcByteOffset);
+ dst[dstIndex] = Color4(s);
+ }
+ srcByteOffset += srcRowPadBytes;
+ }
+}
+
+// RGB32F ->
+static void rgb32f_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
+
+ int dstIndex = 0;
+ int srcByteOffset = 0;
+ int srcRowPadBytes = srcRowPadBits / 8;
+ Color4* dst = static_cast<Color4*>(dstBytes[0]);
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ dstIndex = srcWidth * (srcHeight - 1 - y);
+ }
+
+ for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 3 * sizeof(float)) {
+ const Color3& s = *reinterpret_cast<const Color3*>(src + srcByteOffset);
+ dst[dstIndex] = Color4(Color3(s), 1.0f);
+ }
+ srcByteOffset += srcRowPadBytes;
+ }
+}
+
+// RGBA32F ->
+static void rgba32f_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
+
+ int srcIndex = 0;
+ int dstByteOffset = 0;
+ int dstRowPadBytes = dstRowPadBits / 8;
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const Color4* src = static_cast<const Color4*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ srcIndex = srcWidth * (srcHeight - y - 1);
+ }
+
+ for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3) {
+ Color3uint8& d = *reinterpret_cast<Color3uint8*>(dst + dstByteOffset);
+ const Color4& s = src[srcIndex];
+
+ d = Color3uint8(s.rgb());
+ }
+ dstByteOffset += dstRowPadBytes;
+ }
+}
+
+static void rgba32f_to_rgba8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
+
+ int srcIndex = 0;
+ int dstByteOffset = 0;
+ int dstRowPadBytes = dstRowPadBits / 8;
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const Color4* src = static_cast<const Color4*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ srcIndex = srcWidth * (srcHeight - 1 - y);
+ }
+ for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 4) {
+ Color4uint8& d = *reinterpret_cast<Color4uint8*>(dst + dstByteOffset);
+ const Color4& s = src[srcIndex];
+
+ d = Color4uint8(s);
+ }
+ dstByteOffset += dstRowPadBytes;
+ }
+}
+
+static void rgba32f_to_bgr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
+
+ int srcIndex = 0;
+ int dstByteOffset = 0;
+ int dstRowPadBytes = dstRowPadBits / 8;
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const Color4* src = static_cast<const Color4*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ srcIndex = srcWidth * (srcHeight - y - 1);
+ }
+
+ for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3) {
+ Color3uint8& d = *reinterpret_cast<Color3uint8*>(dst + dstByteOffset);
+ const Color4& s = src[srcIndex];
+
+ d = Color3uint8(s.rgb()).bgr();
+ }
+ dstByteOffset += dstRowPadBytes;
+ }
+}
+
+static void rgba32f_to_rgb32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
+
+ int srcIndex = 0;
+ int dstByteOffset = 0;
+ int dstRowPadBytes = dstRowPadBits / 8;
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+ const Color4* src = static_cast<const Color4*>(srcBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ if (invertY) {
+ srcIndex = srcWidth * (srcHeight - 1 - y);
+ }
+ for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3 * sizeof(float)) {
+ Color3& d = *reinterpret_cast<Color3*>(dst + dstByteOffset);
+ const Color4& s = src[srcIndex];
+ d = s.rgb();
+ }
+ dstByteOffset += dstRowPadBytes;
+ }
+}
+
+// *******************
+// RGB <-> YUV color space conversions
+// *******************
+
+static uint32 blendPixels(uint32 pixel1, uint32 pixel2) {
+ static const uint32 rbMask = 0x00FF00FF;
+ static const uint32 agMask = 0xFF00FF00;
+
+ // Compute two color channels at a time. Use >> 1 for fast division by two
+ // Using alternating color channels prevents overflow
+ const uint32 rb = ((pixel1 & rbMask) + (pixel2 & rbMask)) >> 1;
+
+ // Shift first to avoid overflow in alpha channel
+ const uint32 ag = (((pixel1 & agMask) >> 1) + ((pixel2 & agMask) >> 1));
+
+ return ((rb & rbMask) | (ag & agMask));
+}
+
+#define PIXEL_RGB8_TO_YUV_Y(r, g, b) static_cast<uint8>(iClamp(((66 * r + 129 * g + 25 * b + 128) >> 8) + 16, 0, 255))
+#define PIXEL_RGB8_TO_YUV_U(r, g, b) static_cast<uint8>(iClamp(((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128, 0, 255))
+#define PIXEL_RGB8_TO_YUV_V(r, g, b) static_cast<uint8>(iClamp(((112 * r - 94 * g - 18 * b + 128) >> 8) + 128, 0, 255))
+
+static void rgb8_to_yuv420p(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
+ debugAssertM((srcWidth % 2 == 0) && (srcHeight % 2 == 0), "Source width and height must be a multiple of two");
+
+ const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
+
+ uint8* dstY = static_cast<uint8*>(dstBytes[0]);
+ uint8* dstU = static_cast<uint8*>(dstBytes[1]);
+ uint8* dstV = static_cast<uint8*>(dstBytes[2]);
+
+ for (int y = 0; y < srcHeight; y += 2) {
+ for (int x = 0; x < srcWidth; x += 2) {
+
+ // convert 4-pixel block at a time
+ int srcPixelOffset0 = y * srcWidth + x;
+ int srcPixelOffset1 = srcPixelOffset0 + 1;
+ int srcPixelOffset2 = srcPixelOffset0 + srcWidth;
+ int srcPixelOffset3 = srcPixelOffset2 + 1;
+
+ int yIndex = y * srcWidth + x;
+
+ dstY[yIndex] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset0].r, src[srcPixelOffset0].g, src[srcPixelOffset0].b);
+ dstY[yIndex + 1] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset1].r, src[srcPixelOffset1].g, src[srcPixelOffset1].b);
+
+ yIndex += srcWidth;
+ dstY[yIndex] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset2].r, src[srcPixelOffset2].g, src[srcPixelOffset2].b);
+ dstY[yIndex + 1] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset3].r, src[srcPixelOffset3].g, src[srcPixelOffset3].b);
+
+ uint32 blendedPixel = blendPixels(src[srcPixelOffset0].asUInt32(), src[srcPixelOffset2].asUInt32());
+ Color3uint8 uvSrcColor = Color3uint8::fromARGB(blendedPixel);
+
+ int uvIndex = y / 2 * srcWidth / 2 + x / 2;
+ dstU[uvIndex] = PIXEL_RGB8_TO_YUV_U(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
+ dstV[uvIndex] = PIXEL_RGB8_TO_YUV_V(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
+ }
+ }
+}
+
+static void rgb8_to_yuv422(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
+ debugAssertM((srcWidth % 2 == 0), "Source width must be a multiple of two");
+
+ const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
+
+ uint8* dst = static_cast<uint8*>(dstBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; x += 2) {
+
+ // convert 2-pixel horizontal block at a time
+ int srcIndex = y * srcWidth + x;
+ int dstIndex = srcIndex * 2;
+
+ uint32 blendedPixel = blendPixels(src[srcIndex].asUInt32(), src[srcIndex + 1].asUInt32());
+ Color3uint8 uvSrcColor = Color3uint8::fromARGB(blendedPixel);
+
+ dst[dstIndex] = PIXEL_RGB8_TO_YUV_Y(src[srcIndex].r, src[srcIndex].g, src[srcIndex].b);
+
+ dst[dstIndex + 1] = PIXEL_RGB8_TO_YUV_U(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
+
+ dst[dstIndex + 2] = PIXEL_RGB8_TO_YUV_Y(src[srcIndex + 1].r, src[srcIndex + 1].g, src[srcIndex + 1].b);
+
+ dst[dstIndex + 3] = PIXEL_RGB8_TO_YUV_V(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
+
+ }
+ }
+}
+
+static void rgb8_to_yuv444(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
+
+ const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
+
+ Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+
+ // convert 1-pixels at a time
+ int index = y * srcWidth + x;
+ uint8 y = PIXEL_RGB8_TO_YUV_Y(src[index].r, src[index].g, src[index].b);
+ uint8 u = PIXEL_RGB8_TO_YUV_U(src[index].r, src[index].g, src[index].b);
+ uint8 v = PIXEL_RGB8_TO_YUV_V(src[index].r, src[index].g, src[index].b);
+
+ dst[index].r = y;
+ dst[index].g = u;
+ dst[index].b = v;
+ }
+ }
+}
+
+
+#define PIXEL_YUV_TO_RGB8_R(y, u, v) static_cast<uint8>(iClamp((298 * (y - 16) + 409 * (v - 128) + 128) >> 8, 0, 255))
+#define PIXEL_YUV_TO_RGB8_G(y, u, v) static_cast<uint8>(iClamp((298 * (y - 16) - 100 * (u - 128) - 208 * (v - 128) + 128) >> 8, 0, 255))
+#define PIXEL_YUV_TO_RGB8_B(y, u, v) static_cast<uint8>(iClamp((298 * (y - 16) + 516 * (u - 128) + 128) >> 8, 0, 255))
+
+static void yuv420p_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
+ debugAssertM((srcWidth % 2 == 0) && (srcHeight % 2 == 0), "Source width and height must be a multiple of two");
+
+ const uint8* srcY = static_cast<const uint8*>(srcBytes[0]);
+ const uint8* srcU = static_cast<const uint8*>(srcBytes[1]);
+ const uint8* srcV = static_cast<const uint8*>(srcBytes[2]);
+
+ Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; x += 2) {
+
+ // convert to two rgb pixels in a row
+ Color3uint8* rgb = &dst[y * srcWidth + x];
+
+ int yOffset = y * srcWidth + x;
+ int uvOffset = y / 2 * srcWidth / 2 + x / 2;
+
+ rgb->r = PIXEL_YUV_TO_RGB8_R(srcY[yOffset], srcU[uvOffset], srcV[uvOffset]);
+ rgb->g = PIXEL_YUV_TO_RGB8_G(srcY[yOffset], srcU[uvOffset], srcV[uvOffset]);
+ rgb->b = PIXEL_YUV_TO_RGB8_B(srcY[yOffset], srcU[uvOffset], srcV[uvOffset]);
+
+ rgb += 1;
+ rgb->r = PIXEL_YUV_TO_RGB8_R(srcY[yOffset + 1], srcU[uvOffset], srcV[uvOffset]);
+ rgb->g = PIXEL_YUV_TO_RGB8_G(srcY[yOffset + 1], srcU[uvOffset], srcV[uvOffset]);
+ rgb->b = PIXEL_YUV_TO_RGB8_B(srcY[yOffset + 1], srcU[uvOffset], srcV[uvOffset]);
+ }
+ }
+}
+
+static void yuv422_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
+ debugAssertM((srcWidth % 2 == 0), "Source width must be a multiple of two");
+
+ const uint8* src = static_cast<const uint8*>(srcBytes[0]);
+
+ Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; x += 2) {
+
+ // convert to two rgb pixels in a row
+ Color3uint8* rgb = &dst[y * srcWidth + x];
+
+ int srcIndex = (y * srcWidth + x) * 2;
+ uint8 y = src[srcIndex];
+ uint8 u = src[srcIndex + 1];
+ uint8 y2 = src[srcIndex + 2];
+ uint8 v = src[srcIndex + 3];
+
+ rgb->r = PIXEL_YUV_TO_RGB8_R(y, u, v);
+ rgb->g = PIXEL_YUV_TO_RGB8_G(y, u, v);
+ rgb->b = PIXEL_YUV_TO_RGB8_B(y, u, v);
+
+ rgb += 1;
+ rgb->r = PIXEL_YUV_TO_RGB8_R(y2, u, v);
+ rgb->g = PIXEL_YUV_TO_RGB8_G(y2, u, v);
+ rgb->b = PIXEL_YUV_TO_RGB8_B(y2, u, v);
+ }
+ }
+}
+
+static void yuv444_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
+
+ const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
+
+ Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
+
+ for (int y = 0; y < srcHeight; ++y) {
+ for (int x = 0; x < srcWidth; ++x) {
+
+ // convert to one rgb pixels at a time
+ int index = y * srcWidth + x;
+ Color3uint8* rgb = &dst[index];
+
+ rgb->r = PIXEL_YUV_TO_RGB8_R(src[index].r, src[index].g, src[index].b);
+ rgb->g = PIXEL_YUV_TO_RGB8_G(src[index].r, src[index].g, src[index].b);
+ rgb->b = PIXEL_YUV_TO_RGB8_B(src[index].r, src[index].g, src[index].b);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Bayer conversions
+//
+
+// There are two kinds of rows (GR and BG).
+// In each row, there are two kinds of pixels (G/R, B/G).
+// We express the four kinds of INPUT pixels as:
+// GRG, GRG, BGB, BGG
+//
+// There are three kinds of OUTPUT pixels: R, G, B.
+// Thus there are nominally 12 different I/O combinations,
+// but several are impulses because needed output at that
+// location *is* the input (e.g., G_GRG and G_BGG).
+//
+// The following 5x5 row-major filters are named as output_input.
+
+// Green
+static const float G_GRR[5][5] =
+ {{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
+ { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+ { -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
+ { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+ { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
+
+static const float G_BGB[5][5] =
+ {{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
+ { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+ { -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
+ { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
+ { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
+
+// Red
+//(the caption in the paper is wrong for this case:
+// "R row B column really means R row G column"
+static const float R_GRG[5][5] =
+ {{ 0.0f, 0.0f, 0.5f, 0.0f, 0.0f},
+ { 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
+ { -1.0f, 4.0f, 5.0f, 4.0f, -1.0f},
+ { 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
+ { 0.0f, 0.0f, 0.5f, 0.0f, 0.0f}};
+
+static const float R_BGG[5][5] =
+ {{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
+ { 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
+ { 0.5f, 0.0f, 5.0f, 0.0f, 0.5f},
+ { 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
+ { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
+
+static const float R_BGB[5][5] =
+ {{ 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f},
+ { 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
+ {-3.0f/2.0f, 0.0f, 6.0f, 0.0f, -3.0f/2.0f},
+ { 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
+ { 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f}};
+
+
+// Blue
+//(the caption in the paper is wrong for this case:
+// "B row R column really means B row G column")
+#define B_BGG R_GRG
+#define B_GRG R_BGG
+#define B_GRR R_BGB
+
+// =====================================================================
+// Helper methods
+// =====================================================================
+
+
+/** Applies a 5x5 filter to monochrome image I (wrapping at the boundaries) */
+static uint8 applyFilter(const uint8* I,
+ int x,
+ int y,
+ int w,
+ int h,
+ const float filter[5][5]) {
+
+ debugAssert(isEven(w));
+ debugAssert(isEven(h));
+
+ float sum = 0.0f;
+ float denom = 0.0f;
+
+ for (int dy = 0; dy < 5; ++dy) {
+ int offset = ((y + dy + h - 2) % h) * w;
+
+ for (int dx = 0; dx < 5; ++dx) {
+ float f = filter[dy][dx];
+ sum += f * I[((x + dx + w - 2) % w) + offset];
+ denom += f;
+ }
+ }
+
+ return (uint8)iClamp(iRound(sum / denom), 0, 255);
+}
+
+/** Helper method for Bayer grbg and bggr --> rgb8 */
+static void swapRedAndBlue(int N, Color3uint8* out) {
+ for (int i = N - 1; i >= 0; --i) {
+ uint8 tmp = out[i].r;
+ out[i].r = out[i].b;
+ out[i].b = tmp;
+ }
+}
+
+// RGB -> BAYER color space
+
+// =====================================================================
+// rgb8 --> bayer helpers
+// =====================================================================
+static void rgb8_to_bayer_rggb8(const int w, const int h,
+ const uint8* src, uint8* dst) {
+ Color3uint8* srcColor = (Color3uint8*)src;
+ Color1uint8* dstColor = (Color1uint8*)dst;
+
+ // Top row pixels
+ for (int y = 0; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Top left pixels
+ for(int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].r);
+ }
+
+ // Top right pixels
+ for(int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+ }
+
+ // Bottom row pixels
+ for (int y = 1; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Bottom left pixels
+ for (int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+
+ // Bottom right pixels
+ for (int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].b);
+ }
+ }
+}
+
+
+static void rgb8_to_bayer_grbg8(const int w, const int h,
+ const uint8* src, uint8* dst) {
+ Color3uint8* srcColor = (Color3uint8*)src;
+ Color1uint8* dstColor = (Color1uint8*)dst;
+
+ // Top row pixels
+ for (int y = 0; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Top left pixels
+ for (int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+
+ // Top right pixels
+ for (int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].r);
+ }
+ }
+
+ // Bottom row pixels
+ for (int y = 1; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Bottom left pixels
+ for (int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].b);
+ }
+
+ // Bottom right pixels
+ for (int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+ }
+}
+
+
+static void rgb8_to_bayer_bggr8(const int w, const int h,
+ const uint8* src, uint8* dst) {
+ Color3uint8* srcColor = (Color3uint8*)src;
+ Color1uint8* dstColor = (Color1uint8*)dst;
+
+ // Top row pixels
+ for (int y = 0; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Top left pixels
+ for (int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].b);
+ }
+
+ // Top right pixels
+ for (int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+ }
+
+ // Bottom row pixels
+ for (int y = 1; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Bottom left pixels
+ for(int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+
+ // Bottom right pixels
+ for(int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].r);
+ }
+ }
+}
+
+
+static void rgb8_to_bayer_gbrg8(const int w, const int h,
+ const uint8* src, uint8* dst) {
+ Color3uint8* srcColor = (Color3uint8*)src;
+ Color1uint8* dstColor = (Color1uint8*)dst;
+
+ // Top row pixels
+ for(int y = 0; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Top left pixels
+ for(int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+
+ // Top right pixels
+ for(int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].b);
+ }
+ }
+
+ // Bottom row pixels
+ for(int y = 1; y < h - 1; y += 2) {
+ int offset = y * w;
+
+ // Bottom left pixels
+ for(int x = 0; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].r);
+ }
+
+ // Bottom right pixels
+ for(int x = 1; x < w - 1; x += 2) {
+ dstColor[x + offset] = Color1(srcColor[x + offset].g);
+ }
+ }
+}
+
+// =====================================================================
+// rgba32f (-->rgb8) --> bayer converter implementations
+// =====================================================================
+static void rgba32f_to_bayer_rggb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
+ rgb8_to_bayer_rggb8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
+
+ System::free(tmp[0]);
+}
+
+static void rgba32f_to_bayer_gbrg8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
+ rgb8_to_bayer_grbg8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
+
+ System::free(tmp[0]);
+}
+
+static void rgba32f_to_bayer_grbg8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
+ rgb8_to_bayer_gbrg8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
+
+ System::free(tmp[0]);
+}
+
+static void rgba32f_to_bayer_bggr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
+ rgb8_to_bayer_bggr8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
+
+ System::free(tmp[0]);
+}
+
+// BAYER -> RGB color space
+
+// =====================================================================
+// bayer --> rgb8 helpers
+// =====================================================================
+static void bayer_rggb8_to_rgb8_mhc(int w, int h,
+ const uint8* in, uint8* _out) {
+ debugAssert(in != _out);
+
+ Color3uint8* out = (Color3uint8*)_out;
+
+ for (int y = 0; y < h; ++y) {
+
+ // Row beginning in the input array.
+ int offset = y * w;
+
+ // RG row
+ for (int x = 0; x < w; ++x, ++out) {
+ // R pixel
+ {
+ out->r = in[x + offset];
+ out->g = applyFilter(in, x, y, w, h, G_GRR);
+ out->b = applyFilter(in, x, y, w, h, B_GRR);
+ }
+ ++x; ++out;
+
+ // G pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_GRG);
+ out->g = in[x + offset];
+ out->b = applyFilter(in, x, y, w, h, B_GRG);
+ }
+ }
+
+ ++y;
+ offset += w;
+
+ // GB row
+ for (int x = 0; x < w; ++x, ++out) {
+ // G pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGG);
+ out->g = in[x + offset];
+ out->b = applyFilter(in, x, y, w, h, B_BGG);
+ }
+ ++x; ++out;
+
+ // B pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGB);
+ out->g = applyFilter(in, x, y, w, h, G_BGB);
+ out->b = in[x + offset];
+ }
+ }
+ }
+}
+
+
+
+static void bayer_gbrg8_to_rgb8_mhc(int w, int h,
+ const uint8* in, uint8* _out) {
+
+ debugAssert(in != _out);
+
+ Color3uint8* out = (Color3uint8*)_out;
+
+ for (int y = 0; y < h; ++y) {
+
+ // Row beginning in the input array.
+ int offset = y * w;
+
+ // GB row
+ for (int x = 0; x < w; ++x, ++out) {
+ // G pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGG);
+ out->g = in[x + offset];
+ out->b = applyFilter(in, x, y, w, h, B_BGG);
+ }
+ ++x; ++out;
+
+ // B pixel
+ {
+ out->r = applyFilter(in, x, y, w, h, R_BGB);
+ out->g = applyFilter(in, x, y, w, h, G_BGB);
+ out->b = in[x + offset];
+ }
+ }
+ }
+}
+
+
+static void bayer_grbg8_to_rgb8_mhc(int w, int h,
+ const uint8* in, uint8* _out) {
+ // Run the equivalent function for red
+ bayer_gbrg8_to_rgb8_mhc(w, h, in, _out);
+
+ // Now swap red and blue
+ swapRedAndBlue(w * h, (Color3uint8*)_out);
+}
+
+
+static void bayer_bggr8_to_rgb8_mhc(int w, int h,
+ const uint8* in, uint8* _out) {
+ // Run the equivalent function for red
+ bayer_rggb8_to_rgb8_mhc(w, h, in, _out);
+
+ // Now swap red and blue
+ swapRedAndBlue(w * h, (Color3uint8*)_out);
+}
+
+// =====================================================================
+// bayer (--> rgb8) --> rgba32f converter implementations
+// =====================================================================
+static void bayer_rggb8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ bayer_rggb8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
+ rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
+
+ System::free(tmp[0]);
+}
+
+static void bayer_gbrg8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ bayer_grbg8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
+ rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
+
+ System::free(tmp[0]);
+}
+
+static void bayer_grbg8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ bayer_gbrg8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
+ rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
+
+ System::free(tmp[0]);
+}
+
+static void bayer_bggr8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
+ Array<void*> tmp;
+ tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
+
+ bayer_bggr8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
+ rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
+
+ System::free(tmp[0]);
+}
+
+
+
+
+
+ // TODO: The following region is commented out because so far
+ // those conversions are not used anywhere else. Until it is
+ // decided that such conversions are not needed, this region
+ // remains commented out.
+
+
+// // =====================================================================
+// // bayer --> bgr8
+// // =====================================================================
+
+// static void bayer_rggb8_to_bgr8_mhc(int w, int h,
+// const uint8* in, uint8* _out) {
+// debugAssert(in != _out);
+
+// Color3uint8* out = (Color3uint8*)_out;
+
+// for (int y = 0; y < h; ++y) {
+
+// // Row beginning in the input array.
+// int offset = y * w;
+
+// // RG row
+// for (int x = 0; x < w; ++x, ++out) {
+// // R pixel
+// {
+// out->b = in[x + offset];
+// out->g = applyFilter(in, x, y, w, h, G_GRR);
+// out->r = applyFilter(in, x, y, w, h, B_GRR);
+// }
+// ++x; ++out;
+
+// // G pixel
+// {
+// out->b = applyFilter(in, x, y, w, h, R_GRG);
+// out->g = in[x + offset];
+// out->r = applyFilter(in, x, y, w, h, B_GRG);
+// }
+// }
+
+// ++y;
+// offset += w;
+
+// // GB row
+// for (int x = 0; x < w; ++x, ++out) {
+// // G pixel
+// {
+// out->b = applyFilter(in, x, y, w, h, R_BGG);
+// out->g = in[x + offset];
+// out->r = applyFilter(in, x, y, w, h, B_BGG);
+// }
+// ++x; ++out;
+
+// // B pixel
+// {
+// out->b = applyFilter(in, x, y, w, h, R_BGB);
+// out->g = applyFilter(in, x, y, w, h, G_BGB);
+// out->r = in[x + offset];
+// }
+// }
+// }
+// }
+
+
+// static void bayer_gbrg8_to_bgr8_mhc(int w, int h,
+// const uint8* in, uint8* _out) {
+
+// debugAssert(in != _out);
+
+// Color3uint8* out = (Color3uint8*)_out;
+
+// for (int y = 0; y < h; ++y) {
+
+// // Row beginning in the input array.
+// int offset = y * w;
+
+// // GB row
+// for (int x = 0; x < srcWidth; ++x, ++out) {
+// // G pixel
+// {
+// out->b = applyFilter(in, x, y, w, h, R_BGG);
+// out->g = in[x + offset];
+// out->r = applyFilter(in, x, y, w, h, B_BGG);
+// }
+// ++x; ++out;
+
+// // B pixel
+// {
+// out->b = applyFilter(in, x, y, w, h, R_BGB);
+// out->g = applyFilter(in, x, y, w, h, G_BGB);
+// out->r = in[x + offset];
+// }
+// }
+// }
+// }
+
+// static void bayer_grbg8_to_bgr8_mhc(int w, int h,
+// const uint8* in, uint8* _out) {
+// // Run the equivalent function for red
+// bayer_gbrg8_to_bgr8_mhc(w, h, in, _out);
+
+// // Now swap red and blue
+// swapRedAndBlue(srcWidth * h, (Color3uint8*)_out);
+// }
+
+// static void bayer_bggr8_to_bgr8_mhc(int w, int h,
+// const uint8* in, uint8* _out) {
+// // Run the equivalent function for red
+// bayer_rggb8_to_bgr8_mhc(w, h, in, _out);
+
+// // Now swap red and blue
+// swapRedAndBlue(srcWidth * h, (Color3uint8*)_out);
+// }
+
+
+
+///////////////////////////////////////////////////
+
+} // namespace G3D
diff --git a/dep/src/g3dlite/Intersect.cpp b/dep/src/g3dlite/Intersect.cpp
new file mode 100644
index 00000000000..929a2e4e670
--- /dev/null
+++ b/dep/src/g3dlite/Intersect.cpp
@@ -0,0 +1,844 @@
+/**
+ @file Intersect.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-06-29
+ @edited 2009-06-29
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+
+ From the G3D Innovation Engine
+ http://g3d.sf.net
+ */
+#include "G3D/Intersect.h"
+
+namespace G3D {
+
+#ifdef _MSC_VER
+// Turn on fast floating-point optimizations
+#pragma float_control( push )
+#pragma fp_contract( on )
+#pragma fenv_access( off )
+#pragma float_control( except, off )
+#pragma float_control( precise, off )
+#endif
+
+bool __fastcall Intersect::rayAABox(const Ray& ray, const AABox& box) {
+ switch (ray.classification) {
+ case Ray::MMM:
+
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.lo.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.lo.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.lo.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.hi.x + ray.c_zx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MMP:
+
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.lo.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.hi.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.lo.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.hi.x + ray.c_zx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MPM:
+
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.lo.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.lo.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.lo.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.hi.x + ray.c_zx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MPP:
+
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.lo.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.hi.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.lo.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.hi.x + ray.c_zx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::PMM:
+
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.hi.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.lo.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.hi.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.lo.x + ray.c_zx < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::PMP:
+
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.hi.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.hi.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.hi.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.lo.x + ray.c_zx < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::PPM:
+
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.hi.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.lo.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.hi.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.lo.x + ray.c_zx < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::PPP:
+
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.hi.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.hi.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.hi.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.lo.x + ray.c_zx < 0)) {
+ return false;
+ }
+
+ return true;
+
+ case Ray::OMM:
+
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyk * box.lo.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.hi.z + ray.c_yz > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::OMP:
+
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyk * box.hi.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.lo.z + ray.c_yz < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::OPM:
+
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyk * box.lo.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.hi.z + ray.c_yz > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::OPP:
+
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyk * box.hi.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.lo.z + ray.c_yz < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MOM:
+
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.z < box.lo.z)
+ || (ray.kbyi * box.lo.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.hi.x + ray.c_zx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MOP:
+
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.z > box.hi.z)
+ || (ray.kbyi * box.lo.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.hi.x + ray.c_zx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::POM:
+
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.z < box.lo.z)
+ || (ray.kbyi * box.hi.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.lo.x + ray.c_zx < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::POP:
+
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.z > box.hi.z)
+ || (ray.kbyi * box.hi.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.lo.x + ray.c_zx < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MMO:
+
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.y < box.lo.y)
+ || (ray.jbyi * box.lo.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.hi.x + ray.c_yx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MPO:
+
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.y > box.hi.y)
+ || (ray.jbyi * box.lo.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.hi.x + ray.c_yx > 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::PMO:
+
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.y < box.lo.y)
+ || (ray.jbyi * box.hi.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.lo.x + ray.c_yx < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::PPO:
+
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.y > box.hi.y)
+ || (ray.jbyi * box.hi.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.lo.x + ray.c_yx < 0)
+ )
+ return false;
+
+ return true;
+
+ case Ray::MOO:
+
+ if((ray.m_origin.x < box.lo.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ )
+ return false;
+
+ return true;
+
+ case Ray::POO:
+
+ if((ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ )
+ return false;
+
+ return true;
+
+ case Ray::OMO:
+
+ if((ray.m_origin.y < box.lo.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ )
+ return false;
+
+ case Ray::OPO:
+
+ if((ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ )
+ return false;
+
+ case Ray::OOM:
+
+ if((ray.m_origin.z < box.lo.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ )
+ return false;
+
+ case Ray::OOP:
+
+ if((ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ )
+ return false;
+
+ return true;
+
+ }
+
+ return false;
+}
+
+
+bool __fastcall Intersect::rayAABox(const Ray& ray, const AABox& box, float& time) {
+
+ switch (ray.classification) {
+ case Ray::MMM:
+ {
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.lo.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.lo.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.lo.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.hi.x + ray.c_zx > 0)) {
+ return false;
+ }
+
+ // compute the intersection distance
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::MMP:
+ {
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.lo.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.hi.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.lo.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.hi.x + ray.c_zx > 0)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::MPM:
+ {
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.lo.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.lo.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.lo.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.hi.x + ray.c_zx > 0)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::MPP:
+ {
+ if ((ray.m_origin.x < box.lo.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.lo.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.hi.x + ray.c_yx > 0)
+ || (ray.jbyk * box.hi.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.lo.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.hi.x + ray.c_zx > 0)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::PMM:
+ {
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.hi.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.lo.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.hi.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.lo.x + ray.c_zx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+
+ case Ray::PMP:
+ {
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.hi.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.hi.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.hi.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.lo.x + ray.c_zx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::PPM:
+ {
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyi * box.hi.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.lo.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.hi.z + ray.c_yz > 0)
+ || (ray.kbyi * box.hi.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.lo.x + ray.c_zx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::PPP:
+ {
+ if ((ray.m_origin.x > box.hi.x) || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyi * box.hi.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.lo.x + ray.c_yx < 0)
+ || (ray.jbyk * box.hi.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.lo.z + ray.c_yz < 0)
+ || (ray.kbyi * box.hi.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.lo.x + ray.c_zx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::OMM:
+ {
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyk * box.lo.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.hi.z + ray.c_yz > 0)) {
+ return false;
+ }
+
+ time = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::OMP:
+ {
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyk * box.hi.z - box.hi.y + ray.c_zy > 0)
+ || (ray.kbyj * box.lo.y - box.lo.z + ray.c_yz < 0)) {
+ return false;
+ }
+
+ time = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::OPM:
+ {
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z < box.lo.z)
+ || (ray.jbyk * box.lo.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.hi.z + ray.c_yz > 0)) {
+ return false;
+ }
+
+ time = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::OPP:
+ {
+ if((ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y > box.hi.y) || (ray.m_origin.z > box.hi.z)
+ || (ray.jbyk * box.hi.z - box.lo.y + ray.c_zy < 0)
+ || (ray.kbyj * box.hi.y - box.lo.z + ray.c_yz < 0)) {
+ return false;
+ }
+
+ time = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+
+ case Ray::MOM:
+ {
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.z < box.lo.z)
+ || (ray.kbyi * box.lo.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.hi.x + ray.c_zx > 0)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+
+ case Ray::MOP:
+ {
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.z > box.hi.z)
+ || (ray.kbyi * box.lo.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.hi.x + ray.c_zx > 0)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::POM:
+ {
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.z < box.lo.z)
+ || (ray.kbyi * box.hi.x - box.hi.z + ray.c_xz > 0)
+ || (ray.ibyk * box.lo.z - box.lo.x + ray.c_zx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t2 = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+
+ case Ray::POP:
+ {
+ if((ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.z > box.hi.z)
+ || (ray.kbyi * box.hi.x - box.lo.z + ray.c_xz < 0)
+ || (ray.ibyk * box.hi.z - box.lo.x + ray.c_zx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t2 = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ if (t2 > time) {
+ time = t2;
+ }
+
+ return true;
+ }
+
+ case Ray::MMO:
+ {
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.y < box.lo.y)
+ || (ray.jbyi * box.lo.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.hi.x + ray.c_yx > 0)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+
+ return true;
+ }
+
+ case Ray::MPO:
+ {
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.y > box.hi.y)
+ || (ray.jbyi * box.lo.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.hi.x + ray.c_yx > 0)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+
+ return true;
+ }
+
+
+ case Ray::PMO:
+ {
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.y < box.lo.y)
+ || (ray.jbyi * box.hi.x - box.hi.y + ray.c_xy > 0)
+ || (ray.ibyj * box.lo.y - box.lo.x + ray.c_yx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+
+ return true;
+ }
+
+ case Ray::PPO:
+ {
+ if((ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x > box.hi.x) || (ray.m_origin.y > box.hi.y)
+ || (ray.jbyi * box.hi.x - box.lo.y + ray.c_xy < 0)
+ || (ray.ibyj * box.hi.y - box.lo.x + ray.c_yx < 0)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ float t1 = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ if (t1 > time) {
+ time = t1;
+ }
+
+ return true;
+ }
+
+
+ case Ray::MOO:
+ {
+ if((ray.m_origin.x < box.lo.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)) {
+ return false;
+ }
+
+ time = (box.hi.x - ray.m_origin.x) * ray.m_invDirection.x;
+ return true;
+ }
+
+ case Ray::POO:
+ {
+ if ((ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)) {
+ return false;
+ }
+
+ time = (box.lo.x - ray.m_origin.x) * ray.m_invDirection.x;
+ return true;
+ }
+
+ case Ray::OMO:
+ {
+ if ((ray.m_origin.y < box.lo.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)) {
+ return false;
+ }
+
+ time = (box.hi.y - ray.m_origin.y) * ray.m_invDirection.y;
+ return true;
+ }
+
+ case Ray::OPO:
+ {
+ if ((ray.m_origin.y > box.hi.y)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.z < box.lo.z) || (ray.m_origin.z > box.hi.z)) {
+ return false;
+ }
+
+ time = (box.lo.y - ray.m_origin.y) * ray.m_invDirection.y;
+ return true;
+ }
+
+
+ case Ray::OOM:
+ {
+ if ((ray.m_origin.z < box.lo.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)) {
+ return false;
+ }
+
+ time = (box.hi.z - ray.m_origin.z) * ray.m_invDirection.z;
+ return true;
+ }
+
+ case Ray::OOP:
+ {
+ if ((ray.m_origin.z > box.hi.z)
+ || (ray.m_origin.x < box.lo.x) || (ray.m_origin.x > box.hi.x)
+ || (ray.m_origin.y < box.lo.y) || (ray.m_origin.y > box.hi.y)) {
+ return false;
+ }
+
+ time = (box.lo.z - ray.m_origin.z) * ray.m_invDirection.z;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#ifdef _MSC_VER
+// Turn off fast floating-point optimizations
+#pragma float_control( pop )
+#endif
+
+}
diff --git a/dep/src/g3dlite/Line.cpp b/dep/src/g3dlite/Line.cpp
new file mode 100644
index 00000000000..195ae7197f2
--- /dev/null
+++ b/dep/src/g3dlite/Line.cpp
@@ -0,0 +1,89 @@
+/**
+ @file Line.cpp
+
+ Line class
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2001-06-02
+ @edited 2006-01-28
+ */
+
+#include "G3D/Line.h"
+#include "G3D/Plane.h"
+
+namespace G3D {
+
+Vector3 Line::intersection(const Plane& plane) const {
+ float d;
+ Vector3 normal = plane.normal();
+ plane.getEquation(normal, d);
+ float rate = _direction.dot(normal);
+
+ if (rate == 0) {
+
+ return Vector3::inf();
+
+ } else {
+ float t = -(d + _point.dot(normal)) / rate;
+
+ return _point + _direction * t;
+ }
+}
+
+
+Line::Line(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Line::serialize(class BinaryOutput& b) const {
+ _point.serialize(b);
+ _direction.serialize(b);
+}
+
+
+void Line::deserialize(class BinaryInput& b) {
+ _point.deserialize(b);
+ _direction.deserialize(b);
+}
+
+
+Vector3 Line::closestPoint(const Vector3& pt) const {
+ float t = _direction.dot(pt - _point);
+ return _point + _direction * t;
+}
+
+
+Vector3 Line::point() const {
+ return _point;
+}
+
+
+Vector3 Line::direction() const {
+ return _direction;
+}
+
+
+Vector3 Line::closestPoint(const Line& B, float& minDist) const {
+ const Vector3& P1 = _point;
+ const Vector3& U1 = _direction;
+
+ Vector3 P2 = B.point();
+ Vector3 U2 = B.direction();
+
+ const Vector3& P21 = P2 - P1;
+ const Vector3& M = U2.cross(U1);
+ float m2 = M.length();
+
+ Vector3 R = P21.cross(M) / m2;
+
+ float t1 = R.dot(U2);
+
+ minDist = abs(P21.dot(M)) / sqrt(m2);
+
+ return P1 + t1 * U1;
+}
+
+}
+
diff --git a/dep/src/g3dlite/LineSegment.cpp b/dep/src/g3dlite/LineSegment.cpp
new file mode 100644
index 00000000000..754600ad554
--- /dev/null
+++ b/dep/src/g3dlite/LineSegment.cpp
@@ -0,0 +1,236 @@
+/**
+ @file LineSegment.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-02-08
+ @edited 2008-02-02
+ */
+
+#include "G3D/platform.h"
+#include "G3D/LineSegment.h"
+#include "G3D/Sphere.h"
+#include "G3D/debug.h"
+
+namespace G3D {
+
+
+Vector3 LineSegment::closestPoint(const Vector3& p) const {
+
+ // The vector from the end of the capsule to the point in question.
+ Vector3 v(p - _point);
+
+ // Projection of v onto the line segment scaled by
+ // the length of direction.
+ float t = direction.dot(v);
+
+ // Avoid some square roots. Derivation:
+ // t/direction.length() <= direction.length()
+ // t <= direction.squaredLength()
+
+ if ((t >= 0) && (t <= direction.squaredMagnitude())) {
+
+ // The point falls within the segment. Normalize direction,
+ // divide t by the length of direction.
+ return _point + direction * t / direction.squaredMagnitude();
+
+ } else {
+
+ // The point does not fall within the segment; see which end is closer.
+
+ // Distance from 0, squared
+ float d0Squared = v.squaredMagnitude();
+
+ // Distance from 1, squared
+ float d1Squared = (v - direction).squaredMagnitude();
+
+ if (d0Squared < d1Squared) {
+
+ // Point 0 is closer
+ return _point;
+
+ } else {
+
+ // Point 1 is closer
+ return _point + direction;
+
+ }
+ }
+
+}
+
+Vector3 LineSegment::point(int i) const {
+ switch (i) {
+ case 0:
+ return _point;
+
+ case 1:
+ return _point + direction;
+
+ default:
+ debugAssertM(i == 0 || i == 1, "Argument to point must be 0 or 1");
+ return _point;
+ }
+}
+
+
+bool LineSegment::intersectsSolidSphere(const class Sphere& s) const {
+ return distanceSquared(s.center) <= square(s.radius);
+}
+
+
+LineSegment::LineSegment(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void LineSegment::serialize(class BinaryOutput& b) const {
+ _point.serialize(b);
+ direction.serialize(b);
+}
+
+
+void LineSegment::deserialize(class BinaryInput& b) {
+ _point.deserialize(b);
+ direction.deserialize(b);
+}
+
+
+Vector3 LineSegment::randomPoint() const {
+ return _point + uniformRandom(0, 1) * direction;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+LineSegment2D LineSegment2D::fromTwoPoints(const Vector2& p0, const Vector2& p1) {
+ LineSegment2D s;
+ s.m_origin = p0;
+ s.m_direction = p1 - p0;
+ s.m_length = s.m_direction.length();
+ return s;
+}
+
+
+Vector2 LineSegment2D::point(int i) const {
+ debugAssert(i == 0 || i == 1);
+ if (i == 0) {
+ return m_origin;
+ } else {
+ return m_direction + m_origin;
+ }
+}
+
+
+Vector2 LineSegment2D::closestPoint(const Vector2& Q) const {
+ // Two constants that appear in the result
+ const Vector2 k1(m_origin - Q);
+ const Vector2& k2 = m_direction;
+
+ if (fuzzyEq(m_length, 0)) {
+ // This line segment has no length
+ return m_origin;
+ }
+
+ // Time [0, 1] at which we hit the closest point travelling from p0 to p1.
+ // Derivation can be obtained by minimizing the expression
+ // ||P0 + (P1 - P0)t - Q||.
+ const float t = -k1.dot(k2) / (m_length * m_length);
+
+ if (t < 0) {
+ // Clipped to low end point
+ return m_origin;
+ } else if (t > 1) {
+ // Clipped to high end point
+ return m_origin + m_direction;
+ } else {
+ // Subsitute into the line equation to find
+ // the point on the segment.
+ return m_origin + k2 * t;
+ }
+}
+
+
+float LineSegment2D::distance(const Vector2& p) const {
+ Vector2 closest = closestPoint(p);
+ return (closest - p).length();
+}
+
+
+float LineSegment2D::length() const {
+ return m_length;
+}
+
+
+Vector2 LineSegment2D::intersection(const LineSegment2D& other) const {
+
+ if ((m_origin == other.m_origin) ||
+ (m_origin == other.m_origin + other.m_direction)) {
+ return m_origin;
+ }
+
+ if (m_origin + m_direction == other.m_origin) {
+ return other.m_origin;
+ }
+
+ // Note: Now that we've checked the endpoints, all other parallel lines can now be assumed
+ // to not intersect (within numerical precision)
+
+ Vector2 dir1 = m_direction;
+ Vector2 dir2 = other.m_direction;
+ Vector2 origin1 = m_origin;
+ Vector2 origin2 = other.m_origin;
+
+ if (dir1.x == 0) {
+ // Avoid an upcoming divide by zero
+ dir1 = dir1.yx();
+ dir2 = dir2.yx();
+ origin1 = origin1.yx();
+ origin2 = origin2.yx();
+ }
+
+ // t1 = ((other.m_origin.x - m_origin.x) + other.m_direction.x * t2) / m_direction.x
+ //
+ // ((other.m_origin.x - m_origin.x) + other.m_direction.x * t2) * m_direction.y / m_direction.x =
+ // (other.m_origin.y - m_origin.y) + other.m_direction.y * t2
+ //
+ // m = m_direction.y / m_direction.x
+ // d = other.m_origin - m_origin
+ //
+ // (d.x + other.m_direction.x * t2) * m = d.y + other.m_direction.y * t2
+ //
+ // d.x * m + other.m_direction.x * m * t2 = d.y + other.m_direction.y * t2
+ //
+ // d.x * m - d.y = (other.m_direction.y - other.m_direction.x * m) * t2
+ //
+ // (d.x * m - d.y) / (other.m_direction.y - other.m_direction.x * m) = t2
+ //
+
+ Vector2 d = origin2 - origin1;
+ float m = dir1.y / dir1.x;
+
+ float t2 = (d.x * m - d.y) / (dir2.y - dir2.x * m);
+ if (! isFinite(t2)) {
+ // Parallel lines: no intersection
+ return Vector2::inf();
+ }
+
+ if ((t2 < 0.0f) || (t2 > 1.0f)) {
+ // Intersection occurs past the end of the line segments
+ return Vector2::inf();
+ }
+
+ float t1 = (d.x + dir2.x * t2) / dir1.x;
+ if ((t1 < 0.0f) || (t1 > 1.0f)) {
+ // Intersection occurs past the end of the line segments
+ return Vector2::inf();
+ }
+
+ // Return the intersection point (computed from non-transposed
+ // variables even if we flipped above)
+ return m_origin + m_direction * t1;
+
+}
+
+}
+
diff --git a/dep/src/g3dlite/Log.cpp b/dep/src/g3dlite/Log.cpp
new file mode 100644
index 00000000000..07614fcf563
--- /dev/null
+++ b/dep/src/g3dlite/Log.cpp
@@ -0,0 +1,146 @@
+/**
+ @file Log.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2001-08-04
+ @edited 2009-01-15
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Log.h"
+#include "G3D/format.h"
+#include "G3D/Array.h"
+#include "G3D/fileutils.h"
+#include <time.h>
+
+#ifdef G3D_WIN32
+ #include <imagehlp.h>
+#else
+ #include <stdarg.h>
+#endif
+
+namespace G3D {
+
+void logPrintf(const char* fmt, ...) {
+ va_list arg_list;
+ va_start(arg_list, fmt);
+ Log::common()->vprintf(fmt, arg_list);
+ va_end(arg_list);
+}
+
+
+void logLazyPrintf(const char* fmt, ...) {
+ va_list arg_list;
+ va_start(arg_list, fmt);
+ Log::common()->lazyvprintf(fmt, arg_list);
+ va_end(arg_list);
+}
+
+Log* Log::commonLog = NULL;
+
+Log::Log(const std::string& filename, int stripFromStackBottom) :
+ stripFromStackBottom(stripFromStackBottom) {
+
+ this->filename = filename;
+
+ logFile = fopen(filename.c_str(), "w");
+
+ if (logFile == NULL) {
+ std::string drive, base, ext;
+ Array<std::string> path;
+ parseFilename(filename, drive, path, base, ext);
+ std::string logName = base + ((ext != "") ? ("." + ext) : "");
+
+ // Write time is greater than 1ms. This may be a network drive.... try another file.
+ #ifdef G3D_WIN32
+ logName = std::string(std::getenv("TEMP")) + logName;
+ #else
+ logName = std::string("/tmp/") + logName;
+ #endif
+
+ logFile = fopen(logName.c_str(), "w");
+ }
+
+ // Use a large buffer (although we flush in logPrintf)
+ setvbuf(logFile, NULL, _IOFBF, 2048);
+
+ fprintf(logFile, "Application Log\n");
+ time_t t;
+ time(&t);
+ fprintf(logFile, "Start: %s\n", ctime(&t));
+ fflush(logFile);
+
+ if (commonLog == NULL) {
+ commonLog = this;
+ }
+}
+
+
+Log::~Log() {
+ section("Shutdown");
+ println("Closing log file");
+
+ // Make sure we don't leave a dangling pointer
+ if (Log::commonLog == this) {
+ Log::commonLog = NULL;
+ }
+
+ fclose(logFile);
+}
+
+
+FILE* Log::getFile() const {
+ return logFile;
+}
+
+
+Log* Log::common() {
+ if (commonLog == NULL) {
+ commonLog = new Log();
+ }
+ return commonLog;
+}
+
+
+std::string Log::getCommonLogFilename() {
+ return common()->filename;
+}
+
+
+void Log::section(const std::string& s) {
+ fprintf(logFile, "_____________________________________________________\n");
+ fprintf(logFile, "\n ### %s ###\n\n", s.c_str());
+}
+
+
+void __cdecl Log::printf(const char* fmt, ...) {
+ va_list arg_list;
+ va_start(arg_list, fmt);
+ print(vformat(fmt, arg_list));
+ va_end(arg_list);
+}
+
+
+void __cdecl Log::vprintf(const char* fmt, va_list argPtr) {
+ vfprintf(logFile, fmt, argPtr);
+ fflush(logFile);
+}
+
+
+void __cdecl Log::lazyvprintf(const char* fmt, va_list argPtr) {
+ vfprintf(logFile, fmt, argPtr);
+}
+
+
+void Log::print(const std::string& s) {
+ fprintf(logFile, "%s", s.c_str());
+ fflush(logFile);
+}
+
+
+void Log::println(const std::string& s) {
+ fprintf(logFile, "%s\n", s.c_str());
+ fflush(logFile);
+}
+
+}
diff --git a/dep/src/g3dlite/Makefile.am b/dep/src/g3dlite/Makefile.am
new file mode 100644
index 00000000000..d37528b4c72
--- /dev/null
+++ b/dep/src/g3dlite/Makefile.am
@@ -0,0 +1,69 @@
+## Modified for MaNGOS project <http://getmangos.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
+## 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.
+
+## Process this file with automake to produce Makefile.in
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/../../include -I$(srcdir)/../../include/g3dlite
+
+noinst_LIBRARIES = libg3dlite.a
+libg3dlite_a_SOURCES = \
+ AABox.cpp \
+ Box.cpp \
+ Crypto.cpp \
+ format.cpp \
+ Matrix3.cpp \
+ Plane.cpp \
+ System.cpp \
+ Triangle.cpp \
+ Vector3.cpp \
+ Vector4.cpp \
+ debugAssert.cpp \
+ fileutils.cpp \
+ g3dmath.cpp \
+ g3dfnmatch.cpp \
+ prompt.cpp \
+ stringutils.cpp \
+ Any.cpp \
+ BinaryFormat.cpp \
+ BinaryInput.cpp \
+ BinaryOutput.cpp \
+ Capsule.cpp \
+ CollisionDetection.cpp \
+ CoordinateFrame.cpp \
+ Cylinder.cpp \
+ Line.cpp \
+ LineSegment.cpp \
+ Log.cpp \
+ Matrix4.cpp \
+ MemoryManager.cpp \
+ Quat.cpp \
+ Random.cpp \
+ Ray.cpp \
+ ReferenceCount.cpp \
+ Sphere.cpp \
+ TextInput.cpp \
+ TextOutput.cpp \
+ UprightFrame.cpp \
+ Vector2.cpp
+
+EXTRA_DIST = \
+ license.html
+
+
diff --git a/dep/src/g3dlite/Matrix.cpp b/dep/src/g3dlite/Matrix.cpp
new file mode 100644
index 00000000000..7a668e59e2c
--- /dev/null
+++ b/dep/src/g3dlite/Matrix.cpp
@@ -0,0 +1,1802 @@
+/**
+ @file Matrix.cpp
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ */
+#include "G3D/Matrix.h"
+#include "G3D/TextOutput.h"
+
+static inline G3D::Matrix::T negate(G3D::Matrix::T x) {
+ return -x;
+}
+
+namespace G3D {
+
+int Matrix::debugNumCopyOps = 0;
+int Matrix::debugNumAllocOps = 0;
+
+void Matrix::serialize(TextOutput& t) const {
+ t.writeSymbol("%");
+ t.writeNumber(rows());
+ t.writeSymbol("x");
+ t.writeNumber(cols());
+ t.pushIndent();
+ t.writeNewline();
+
+ t.writeSymbol("[");
+ for (int r = 0; r < rows(); ++r) {
+ for (int c = 0; c < cols(); ++c) {
+ t.writeNumber(impl->get(r, c));
+ if (c < cols() - 1) {
+ t.writeSymbol(",");
+ } else {
+ if (r < rows() - 1) {
+ t.writeSymbol(";");
+ t.writeNewline();
+ }
+ }
+ }
+ }
+ t.writeSymbol("]");
+ t.popIndent();
+ t.writeNewline();
+}
+
+
+std::string Matrix::toString(const std::string& name) const {
+ std::string s;
+
+ if (name != "") {
+ s += format("%s = \n", name.c_str());
+ }
+
+ s += "[";
+ for (int r = 0; r < rows(); ++r) {
+ for (int c = 0; c < cols(); ++c) {
+ double v = impl->get(r, c);
+
+ if (::fabs(v) < 0.00001) {
+ // Don't print "negative zero"
+ s += format("% 10.04g", 0.0);
+ } else if (v == iRound(v)) {
+ // Print integers nicely
+ s += format("% 10.04g", v);
+ } else {
+ s += format("% 10.04f", v);
+ }
+
+ if (c < cols() - 1) {
+ s += ",";
+ } else if (r < rows() - 1) {
+ s += ";\n ";
+ } else {
+ s += "]\n";
+ }
+ }
+ }
+ return s;
+}
+
+
+#define INPLACE(OP)\
+ ImplRef A = impl;\
+\
+ if (! A.isLastReference()) {\
+ impl = new Impl(A->R, A->C);\
+ }\
+\
+ A->OP(B, *impl);
+
+Matrix& Matrix::operator*=(const T& B) {
+ INPLACE(mul)
+ return *this;
+}
+
+
+Matrix& Matrix::operator-=(const T& B) {
+ INPLACE(sub)
+ return *this;
+}
+
+
+Matrix& Matrix::operator+=(const T& B) {
+ INPLACE(add)
+ return *this;
+}
+
+
+Matrix& Matrix::operator/=(const T& B) {
+ INPLACE(div)
+ return *this;
+}
+
+
+Matrix& Matrix::operator*=(const Matrix& B) {
+ // We can't optimize this one
+ *this = *this * B;
+ return *this;
+}
+
+
+Matrix& Matrix::operator-=(const Matrix& _B) {
+ const Impl& B = *_B.impl;
+ INPLACE(sub)
+ return *this;
+}
+
+
+Matrix& Matrix::operator+=(const Matrix& _B) {
+ const Impl& B = *_B.impl;
+ INPLACE(add)
+ return *this;
+}
+
+
+void Matrix::arrayMulInPlace(const Matrix& _B) {
+ const Impl& B = *_B.impl;
+ INPLACE(arrayMul)
+}
+
+
+void Matrix::arrayDivInPlace(const Matrix& _B) {
+ const Impl& B = *_B.impl;
+ INPLACE(arrayDiv)
+}
+
+#undef INPLACE
+
+Matrix Matrix::fromDiagonal(const Matrix& d) {
+ debugAssert((d.rows() == 1) || (d.cols() == 1));
+
+ int n = d.numElements();
+ Matrix D = zero(n, n);
+ for (int i = 0; i < n; ++i) {
+ D.set(i, i, d.impl->data[i]);
+ }
+
+ return D;
+}
+
+void Matrix::set(int r, int c, T v) {
+ if (! impl.isLastReference()) {
+ // Copy the data before mutating; this object is shared
+ impl = new Impl(*impl);
+ }
+ impl->set(r, c, v);
+}
+
+
+void Matrix::setRow(int r, const Matrix& vec) {
+ debugAssertM(vec.cols() == cols(),
+ "A row must be set to a vector of the same size.");
+ debugAssertM(vec.rows() == 1,
+ "A row must be set to a row vector.");
+
+ debugAssert(r >= 0);
+ debugAssert(r < rows());
+
+ if (! impl.isLastReference()) {
+ // Copy the data before mutating; this object is shared
+ impl = new Impl(*impl);
+ }
+ impl->setRow(r, vec.impl->data);
+}
+
+
+void Matrix::setCol(int c, const Matrix& vec) {
+ debugAssertM(vec.rows() == rows(),
+ "A column must be set to a vector of the same size.");
+ debugAssertM(vec.cols() == 1,
+ "A column must be set to a column vector.");
+
+ debugAssert(c >= 0);
+
+ debugAssert(c < cols());
+
+ if (! impl.isLastReference()) {
+ // Copy the data before mutating; this object is shared
+ impl = new Impl(*impl);
+ }
+ impl->setCol(c, vec.impl->data);
+}
+
+
+Matrix::T Matrix::get(int r, int c) const {
+ return impl->get(r, c);
+}
+
+
+Matrix Matrix::row(int r) const {
+ debugAssert(r >= 0);
+ debugAssert(r < rows());
+ Matrix out(1, cols());
+ out.impl->setRow(1, impl->elt[r]);
+ return out;
+}
+
+
+Matrix Matrix::col(int c) const {
+ debugAssert(c >= 0);
+ debugAssert(c < cols());
+ Matrix out(rows(), 1);
+
+ T* outData = out.impl->data;
+ // Get a pointer to the first element in the column
+ const T* inElt = &(impl->elt[0][c]);
+ int R = rows();
+ int C = cols();
+ for (int r = 0; r < R; ++r) {
+ outData[r] = *inElt;
+ // Skip around to the next row
+ inElt += C;
+ }
+
+ return out;
+}
+
+
+Matrix Matrix::zero(int R, int C) {
+ Impl* A = new Impl(R, C);
+ A->setZero();
+ return Matrix(A);
+}
+
+
+Matrix Matrix::one(int R, int C) {
+ Impl* A = new Impl(R, C);
+ for (int i = R * C - 1; i >= 0; --i) {
+ A->data[i] = 1.0;
+ }
+ return Matrix(A);
+}
+
+
+Matrix Matrix::random(int R, int C) {
+ Impl* A = new Impl(R, C);
+ for (int i = R * C - 1; i >= 0; --i) {
+ A->data[i] = G3D::uniformRandom(0.0, 1.0);
+ }
+ return Matrix(A);
+}
+
+
+Matrix Matrix::identity(int N) {
+ Impl* m = new Impl(N, N);
+ m->setZero();
+ for (int i = 0; i < N; ++i) {
+ m->elt[i][i] = 1.0;
+ }
+ return Matrix(m);
+}
+
+
+// Implement an explicit-output unary method by trampolining to the impl
+#define TRAMPOLINE_EXPLICIT_1(method)\
+void Matrix::method(Matrix& out) const {\
+ if ((out.impl == impl) && impl.isLastReference()) {\
+ impl->method(*out.impl);\
+ } else {\
+ out = this->method();\
+ }\
+}
+
+TRAMPOLINE_EXPLICIT_1(abs)
+TRAMPOLINE_EXPLICIT_1(negate)
+TRAMPOLINE_EXPLICIT_1(arrayLog)
+TRAMPOLINE_EXPLICIT_1(arrayExp)
+TRAMPOLINE_EXPLICIT_1(arrayCos)
+TRAMPOLINE_EXPLICIT_1(arraySin)
+
+void Matrix::mulRow(int r, const T& v) {
+ debugAssert(r >= 0 && r < rows());
+
+ if (! impl.isLastReference()) {
+ impl = new Impl(*impl);
+ }
+
+ impl->mulRow(r, v);
+}
+
+
+void Matrix::transpose(Matrix& out) const {
+ if ((out.impl == impl) && impl.isLastReference() && (impl->R == impl->C)) {
+ // In place
+ impl->transpose(*out.impl);
+ } else {
+ out = this->transpose();
+ }
+}
+
+
+Matrix3 Matrix::toMatrix3() const {
+ debugAssert(impl->R == 3);
+ debugAssert(impl->C == 3);
+ return Matrix3(
+ impl->get(0,0), impl->get(0,1), impl->get(0,2),
+ impl->get(1,0), impl->get(1,1), impl->get(1,2),
+ impl->get(2,0), impl->get(2,1), impl->get(2,2));
+}
+
+
+Matrix4 Matrix::toMatrix4() const {
+ debugAssert(impl->R == 4);
+ debugAssert(impl->C == 4);
+ return Matrix4(
+ impl->get(0,0), impl->get(0,1), impl->get(0,2), impl->get(0,3),
+ impl->get(1,0), impl->get(1,1), impl->get(1,2), impl->get(1,3),
+ impl->get(2,0), impl->get(2,1), impl->get(2,2), impl->get(2,3),
+ impl->get(3,0), impl->get(3,1), impl->get(3,2), impl->get(3,3));
+}
+
+
+Vector2 Matrix::toVector2() const {
+ debugAssert(impl->R * impl->C == 2);
+ if (impl->R > impl->C) {
+ return Vector2(impl->get(0,0), impl->get(1,0));
+ } else {
+ return Vector2(impl->get(0,0), impl->get(0,1));
+ }
+}
+
+
+Vector3 Matrix::toVector3() const {
+ debugAssert(impl->R * impl->C == 3);
+ if (impl->R > impl->C) {
+ return Vector3(impl->get(0,0), impl->get(1,0), impl->get(2, 0));
+ } else {
+ return Vector3(impl->get(0,0), impl->get(0,1), impl->get(0, 2));
+ }
+}
+
+
+Vector4 Matrix::toVector4() const {
+ debugAssert(
+ ((impl->R == 4) && (impl->C == 1)) ||
+ ((impl->R == 1) && (impl->C == 4)));
+
+ if (impl->R > impl->C) {
+ return Vector4(impl->get(0,0), impl->get(1,0), impl->get(2, 0), impl->get(3,0));
+ } else {
+ return Vector4(impl->get(0,0), impl->get(0,1), impl->get(0, 2), impl->get(0,3));
+ }
+}
+
+
+void Matrix::swapRows(int r0, int r1) {
+ debugAssert(r0 >= 0 && r0 < rows());
+ debugAssert(r1 >= 0 && r1 < rows());
+
+ if (r0 == r1) {
+ return;
+ }
+
+ if (! impl.isLastReference()) {
+ impl = new Impl(*impl);
+ }
+
+ impl->swapRows(r0, r1);
+}
+
+
+void Matrix::swapAndNegateCols(int c0, int c1) {
+ debugAssert(c0 >= 0 && c0 < cols());
+ debugAssert(c1 >= 0 && c1 < cols());
+
+ if (c0 == c1) {
+ return;
+ }
+
+ if (! impl.isLastReference()) {
+ impl = new Impl(*impl);
+ }
+
+ impl->swapAndNegateCols(c0, c1);
+}
+
+Matrix Matrix::subMatrix(int r1, int r2, int c1, int c2) const {
+ debugAssert(r2>=r1);
+ debugAssert(c2>=c1);
+ debugAssert(c2<cols());
+ debugAssert(r2<rows());
+ debugAssert(r1>=0);
+ debugAssert(c1>=0);
+
+ Matrix X(r2 - r1 + 1, c2 - c1 + 1);
+
+ for (int r = 0; r < X.rows(); ++r) {
+ for (int c = 0; c < X.cols(); ++c) {
+ X.set(r, c, get(r + r1, c + c1));
+ }
+ }
+
+ return X;
+}
+
+
+bool Matrix::anyNonZero() const {
+ return impl->anyNonZero();
+}
+
+
+bool Matrix::allNonZero() const {
+ return impl->allNonZero();
+}
+
+
+void Matrix::svd(Matrix& U, Array<T>& d, Matrix& V, bool sort) const {
+ debugAssert(rows() >= cols());
+ debugAssertM(&U != &V, "Arguments to SVD must be different matrices");
+ debugAssertM(&U != this, "Arguments to SVD must be different matrices");
+ debugAssertM(&V != this, "Arguments to SVD must be different matrices");
+
+ int R = rows();
+ int C = cols();
+
+ // Make sure we don't overwrite a shared matrix
+ if (! V.impl.isLastReference()) {
+ V = Matrix::zero(C, C);
+ } else {
+ V.impl->setSize(C, C);
+ }
+
+ if (&U != this || ! impl.isLastReference()) {
+ // Make a copy of this for in-place SVD
+ U.impl = new Impl(*impl);
+ }
+
+ d.resize(C);
+ const char* ret = svdCore(U.impl->elt, R, C, d.getCArray(), V.impl->elt);
+
+ debugAssertM(ret == NULL, ret);
+ (void)ret;
+
+ if (sort) {
+ // Sort the singular values from greatest to least
+
+ Array<SortRank> rank;
+ rank.resize(C);
+ for (int c = 0; c < C; ++c) {
+ rank[c].col = c;
+ rank[c].value = d[c];
+ }
+
+ rank.sort(SORT_INCREASING);
+
+ Matrix Uold = U;
+ Matrix Vold = V;
+
+ U = Matrix(U.rows(), U.cols());
+ V = Matrix(V.rows(), V.cols());
+
+ // Now permute U, d, and V appropriately
+ for (int c0 = 0; c0 < C; ++c0) {
+ const int c1 = rank[c0].col;
+
+ d[c0] = rank[c0].value;
+ U.setCol(c0, Uold.col(c1));
+ V.setCol(c0, Vold.col(c1));
+ }
+
+ }
+}
+
+
+#define COMPARE_SCALAR(OP)\
+Matrix Matrix::operator OP (const T& scalar) const {\
+ int R = rows();\
+ int C = cols();\
+ int N = R * C;\
+ Matrix out = Matrix::zero(R, C);\
+\
+ const T* raw = impl->data;\
+ T* outRaw = out.impl->data;\
+ for (int i = 0; i < N; ++i) {\
+ outRaw[i] = raw[i] OP scalar;\
+ }\
+\
+ return out;\
+}
+
+COMPARE_SCALAR(<)
+COMPARE_SCALAR(<=)
+COMPARE_SCALAR(>)
+COMPARE_SCALAR(>=)
+COMPARE_SCALAR(==)
+COMPARE_SCALAR(!=)
+
+#undef COMPARE_SCALAR
+
+double Matrix::normSquared() const {
+ int R = rows();
+ int C = cols();
+ int N = R * C;
+
+ double sum = 0.0;
+
+ const T* raw = impl->data;
+ for (int i = 0; i < N; ++i) {
+ sum += square(raw[i]);
+ }
+
+ return sum;
+}
+
+double Matrix::norm() const {
+ return sqrt(normSquared());
+}
+
+///////////////////////////////////////////////////////////
+
+Matrix::Impl::Impl(const Matrix3& M) : elt(NULL), data(NULL), R(0), C(0), dataSize(0){
+ setSize(3, 3);
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ set(r, c, M[r][c]);
+ }
+ }
+
+}
+
+
+Matrix::Impl::Impl(const Matrix4& M): elt(NULL), data(NULL), R(0), C(0), dataSize(0) {
+ setSize(4, 4);
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ set(r, c, M[r][c]);
+ }
+ }
+}
+
+
+void Matrix::Impl::setSize(int newRows, int newCols) {
+ if ((R == newRows) && (C == newCols)) {
+ // Nothing to do
+ return;
+ }
+
+ int newSize = newRows * newCols;
+
+ R = newRows; C = newCols;
+
+ // Only allocate if we need more space
+ // or the size difference is ridiculous
+ if ((newSize > dataSize) || (newSize < dataSize / 4)) {
+ System::alignedFree(data);
+ data = (float*)System::alignedMalloc(R * C * sizeof(T), 16);
+ ++Matrix::debugNumAllocOps;
+ dataSize = newSize;
+ }
+
+ // Construct the row pointers
+ //delete[] elt;
+ System::free(elt);
+ elt = (T**)System::malloc(R * sizeof(T*));// new T*[R];
+
+ for (int r = 0; r < R; ++ r) {
+ elt[r] = data + r * C;
+ }
+}
+
+
+Matrix::Impl::~Impl() {
+ //delete[] elt;
+ System::free(elt);
+ System::alignedFree(data);
+}
+
+
+Matrix::Impl& Matrix::Impl::operator=(const Impl& m) {
+ setSize(m.R, m.C);
+ System::memcpy(data, m.data, R * C * sizeof(T));
+ ++Matrix::debugNumCopyOps;
+ return *this;
+}
+
+
+void Matrix::Impl::setZero() {
+ System::memset(data, 0, R * C * sizeof(T));
+}
+
+
+void Matrix::Impl::swapRows(int r0, int r1) {
+ T* R0 = elt[r0];
+ T* R1 = elt[r1];
+
+ for (int c = 0; c < C; ++c) {
+ T temp = R0[c];
+ R0[c] = R1[c];
+ R1[c] = temp;
+ }
+}
+
+
+void Matrix::Impl::swapAndNegateCols(int c0, int c1) {
+ for (int r = 0; r < R; ++r) {
+ T* row = elt[r];
+
+ const T temp = -row[c0];
+ row[c0] = -row[c1];
+ row[c1] = temp;
+ }
+}
+
+
+void Matrix::Impl::mulRow(int r, const T& v) {
+ T* row = elt[r];
+
+ for (int c = 0; c < C; ++c) {
+ row[c] *= v;
+ }
+}
+
+
+void Matrix::Impl::mul(const Impl& B, Impl& out) const {
+ const Impl& A = *this;
+
+ debugAssertM(
+ (this != &out) && (&B != &out),
+ "Output argument to mul cannot be the same as an input argument.");
+
+ debugAssert(A.C == B.R);
+ debugAssert(A.R == out.R);
+ debugAssert(B.C == out.C);
+
+ for (int r = 0; r < out.R; ++r) {
+ for (int c = 0; c < out.C; ++c) {
+ T sum = 0.0;
+ for (int i = 0; i < A.C; ++i) {
+ sum += A.get(r, i) * B.get(i, c);
+ }
+ out.set(r, c, sum);
+ }
+ }
+}
+
+
+// We're about to define several similar methods,
+// so use a macro to share implementations. This
+// must be a macro because the difference between
+// the macros is the operation in the inner loop.
+#define IMPLEMENT_ARRAY_2(method, OP)\
+void Matrix::Impl::method(const Impl& B, Impl& out) const {\
+ const Impl& A = *this;\
+ \
+ debugAssert(A.C == B.C);\
+ debugAssert(A.R == B.R);\
+ debugAssert(A.C == out.C);\
+ debugAssert(A.R == out.R);\
+ \
+ for (int i = R * C - 1; i >= 0; --i) {\
+ out.data[i] = A.data[i] OP B.data[i];\
+ }\
+}
+
+
+#define IMPLEMENT_ARRAY_1(method, f)\
+void Matrix::Impl::method(Impl& out) const {\
+ const Impl& A = *this;\
+ \
+ debugAssert(A.C == out.C);\
+ debugAssert(A.R == out.R);\
+ \
+ for (int i = R * C - 1; i >= 0; --i) {\
+ out.data[i] = f(A.data[i]);\
+ }\
+}
+
+
+#define IMPLEMENT_ARRAY_SCALAR(method, OP)\
+void Matrix::Impl::method(Matrix::T B, Impl& out) const {\
+ const Impl& A = *this;\
+ \
+ debugAssert(A.C == out.C);\
+ debugAssert(A.R == out.R);\
+ \
+ for (int i = R * C - 1; i >= 0; --i) {\
+ out.data[i] = A.data[i] OP B;\
+ }\
+}
+
+IMPLEMENT_ARRAY_2(add, +)
+IMPLEMENT_ARRAY_2(sub, -)
+IMPLEMENT_ARRAY_2(arrayMul, *)
+IMPLEMENT_ARRAY_2(arrayDiv, /)
+
+IMPLEMENT_ARRAY_SCALAR(add, +)
+IMPLEMENT_ARRAY_SCALAR(sub, -)
+IMPLEMENT_ARRAY_SCALAR(mul, *)
+IMPLEMENT_ARRAY_SCALAR(div, /)
+
+IMPLEMENT_ARRAY_1(abs, ::fabs)
+IMPLEMENT_ARRAY_1(negate, ::negate)
+IMPLEMENT_ARRAY_1(arrayLog, ::log)
+IMPLEMENT_ARRAY_1(arraySqrt, ::sqrt)
+IMPLEMENT_ARRAY_1(arrayExp, ::exp)
+IMPLEMENT_ARRAY_1(arrayCos, ::cos)
+IMPLEMENT_ARRAY_1(arraySin, ::sin)
+
+#undef IMPLEMENT_ARRAY_SCALAR
+#undef IMPLEMENT_ARRAY_1
+#undef IMPLEMENT_ARRAY_2
+
+// lsub is special because the argument order is reversed
+void Matrix::Impl::lsub(Matrix::T B, Impl& out) const {
+ const Impl& A = *this;
+
+ debugAssert(A.C == out.C);
+ debugAssert(A.R == out.R);
+
+ for (int i = R * C - 1; i >= 0; --i) {
+ out.data[i] = B - A.data[i];
+ }
+}
+
+
+void Matrix::Impl::inverseViaAdjoint(Impl& out) const {
+ debugAssert(&out != this);
+
+ // Inverse = adjoint / determinant
+
+ adjoint(out);
+
+ // Don't call the determinant method when we already have an
+ // adjoint matrix; there's a faster way of computing it: the dot
+ // product of the first row and the adjoint's first col.
+ double det = 0.0;
+ for (int r = R - 1; r >= 0; --r) {
+ det += elt[0][r] * out.elt[r][0];
+ }
+
+ out.div(Matrix::T(det), out);
+}
+
+
+void Matrix::Impl::transpose(Impl& out) const {
+ debugAssert(out.R == C);
+ debugAssert(out.C == R);
+
+ if (&out == this) {
+ // Square matrix in place
+ for (int r = 0; r < R; ++r) {
+ for (int c = r + 1; c < C; ++c) {
+ T temp = get(r, c);
+ out.set(r, c, get(c, r));
+ out.set(c, r, temp);
+ }
+ }
+ } else {
+ for (int r = 0; r < R; ++r) {
+ for (int c = 0; c < C; ++c) {
+ out.set(c, r, get(r, c));
+ }
+ }
+ }
+}
+
+
+void Matrix::Impl::adjoint(Impl& out) const {
+ cofactor(out);
+ // Transpose is safe to perform in place
+ out.transpose(out);
+}
+
+
+void Matrix::Impl::cofactor(Impl& out) const {
+ debugAssert(&out != this);
+ for(int r = 0; r < R; ++r) {
+ for(int c = 0; c < C; ++c) {
+ out.set(r, c, cofactor(r, c));
+ }
+ }
+}
+
+
+Matrix::T Matrix::Impl::cofactor(int r, int c) const {
+ // Strang p. 217
+ float s = isEven(r + c) ? 1.0f : -1.0f;
+
+ return s * determinant(r, c);
+}
+
+
+Matrix::T Matrix::Impl::determinant(int nr, int nc) const {
+ debugAssert(R > 0);
+ debugAssert(C > 0);
+ Impl A(R - 1, C - 1);
+ withoutRowAndCol(nr, nc, A);
+ return A.determinant();
+}
+
+
+void Matrix::Impl::setRow(int r, const T* vals) {
+ debugAssert(r >= 0);
+ System::memcpy(elt[r], vals, sizeof(T) * C);
+}
+
+
+void Matrix::Impl::setCol(int c, const T* vals) {
+ for (int r = 0; r < R; ++r) {
+ elt[r][c] = vals[r];
+ }
+}
+
+
+Matrix::T Matrix::Impl::determinant() const {
+
+ debugAssert(R == C);
+
+ // Compute using cofactors
+ switch(R) {
+ case 0:
+ return 0;
+
+ case 1:
+ // Determinant of a 1x1 is the element
+ return elt[0][0];
+
+ case 2:
+ // Determinant of a 2x2 is ad-bc
+ return elt[0][0] * elt[1][1] - elt[0][1] * elt[1][0];
+
+ case 3:
+ {
+ // Determinant of an nxn matrix is the dot product of the first
+ // row with the first row of cofactors. The base cases of this
+ // method get called a lot, so we spell out the implementation
+ // for the 3x3 case.
+
+ float cofactor00 = elt[1][1] * elt[2][2] - elt[1][2] * elt[2][1];
+ float cofactor10 = elt[1][2] * elt[2][0] - elt[1][0] * elt[2][2];
+ float cofactor20 = elt[1][0] * elt[2][1] - elt[1][1] * elt[2][0];
+
+ return Matrix::T(
+ elt[0][0] * cofactor00 +
+ elt[0][1] * cofactor10 +
+ elt[0][2] * cofactor20);
+ }
+
+ default:
+ {
+ // Determinant of an n x n matrix is the dot product of the first
+ // row with the first row of cofactors
+ T det = 0;
+
+ for (int c = 0; c < C; ++c) {
+ det += elt[0][c] * cofactor(0, c);
+ }
+
+ return det;
+ }
+ }
+}
+
+
+void Matrix::Impl::withoutRowAndCol(int excludeRow, int excludeCol, Impl& out) const {
+ debugAssert(out.R == R - 1);
+ debugAssert(out.C == C - 1);
+
+ for (int r = 0; r < out.R; ++r) {
+ for (int c = 0; c < out.C; ++c) {
+ out.elt[r][c] = elt[r + ((r >= excludeRow) ? 1 : 0)][c + ((c >= excludeCol) ? 1 : 0)];
+ }
+ }
+}
+
+
+Matrix Matrix::pseudoInverse(float tolerance) const {
+ if ((cols() == 1) || (rows() == 1)) {
+ return vectorPseudoInverse();
+ } else if ((cols() <= 4) || (rows() <= 4)) {
+ return partitionPseudoInverse();
+ } else {
+ return svdPseudoInverse(tolerance);
+ }
+}
+
+/*
+ Public function for testing purposes only. Use pseudoInverse(), as it contains optimizations for
+ nonsingular matrices with at least one small (<5) dimension.
+*/
+Matrix Matrix::svdPseudoInverse(float tolerance) const {
+ if (cols() > rows()) {
+ return transpose().svdPseudoInverse(tolerance).transpose();
+ }
+
+ // Matrices from SVD
+ Matrix U, V;
+
+ // Diagonal elements
+ Array<T> d;
+
+ svd(U, d, V);
+
+ if (rows() == 1) {
+ d.resize(1, false);
+ }
+
+ if (tolerance < 0) {
+ // TODO: Should be eps(d[0]), which is the largest diagonal
+ tolerance = G3D::max(rows(), cols()) * 0.0001f;
+ }
+
+ Matrix X;
+
+ int r = 0;
+ for (int i = 0; i < d.size(); ++i) {
+ if (d[i] > tolerance) {
+ d[i] = Matrix::T(1) / d[i];
+ ++r;
+ }
+ }
+
+ if (r == 0) {
+ // There were no non-zero elements
+ X = zero(cols(), rows());
+ } else {
+ // Use the first r columns
+
+ // Test code (the rest is below)
+ /*
+ d.resize(r);
+ Matrix testU = U.subMatrix(0, U.rows() - 1, 0, r - 1);
+ Matrix testV = V.subMatrix(0, V.rows() - 1, 0, r - 1);
+ Matrix testX = testV * Matrix::fromDiagonal(d) * testU.transpose();
+ X = testX;
+ */
+
+
+ // We want to do this:
+ //
+ // d.resize(r);
+ // U = U.subMatrix(0, U.rows() - 1, 0, r - 1);
+ // X = V * Matrix::fromDiagonal(d) * U.transpose();
+ //
+ // but creating a large diagonal matrix and then
+ // multiplying by it is wasteful. So we instead
+ // explicitly perform A = (D * U')' = U * D, and
+ // then multiply X = V * A'.
+
+ Matrix A = Matrix(U.rows(), r);
+
+ const T* dPtr = d.getCArray();
+ for (int i = 0; i < A.rows(); ++i) {
+ const T* Urow = U.impl->elt[i];
+ T* Arow = A.impl->elt[i];
+ const int Acols = A.cols();
+ for (int j = 0; j < Acols; ++j) {
+ // A(i,j) = U(i,:) * D(:,j)
+ // This is non-zero only at j = i because D is diagonal
+ // A(i,j) = U(i,j) * D(j,j)
+ Arow[j] = Urow[j] * dPtr[j];
+ }
+ }
+
+ //
+ // Compute X = V.subMatrix(0, V.rows() - 1, 0, r - 1) * A.transpose()
+ //
+ // Avoid the explicit subMatrix call, and by storing A' instead of A, avoid
+ // both the transpose and the memory incoherence of striding across memory
+ // in big steps.
+
+ alwaysAssertM(A.cols() == r,
+ "Internal dimension mismatch during pseudoInverse()");
+ alwaysAssertM(V.cols() >= r,
+ "Internal dimension mismatch during pseudoInverse()");
+
+ X = Matrix(V.rows(), A.rows());
+ T** Xelt = X.impl->elt;
+ for (int i = 0; i < X.rows(); ++i) {
+ const T* Vrow = V.impl->elt[i];
+ for (int j = 0; j < X.cols(); ++j) {
+ const T* Arow = A.impl->elt[j];
+ T sum = 0;
+ for (int k = 0; k < r; ++k) {
+ sum += Vrow[k] * Arow[k];
+ }
+ Xelt[i][j] = sum;
+ }
+ }
+
+ /*
+ // Test that results are the same after optimizations:
+ Matrix diff = X - testX;
+ T n = diff.norm();
+ debugAssert(n < 0.0001);
+ */
+ }
+ return X;
+}
+
+// Computes pseudoinverse for a vector
+Matrix Matrix::vectorPseudoInverse() const {
+ // If vector A has nonzero elements: transpose A, then divide each elt. by the squared norm
+ // If A is zero vector: transpose A
+ double x = 0.0;
+
+ if (anyNonZero()) {
+ x = 1.0 / normSquared();
+ }
+
+ Matrix A(cols(), rows());
+ T** Aelt = A.impl->elt;
+ for (int r = 0; r < rows(); ++r) {
+ const T* MyRow = impl->elt[r];
+ for (int c = 0; c < cols(); ++c) {
+ Aelt[c][r] = T(MyRow[c] * x);
+ }
+ }
+ return Matrix(A);
+}
+
+
+Matrix Matrix::rowPartPseudoInverse() const{
+ int m = rows();
+ int n = cols();
+ alwaysAssertM((m<=n),"Row-partitioned block matrix pseudoinverse requires R<C");
+
+ // B = A * A'
+ Matrix A = *this;
+ Matrix B = Matrix(m,m);
+
+ T** Aelt = A.impl->elt;
+ T** Belt = B.impl->elt;
+ for (int i = 0; i < m; ++i) {
+ const T* Arow = Aelt[i];
+ for (int j = 0; j < m; ++j) {
+ const T* Brow = Aelt[j];
+ T sum = 0;
+ for (int k = 0; k < n; ++k) {
+ sum += Arow[k] * Brow[k];
+ }
+ Belt[i][j] = sum;
+ }
+ }
+
+ // B has size m x m
+ switch (m) {
+ case 2:
+ return row2PseudoInverse(B);
+
+ case 3:
+ return row3PseudoInverse(B);
+
+ case 4:
+ return row4PseudoInverse(B);
+
+ default:
+ alwaysAssertM(false, "G3D internal error: Should have used the vector or general case!");
+ return Matrix();
+ }
+}
+
+Matrix Matrix::colPartPseudoInverse() const{
+ int m = rows();
+ int n = cols();
+ alwaysAssertM((m>=n),"Column-partitioned block matrix pseudoinverse requires R>C");
+ // TODO: Put each of the individual cases in its own helper function
+ // TODO: Push the B computation down into the individual cases
+ // B = A' * A
+ Matrix A = *this;
+ Matrix B = Matrix(n, n);
+ T** Aelt = A.impl->elt;
+ T** Belt = B.impl->elt;
+ for (int i = 0; i < n; ++i) {
+ for (int j = 0; j < n; ++j) {
+ T sum = 0;
+ for (int k = 0; k < m; ++k) {
+ sum += Aelt[k][i] * Aelt[k][j];
+ }
+ Belt[i][j] = sum;
+ }
+ }
+
+ // B has size n x n
+ switch (n) {
+ case 2:
+ return col2PseudoInverse(B);
+
+ case 3:
+ return col3PseudoInverse(B);
+
+ case 4:
+ return col4PseudoInverse(B);
+
+ default:
+ alwaysAssertM(false, "G3D internal error: Should have used the vector or general case!");
+ return Matrix();
+ }
+}
+
+Matrix Matrix::col2PseudoInverse(const Matrix& B) const {
+
+ Matrix A = *this;
+ int m = rows();
+ int n = cols();
+ (void)n;
+
+ // Row-major 2x2 matrix
+ const float B2[2][2] =
+ {{B.get(0,0), B.get(0,1)},
+ {B.get(1,0), B.get(1,1)}};
+
+ float det = (B2[0][0]*B2[1][1]) - (B2[0][1]*B2[1][0]);
+
+ if (fuzzyEq(det, T(0))) {
+
+ // Matrix was singular; the block matrix pseudo-inverse can't
+ // handle that, so fall back to the old case
+ return svdPseudoInverse();
+
+ } else {
+ // invert using formula at http://www.netsoc.tcd.ie/~jgilbert/maths_site/applets/algebra/matrix_inversion.html
+
+ // Multiply by Binv * A'
+ Matrix X(cols(), rows());
+
+ T** Xelt = X.impl->elt;
+ T** Aelt = A.impl->elt;
+ float binv00 = B2[1][1]/det, binv01 = -B2[1][0]/det;
+ float binv10 = -B2[0][1]/det, binv11 = B2[0][0]/det;
+ for (int j = 0; j < m; ++j) {
+ const T* Arow = Aelt[j];
+ float a0 = Arow[0];
+ float a1 = Arow[1];
+ Xelt[0][j] = binv00 * a0 + binv01 * a1;
+ Xelt[1][j] = binv10 * a0 + binv11 * a1;
+ }
+ return X;
+ }
+}
+
+Matrix Matrix::col3PseudoInverse(const Matrix& B) const {
+ Matrix A = *this;
+ int m = rows();
+ int n = cols();
+
+ Matrix3 B3 = B.toMatrix3();
+ if (fuzzyEq(B3.determinant(), (T)0.0)) {
+
+ // Matrix was singular; the block matrix pseudo-inverse can't
+ // handle that, so fall back to the old case
+ return svdPseudoInverse();
+
+ } else {
+ Matrix3 B3inv = B3.inverse();
+
+ // Multiply by Binv * A'
+ Matrix X(cols(), rows());
+
+ T** Xelt = X.impl->elt;
+ T** Aelt = A.impl->elt;
+ for (int i = 0; i < n; ++i) {
+ T* Xrow = Xelt[i];
+ for (int j = 0; j < m; ++j) {
+ const T* Arow = Aelt[j];
+ T sum = 0;
+ const float* Binvrow = B3inv[i];
+ for (int k = 0; k < n; ++k) {
+ sum += Binvrow[k] * Arow[k];
+ }
+ Xrow[j] = sum;
+ }
+ }
+ return X;
+ }
+}
+
+Matrix Matrix::col4PseudoInverse(const Matrix& B) const {
+ Matrix A = *this;
+ int m = rows();
+ int n = cols();
+
+ Matrix4 B4 = B.toMatrix4();
+ if (fuzzyEq(B4.determinant(), (T)0.0)) {
+
+ // Matrix was singular; the block matrix pseudo-inverse can't
+ // handle that, so fall back to the old case
+ return svdPseudoInverse();
+
+ } else {
+ Matrix4 B4inv = B4.inverse();
+
+ // Multiply by Binv * A'
+ Matrix X(cols(), rows());
+
+ T** Xelt = X.impl->elt;
+ T** Aelt = A.impl->elt;
+ for (int i = 0; i < n; ++i) {
+ T* Xrow = Xelt[i];
+ for (int j = 0; j < m; ++j) {
+ const T* Arow = Aelt[j];
+ T sum = 0;
+ const float* Binvrow = B4inv[i];
+ for (int k = 0; k < n; ++k) {
+ sum += Binvrow[k] * Arow[k];
+ }
+ Xrow[j] = sum;
+ }
+ }
+ return X;
+ }
+}
+
+Matrix Matrix::row2PseudoInverse(const Matrix& B) const {
+
+ Matrix A = *this;
+ int m = rows();
+ int n = cols();
+ (void)m;
+
+ // Row-major 2x2 matrix
+ const float B2[2][2] =
+ {{B.get(0,0), B.get(0,1)},
+ {B.get(1,0), B.get(1,1)}};
+
+ float det = (B2[0][0]*B2[1][1]) - (B2[0][1]*B2[1][0]);
+
+ if (fuzzyEq(det, T(0))) {
+
+ // Matrix was singular; the block matrix pseudo-inverse can't
+ // handle that, so fall back to the old case
+ return svdPseudoInverse();
+
+ } else {
+ // invert using formula at http://www.netsoc.tcd.ie/~jgilbert/maths_site/applets/algebra/matrix_inversion.html
+
+ // Multiply by Binv * A'
+ Matrix X(cols(), rows());
+
+ T** Xelt = X.impl->elt;
+ T** Aelt = A.impl->elt;
+ float binv00 = B2[1][1]/det, binv01 = -B2[1][0]/det;
+ float binv10 = -B2[0][1]/det, binv11 = B2[0][0]/det;
+ for (int j = 0; j < n; ++j) {
+ Xelt[j][0] = Aelt[0][j] * binv00 + Aelt[1][j] * binv10;
+ Xelt[j][1] = Aelt[0][j] * binv01 + Aelt[1][j] * binv11;
+ }
+ return X;
+ }
+}
+
+Matrix Matrix::row3PseudoInverse(const Matrix& B) const {
+
+ Matrix A = *this;
+ int m = rows();
+ int n = cols();
+
+ Matrix3 B3 = B.toMatrix3();
+ if (fuzzyEq(B3.determinant(), (T)0.0)) {
+
+ // Matrix was singular; the block matrix pseudo-inverse can't
+ // handle that, so fall back to the old case
+ return svdPseudoInverse();
+
+ } else {
+ Matrix3 B3inv = B3.inverse();
+
+ // Multiply by Binv * A'
+ Matrix X(cols(), rows());
+
+ T** Xelt = X.impl->elt;
+ T** Aelt = A.impl->elt;
+ for (int i = 0; i < n; ++i) {
+ T* Xrow = Xelt[i];
+ for (int j = 0; j < m; ++j) {
+ T sum = 0;
+ for (int k = 0; k < m; ++k) {
+ sum += Aelt[k][i] * B3inv[j][k];
+ }
+ Xrow[j] = sum;
+ }
+ }
+ return X;
+ }
+}
+
+Matrix Matrix::row4PseudoInverse(const Matrix& B) const {
+
+ Matrix A = *this;
+ int m = rows();
+ int n = cols();
+
+ Matrix4 B4 = B.toMatrix4();
+ if (fuzzyEq(B4.determinant(), (T)0.0)) {
+
+ // Matrix was singular; the block matrix pseudo-inverse can't
+ // handle that, so fall back to the old case
+ return svdPseudoInverse();
+
+ } else {
+ Matrix4 B4inv = B4.inverse();
+
+ // Multiply by Binv * A'
+ Matrix X(cols(), rows());
+
+ T** Xelt = X.impl->elt;
+ T** Aelt = A.impl->elt;
+ for (int i = 0; i < n; ++i) {
+ T* Xrow = Xelt[i];
+ for (int j = 0; j < m; ++j) {
+ T sum = 0;
+ for (int k = 0; k < m; ++k) {
+ sum += Aelt[k][i] * B4inv[j][k];
+ }
+ Xrow[j] = sum;
+ }
+ }
+ return X;
+ }
+}
+
+// Uses the block matrix pseudoinverse to compute the pseudoinverse of a full-rank mxn matrix with m >= n
+// http://en.wikipedia.org/wiki/Block_matrix_pseudoinverse
+Matrix Matrix::partitionPseudoInverse() const {
+
+ // Logic:
+ // A^-1 = (A'A)^-1 A'
+ // A has few (n) columns, so A'A is small (n x n) and fast to invert
+
+ int m = rows();
+ int n = cols();
+
+ if (m < n) {
+ // TODO: optimize by pushing through the transpose
+ //return transpose().partitionPseudoInverse().transpose();
+ return rowPartPseudoInverse();
+
+ } else {
+ return colPartPseudoInverse();
+ }
+}
+
+void Matrix::Impl::inverseInPlaceGaussJordan() {
+ debugAssertM(R == C,
+ format(
+ "Cannot perform Gauss-Jordan inverse on a non-square matrix."
+ " (Argument was %dx%d)",
+ R, C));
+
+ // Exchange to float elements
+# define SWAP(x, y) {float temp = x; x = y; y = temp;}
+
+ // The integer arrays pivot, rowIndex, and colIndex are
+ // used for bookkeeping on the pivoting
+ static Array<int> colIndex, rowIndex, pivot;
+
+ int col = 0, row = 0;
+
+ colIndex.resize(R);
+ rowIndex.resize(R);
+ pivot.resize(R);
+
+ static const int NO_PIVOT = -1;
+
+ // Initialize the pivot array to default values.
+ for (int i = 0; i < R; ++i) {
+ pivot[i] = NO_PIVOT;
+ }
+
+ // This is the main loop over the columns to be reduced
+ // Loop over the columns.
+ for (int c = 0; c < R; ++c) {
+
+ // Find the largest element and use that as a pivot
+ float largestMagnitude = 0.0;
+
+ // This is the outer loop of the search for a pivot element
+ for (int r = 0; r < R; ++r) {
+
+ // Unless we've already found the pivot, keep going
+ if (pivot[r] != 0) {
+
+ // Find the largest pivot
+ for (int k = 0; k < R; ++k) {
+ if (pivot[k] == NO_PIVOT) {
+ const float mag = fabs(elt[r][k]);
+
+ if (mag >= largestMagnitude) {
+ largestMagnitude = mag;
+ row = r; col = k;
+ }
+ }
+ }
+ }
+ }
+
+ pivot[col] += 1;
+
+ // Interchange columns so that the pivot element is on the diagonal (we'll have to undo this
+ // at the end)
+ if (row != col) {
+ for (int k = 0; k < R; ++k) {
+ SWAP(elt[row][k], elt[col][k])
+ }
+ }
+
+ // The pivot is now at [row, col]
+ rowIndex[c] = row;
+ colIndex[c] = col;
+
+ double piv = elt[col][col];
+
+ debugAssertM(piv != 0.0, "Matrix is singular");
+
+ // Divide everything by the pivot (avoid computing the division
+ // multiple times).
+ const double pivotInverse = 1.0 / piv;
+ elt[col][col] = 1.0;
+
+ for (int k = 0; k < R; ++k) {
+ elt[col][k] *= Matrix::T(pivotInverse);
+ }
+
+ // Reduce all rows
+ for (int r = 0; r < R; ++r) {
+ // Skip over the pivot row
+ if (r != col) {
+
+ double oldValue = elt[r][col];
+ elt[r][col] = 0.0;
+
+ for (int k = 0; k < R; ++k) {
+ elt[r][k] -= Matrix::T(elt[col][k] * oldValue);
+ }
+ }
+ }
+ }
+
+
+ // Put the columns back in the correct locations
+ for (int i = R - 1; i >= 0; --i) {
+ if (rowIndex[i] != colIndex[i]) {
+ for (int k = 0; k < R; ++k) {
+ SWAP(elt[k][rowIndex[i]], elt[k][colIndex[i]]);
+ }
+ }
+ }
+
+# undef SWAP
+}
+
+
+bool Matrix::Impl::anyNonZero() const {
+ int N = R * C;
+ for (int i = 0; i < N; ++i) {
+ if (data[i] != 0.0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool Matrix::Impl::allNonZero() const {
+ int N = R * C;
+ for (int i = 0; i < N; ++i) {
+ if (data[i] == 0.0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+/** Helper for svdCore */
+static double pythag(double a, double b) {
+
+ double at = fabs(a), bt = fabs(b), ct, result;
+
+ if (at > bt) {
+ ct = bt / at;
+ result = at * sqrt(1.0 + square(ct));
+ } else if (bt > 0.0) {
+ ct = at / bt;
+ result = bt * sqrt(1.0 + square(ct));
+ } else {
+ result = 0.0;
+ }
+
+ return result;
+}
+
+#define SIGN(a, b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
+
+const char* Matrix::svdCore(float** U, int rows, int cols, float* D, float** V) {
+ const int MAX_ITERATIONS = 30;
+
+ int flag, i, its, j, jj, k, l = 0, nm = 0;
+ double c, f, h, s, x, y, z;
+ double anorm = 0.0, g = 0.0, scale = 0.0;
+
+ // Temp row vector
+ double* rv1;
+
+ debugAssertM(rows >= cols, "Must have more rows than columns");
+
+ rv1 = (double*)System::alignedMalloc(cols * sizeof(double), 16);
+ debugAssert(rv1);
+
+ // Householder reduction to bidiagonal form
+ for (i = 0; i < cols; ++i) {
+
+ // Left-hand reduction
+ l = i + 1;
+ rv1[i] = scale * g;
+ g = s = scale = 0.0;
+
+ if (i < rows) {
+
+ for (k = i; k < rows; ++k) {
+ scale += fabs((double)U[k][i]);
+ }
+
+ if (scale) {
+ for (k = i; k < rows; ++k) {
+ U[k][i] = (float)((double)U[k][i]/scale);
+ s += ((double)U[k][i] * (double)U[k][i]);
+ }
+
+ f = (double)U[i][i];
+
+ // TODO: what is this 2-arg sign function?
+ g = -SIGN(sqrt(s), f);
+ h = f * g - s;
+ U[i][i] = (float)(f - g);
+
+ if (i != cols - 1) {
+ for (j = l; j < cols; j++) {
+
+ for (s = 0.0, k = i; k < rows; ++k) {
+ s += ((double)U[k][i] * (double)U[k][j]);
+ }
+
+ f = s / h;
+ for (k = i; k < rows; ++k) {
+ U[k][j] += (float)(f * (double)U[k][i]);
+ }
+ }
+ }
+ for (k = i; k < rows; ++k) {
+ U[k][i] = (float)((double)U[k][i]*scale);
+ }
+ }
+ }
+ D[i] = (float)(scale * g);
+
+ // right-hand reduction
+ g = s = scale = 0.0;
+ if (i < rows && i != cols - 1) {
+ for (k = l; k < cols; ++k) {
+ scale += fabs((double)U[i][k]);
+ }
+
+ if (scale) {
+ for (k = l; k < cols; ++k) {
+ U[i][k] = (float)((double)U[i][k]/scale);
+ s += ((double)U[i][k] * (double)U[i][k]);
+ }
+
+ f = (double)U[i][l];
+ g = -SIGN(sqrt(s), f);
+ h = f * g - s;
+ U[i][l] = (float)(f - g);
+
+ for (k = l; k < cols; ++k) {
+ rv1[k] = (double)U[i][k] / h;
+ }
+
+ if (i != rows - 1) {
+
+ for (j = l; j < rows; ++j) {
+ for (s = 0.0, k = l; k < cols; ++k) {
+ s += ((double)U[j][k] * (double)U[i][k]);
+ }
+
+ for (k = l; k < cols; ++k) {
+ U[j][k] += (float)(s * rv1[k]);
+ }
+ }
+ }
+
+ for (k = l; k < cols; ++k) {
+ U[i][k] = (float)((double)U[i][k]*scale);
+ }
+ }
+ }
+
+ anorm = max(anorm, fabs((double)D[i]) + fabs(rv1[i]));
+ }
+
+ // accumulate the right-hand transformation
+ for (i = cols - 1; i >= 0; --i) {
+ if (i < cols - 1) {
+ if (g) {
+ for (j = l; j < cols; j++) {
+ V[j][i] = (float)(((double)U[i][j] / (double)U[i][l]) / g);
+ }
+
+ // double division to avoid underflow
+ for (j = l; j < cols; ++j) {
+ for (s = 0.0, k = l; k < cols; k++) {
+ s += ((double)U[i][k] * (double)V[k][j]);
+ }
+
+ for (k = l; k < cols; ++k) {
+ V[k][j] += (float)(s * (double)V[k][i]);
+ }
+ }
+ }
+
+ for (j = l; j < cols; ++j) {
+ V[i][j] = V[j][i] = 0.0;
+ }
+ }
+
+ V[i][i] = 1.0;
+ g = rv1[i];
+ l = i;
+ }
+
+ // accumulate the left-hand transformation
+ for (i = cols - 1; i >= 0; --i) {
+ l = i + 1;
+ g = (double)D[i];
+ if (i < cols - 1) {
+ for (j = l; j < cols; ++j) {
+ U[i][j] = 0.0;
+ }
+ }
+
+ if (g) {
+ g = 1.0 / g;
+ if (i != cols - 1) {
+ for (j = l; j < cols; ++j) {
+ for (s = 0.0, k = l; k < rows; ++k) {
+ s += ((double)U[k][i] * (double)U[k][j]);
+ }
+
+ f = (s / (double)U[i][i]) * g;
+
+ for (k = i; k < rows; ++k) {
+ U[k][j] += (float)(f * (double)U[k][i]);
+ }
+ }
+ }
+
+ for (j = i; j < rows; ++j) {
+ U[j][i] = (float)((double)U[j][i]*g);
+ }
+
+ } else {
+ for (j = i; j < rows; ++j) {
+ U[j][i] = 0.0;
+ }
+ }
+ ++U[i][i];
+ }
+
+ // diagonalize the bidiagonal form
+ for (k = cols - 1; k >= 0; --k) {
+ // loop over singular values
+ for (its = 0; its < MAX_ITERATIONS; ++its) {
+ // loop over allowed iterations
+ flag = 1;
+
+ for (l = k; l >= 0; --l) {
+ // test for splitting
+ nm = l - 1;
+ if (fabs(rv1[l]) + anorm == anorm) {
+ flag = 0;
+ break;
+ }
+
+ if (fabs((double)D[nm]) + anorm == anorm) {
+ break;
+ }
+ }
+
+ if (flag) {
+ c = 0.0;
+ s = 1.0;
+ for (i = l; i <= k; ++i) {
+ f = s * rv1[i];
+ if (fabs(f) + anorm != anorm) {
+ g = (double)D[i];
+ h = pythag(f, g);
+ D[i] = (float)h;
+ h = 1.0 / h;
+ c = g * h;
+ s = (- f * h);
+ for (j = 0; j < rows; ++j) {
+ y = (double)U[j][nm];
+ z = (double)U[j][i];
+ U[j][nm] = (float)(y * c + z * s);
+ U[j][i] = (float)(z * c - y * s);
+ }
+ }
+ }
+ }
+
+ z = (double)D[k];
+ if (l == k) {
+ // convergence
+ if (z < 0.0) {
+ // make singular value nonnegative
+ D[k] = (float)(-z);
+
+ for (j = 0; j < cols; ++j) {
+ V[j][k] = (-V[j][k]);
+ }
+ }
+ break;
+ }
+
+ if (its >= MAX_ITERATIONS) {
+ free(rv1);
+ rv1 = NULL;
+ return "Failed to converge.";
+ }
+
+ // shift from bottom 2 x 2 minor
+ x = (double)D[l];
+ nm = k - 1;
+ y = (double)D[nm];
+ g = rv1[nm];
+ h = rv1[k];
+ f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
+ g = pythag(f, 1.0);
+ f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
+
+ // next QR transformation
+ c = s = 1.0;
+ for (j = l; j <= nm; ++j) {
+ i = j + 1;
+ g = rv1[i];
+ y = (double)D[i];
+ h = s * g;
+ g = c * g;
+ z = pythag(f, h);
+ rv1[j] = z;
+ c = f / z;
+ s = h / z;
+ f = x * c + g * s;
+ g = g * c - x * s;
+ h = y * s;
+ y = y * c;
+
+ for (jj = 0; jj < cols; ++jj) {
+ x = (double)V[jj][j];
+ z = (double)V[jj][i];
+ V[jj][j] = (float)(x * c + z * s);
+ V[jj][i] = (float)(z * c - x * s);
+ }
+ z = pythag(f, h);
+ D[j] = (float)z;
+ if (z) {
+ z = 1.0 / z;
+ c = f * z;
+ s = h * z;
+ }
+ f = (c * g) + (s * y);
+ x = (c * y) - (s * g);
+ for (jj = 0; jj < rows; jj++) {
+ y = (double)U[jj][j];
+ z = (double)U[jj][i];
+ U[jj][j] = (float)(y * c + z * s);
+ U[jj][i] = (float)(z * c - y * s);
+ }
+ }
+ rv1[l] = 0.0;
+ rv1[k] = f;
+ D[k] = (float)x;
+ }
+ }
+
+ System::alignedFree(rv1);
+ rv1 = NULL;
+
+ return NULL;
+}
+
+#undef SIGN
+
+}
diff --git a/dep/src/g3dlite/Matrix3.cpp b/dep/src/g3dlite/Matrix3.cpp
index 76864e1b60c..b32d938f0f9 100644
--- a/dep/src/g3dlite/Matrix3.cpp
+++ b/dep/src/g3dlite/Matrix3.cpp
@@ -6,21 +6,51 @@
@author Morgan McGuire, graphics3d.com
@created 2001-06-02
- @edited 2006-04-06
+ @edited 2009-11-15
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
*/
#include "G3D/platform.h"
-#include "G3D/format.h"
#include <memory.h>
#include <assert.h>
#include "G3D/Matrix3.h"
#include "G3D/g3dmath.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
#include "G3D/Quat.h"
+#include "G3D/Any.h"
namespace G3D {
const float Matrix3::EPSILON = 1e-06f;
+Matrix3::Matrix3(const Any& any) {
+ any.verifyName("Matrix3");
+ any.verifyType(Any::ARRAY);
+ any.verifySize(9);
+
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ elt[r][c] = any[r * 3 + c];
+ }
+ }
+}
+
+
+Matrix3::operator Any() const {
+ Any any(Any::ARRAY, "Matrix3");
+ any.resize(9);
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ any[r * 3 + c] = elt[r][c];
+ }
+ }
+
+ return any;
+}
+
const Matrix3& Matrix3::zero() {
static Matrix3 m(0, 0, 0, 0, 0, 0, 0, 0, 0);
return m;
@@ -31,13 +61,14 @@ const Matrix3& Matrix3::identity() {
return m;
}
-// Deprecated.
-const Matrix3 Matrix3::ZERO(0, 0, 0, 0, 0, 0, 0, 0, 0);
-const Matrix3 Matrix3::IDENTITY(1, 0, 0, 0, 1, 0, 0, 0, 1);
const float Matrix3::ms_fSvdEpsilon = 1e-04f;
const int Matrix3::ms_iSvdMaxIterations = 32;
+Matrix3::Matrix3(BinaryInput& b) {
+ deserialize(b);
+}
+
bool Matrix3::fuzzyEq(const Matrix3& b) const {
for (int r = 0; r < 3; ++r) {
for (int c = 0; c < 3; ++c) {
@@ -49,12 +80,25 @@ bool Matrix3::fuzzyEq(const Matrix3& b) const {
return true;
}
+
+bool Matrix3::isRightHanded() const{
+
+ const Vector3& X = column(0);
+ const Vector3& Y = column(1);
+ const Vector3& Z = column(2);
+
+ const Vector3& W = X.cross(Y);
+
+ return W.dot(Z) > 0.0f;
+}
+
+
bool Matrix3::isOrthonormal() const {
- Vector3 X = getColumn(0);
- Vector3 Y = getColumn(1);
- Vector3 Z = getColumn(2);
+ const Vector3& X = column(0);
+ const Vector3& Y = column(1);
+ const Vector3& Z = column(2);
- return
+ return
(G3D::fuzzyEq(X.dot(Y), 0.0f) &&
G3D::fuzzyEq(Y.dot(Z), 0.0f) &&
G3D::fuzzyEq(X.dot(Z), 0.0f) &&
@@ -66,8 +110,9 @@ bool Matrix3::isOrthonormal() const {
//----------------------------------------------------------------------------
Matrix3::Matrix3(const Quat& _q) {
// Implementation from Watt and Watt, pg 362
- // See also http://www.flipcode.com/documents/matrfaq.html#Q54
- Quat q = _q.unitize();
+ // See also http://www.flipcode.com/documents/matrfaq.html#Q54
+ Quat q = _q;
+ q.unitize();
float xx = 2.0f * q.x * q.x;
float xy = 2.0f * q.x * q.y;
float xz = 2.0f * q.x * q.z;
@@ -108,7 +153,7 @@ Matrix3::Matrix3(
void Matrix3::set(
float fEntry00, float fEntry01, float fEntry02,
- float fEntry10, float fEntry11, float fEntry12,
+ float fEntry10, float fEntry11, float fEntry12,
float fEntry20, float fEntry21, float fEntry22) {
elt[0][0] = fEntry00;
@@ -122,17 +167,41 @@ void Matrix3::set(
elt[2][2] = fEntry22;
}
+
+void Matrix3::deserialize(BinaryInput& b) {
+ int r,c;
+ for (c = 0; c < 3; ++c) {
+ for (r = 0; r < 3; ++r) {
+ elt[r][c] = b.readFloat32();
+ }
+ }
+}
+
+
+void Matrix3::serialize(BinaryOutput& b) const {
+ int r,c;
+ for (c = 0; c < 3; ++c) {
+ for (r = 0; r < 3; ++r) {
+ b.writeFloat32(elt[r][c]);
+ }
+ }
+}
+
+
//----------------------------------------------------------------------------
-Vector3 Matrix3::getColumn (int iCol) const {
+Vector3 Matrix3::column (int iCol) const {
assert((0 <= iCol) && (iCol < 3));
return Vector3(elt[0][iCol], elt[1][iCol],
elt[2][iCol]);
}
-Vector3 Matrix3::getRow (int iRow) const {
- return Vector3(elt[iRow][0], elt[iRow][1], elt[iRow][2]);
+
+const Vector3& Matrix3::row (int iRow) const {
+ assert((0 <= iRow) && (iRow < 3));
+ return *reinterpret_cast<const Vector3*>(elt[iRow]);
}
+
void Matrix3::setColumn(int iCol, const Vector3 &vector) {
debugAssert((iCol >= 0) && (iCol < 3));
elt[0][iCol] = vector.x;
@@ -140,6 +209,7 @@ void Matrix3::setColumn(int iCol, const Vector3 &vector) {
elt[2][iCol] = vector.z;
}
+
void Matrix3::setRow(int iRow, const Vector3 &vector) {
debugAssert((iRow >= 0) && (iRow < 3));
elt[iRow][0] = vector.x;
@@ -147,6 +217,7 @@ void Matrix3::setRow(int iRow, const Vector3 &vector) {
elt[iRow][2] = vector.z;
}
+
//----------------------------------------------------------------------------
bool Matrix3::operator== (const Matrix3& rkMatrix) const {
for (int iRow = 0; iRow < 3; iRow++) {
@@ -269,6 +340,21 @@ Matrix3 Matrix3::operator* (float fScalar) const {
return kProd;
}
+Matrix3& Matrix3::operator/= (float fScalar) {
+ return *this *= (1.0f / fScalar);
+}
+
+Matrix3& Matrix3::operator*= (float fScalar) {
+
+ for (int iRow = 0; iRow < 3; iRow++) {
+ for (int iCol = 0; iCol < 3; iCol++) {
+ elt[iRow][iCol] *= fScalar;
+ }
+ }
+
+ return *this;
+}
+
//----------------------------------------------------------------------------
Matrix3 operator* (double fScalar, const Matrix3& rkMatrix) {
Matrix3 kProd;
@@ -286,6 +372,7 @@ Matrix3 operator* (float fScalar, const Matrix3& rkMatrix) {
return (double)fScalar * rkMatrix;
}
+
Matrix3 operator* (int fScalar, const Matrix3& rkMatrix) {
return (double)fScalar * rkMatrix;
}
@@ -914,6 +1001,97 @@ void Matrix3::qDUDecomposition (Matrix3& kQ,
}
//----------------------------------------------------------------------------
+void Matrix3::polarDecomposition(Matrix3 &R, Matrix3 &S) const{
+ /*
+ Polar decomposition of a matrix. Based on pseudocode from
+ Nicholas J Higham, "Computing the Polar Decomposition -- with
+ Applications Siam Journal of Science and Statistical Computing, Vol 7, No. 4,
+ October 1986.
+
+ Decomposes A into R*S, where R is orthogonal and S is symmetric.
+
+ Ken Shoemake's "Matrix animation and polar decomposition"
+ in Proceedings of the conference on Graphics interface '92
+ seems to be better known in the world of graphics, but Higham's version
+ uses a scaling constant that can lead to faster convergence than
+ Shoemake's when the initial matrix is far from orthogonal.
+ */
+
+ Matrix3 X = *this;
+ Matrix3 tmp = X.inverse();
+ Matrix3 Xit = tmp.transpose();
+ int iter = 0;
+
+ const int MAX_ITERS = 100;
+
+ const double eps = 50 * std::numeric_limits<float>::epsilon();
+ const float BigEps = 50 * eps;
+
+ /* Higham suggests using OneNorm(Xit-X) < eps * OneNorm(X)
+ * as the convergence criterion, but OneNorm(X) should quickly
+ * settle down to something between 1 and 1.7, so just comparing
+ * with eps seems sufficient.
+ *--------------------------------------------------------------- */
+
+ double resid = X.diffOneNorm(Xit);
+ while (resid > eps && iter < MAX_ITERS) {
+
+ tmp = X.inverse();
+ Xit = tmp.transpose();
+
+ if (resid < BigEps) {
+ // close enough use simple iteration
+ X += Xit;
+ X *= 0.5f;
+ }
+ else {
+ // not close to convergence, compute acceleration factor
+ float gamma = sqrt( sqrt(
+ (Xit.l1Norm()* Xit.lInfNorm())/(X.l1Norm()*X.lInfNorm()) ) );
+
+ X *= 0.5f * gamma;
+ tmp = Xit;
+ tmp *= 0.5f / gamma;
+ X += tmp;
+ }
+
+ resid = X.diffOneNorm(Xit);
+ iter++;
+ }
+
+ R = X;
+ tmp = R.transpose();
+
+ S = tmp * (*this);
+
+ // S := (S + S^t)/2 one more time to make sure it is symmetric
+ tmp = S.transpose();
+
+ S += tmp;
+ S *= 0.5f;
+
+#ifdef G3D_DEBUG
+ // Check iter limit
+ assert(iter < MAX_ITERS);
+
+ // Check A = R*S
+ tmp = R*S;
+ resid = tmp.diffOneNorm(*this);
+ assert(resid < eps);
+
+ // Check R is orthogonal
+ tmp = R*R.transpose();
+ resid = tmp.diffOneNorm(Matrix3::identity());
+ assert(resid < eps);
+
+ // Check that S is symmetric
+ tmp = S.transpose();
+ resid = tmp.diffOneNorm(S);
+ assert(resid < eps);
+#endif
+}
+
+//----------------------------------------------------------------------------
float Matrix3::maxCubicRoot (float afCoeff[3]) {
// Spectral norm is for A^T*A, so characteristic polynomial
// P(x) = c[0]+c[1]*x+c[2]*x^2+x^3 has three positive float roots.
@@ -1006,9 +1184,74 @@ float Matrix3::spectralNorm () const {
}
//----------------------------------------------------------------------------
+float Matrix3::squaredFrobeniusNorm() const {
+ float norm2 = 0;
+ const float* e = &elt[0][0];
+
+ for (int i = 0; i < 9; ++i){
+ norm2 += (*e) * (*e);
+ }
+
+ return norm2;
+}
+
+//----------------------------------------------------------------------------
+float Matrix3::frobeniusNorm() const {
+ return sqrtf(squaredFrobeniusNorm());
+}
+
+//----------------------------------------------------------------------------
+float Matrix3::l1Norm() const {
+ // The one norm of a matrix is the max column sum in absolute value.
+ float oneNorm = 0;
+ for (int c = 0; c < 3; ++c) {
+
+ float f = fabs(elt[0][c])+ fabs(elt[1][c]) + fabs(elt[2][c]);
+
+ if (f > oneNorm) {
+ oneNorm = f;
+ }
+ }
+ return oneNorm;
+}
+
+//----------------------------------------------------------------------------
+float Matrix3::lInfNorm() const {
+ // The infinity norm of a matrix is the max row sum in absolute value.
+ float infNorm = 0;
+
+ for (int r = 0; r < 3; ++r) {
+
+ float f = fabs(elt[r][0]) + fabs(elt[r][1])+ fabs(elt[r][2]);
+
+ if (f > infNorm) {
+ infNorm = f;
+ }
+ }
+ return infNorm;
+}
+
+//----------------------------------------------------------------------------
+float Matrix3::diffOneNorm(const Matrix3 &y) const{
+ float oneNorm = 0;
+
+ for (int c = 0; c < 3; ++c){
+
+ float f = fabs(elt[0][c] - y[0][c]) + fabs(elt[1][c] - y[1][c])
+ + fabs(elt[2][c] - y[2][c]);
+
+ if (f > oneNorm) {
+ oneNorm = f;
+ }
+ }
+ return oneNorm;
+}
+
+//----------------------------------------------------------------------------
void Matrix3::toAxisAngle (Vector3& rkAxis, float& rfRadians) const {
+ //
// Let (x,y,z) be the unit-length axis and let A be an angle of rotation.
- // The rotation matrix is R = I + sin(A)*P + (1-cos(A))*P^2 where
+ // The rotation matrix is R = I + sin(A)*P + (1-cos(A))*P^2 (Rodrigues' formula) where
// I is the identity and
//
// +- -+
@@ -1030,11 +1273,11 @@ void Matrix3::toAxisAngle (Vector3& rkAxis, float& rfRadians) const {
// it does not matter which sign you choose on the square roots.
float fTrace = elt[0][0] + elt[1][1] + elt[2][2];
- float fCos = 0.5 * (fTrace - 1.0);
+ float fCos = 0.5f * (fTrace - 1.0f);
rfRadians = G3D::aCos(fCos); // in [0,PI]
if ( rfRadians > 0.0 ) {
- if ( rfRadians < G3D_PI ) {
+ if ( rfRadians < pi() ) {
rkAxis.x = elt[2][1] - elt[1][2];
rkAxis.y = elt[0][2] - elt[2][0];
rkAxis.z = elt[1][0] - elt[0][1];
@@ -1089,28 +1332,31 @@ void Matrix3::toAxisAngle (Vector3& rkAxis, float& rfRadians) const {
}
//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromAxisAngle (const Vector3& rkAxis, float fRadians) {
- Matrix3 m;
+Matrix3 Matrix3::fromAxisAngle (const Vector3& _axis, float fRadians) {
+ Vector3 axis = _axis.direction();
- float fCos = cos(fRadians);
- float fSin = sin(fRadians);
+ Matrix3 m;
+ float fCos = cos(fRadians);
+ float fSin = sin(fRadians);
float fOneMinusCos = 1.0 - fCos;
- float fX2 = rkAxis.x * rkAxis.x;
- float fY2 = rkAxis.y * rkAxis.y;
- float fZ2 = rkAxis.z * rkAxis.z;
- float fXYM = rkAxis.x * rkAxis.y * fOneMinusCos;
- float fXZM = rkAxis.x * rkAxis.z * fOneMinusCos;
- float fYZM = rkAxis.y * rkAxis.z * fOneMinusCos;
- float fXSin = rkAxis.x * fSin;
- float fYSin = rkAxis.y * fSin;
- float fZSin = rkAxis.z * fSin;
+ float fX2 = square(axis.x);
+ float fY2 = square(axis.y);
+ float fZ2 = square(axis.z);
+ float fXYM = axis.x * axis.y * fOneMinusCos;
+ float fXZM = axis.x * axis.z * fOneMinusCos;
+ float fYZM = axis.y * axis.z * fOneMinusCos;
+ float fXSin = axis.x * fSin;
+ float fYSin = axis.y * fSin;
+ float fZSin = axis.z * fSin;
m.elt[0][0] = fX2 * fOneMinusCos + fCos;
m.elt[0][1] = fXYM - fZSin;
m.elt[0][2] = fXZM + fYSin;
+
m.elt[1][0] = fXYM + fZSin;
m.elt[1][1] = fY2 * fOneMinusCos + fCos;
m.elt[1][2] = fYZM - fXSin;
+
m.elt[2][0] = fXZM - fYSin;
m.elt[2][1] = fYZM + fXSin;
m.elt[2][2] = fZ2 * fOneMinusCos + fCos;
@@ -1134,14 +1380,14 @@ bool Matrix3::toEulerAnglesXYZ (float& rfXAngle, float& rfYAngle,
} else {
// WARNING. Not unique. XA - ZA = -atan2(r10,r11)
rfXAngle = -G3D::aTan2(elt[1][0], elt[1][1]);
- rfYAngle = -(float)G3D_HALF_PI;
+ rfYAngle = -(float)halfPi();
rfZAngle = 0.0f;
return false;
}
} else {
// WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11)
rfXAngle = G3D::aTan2(elt[1][0], elt[1][1]);
- rfYAngle = (float)G3D_HALF_PI;
+ rfYAngle = (float)halfPi();
rfZAngle = 0.0f;
return false;
}
@@ -1163,14 +1409,14 @@ bool Matrix3::toEulerAnglesXZY (float& rfXAngle, float& rfZAngle,
} else {
// WARNING. Not unique. XA - YA = atan2(r20,r22)
rfXAngle = G3D::aTan2(elt[2][0], elt[2][2]);
- rfZAngle = (float)G3D_HALF_PI;
+ rfZAngle = (float)halfPi();
rfYAngle = 0.0;
return false;
}
} else {
// WARNING. Not unique. XA + YA = atan2(-r20,r22)
rfXAngle = G3D::aTan2( -elt[2][0], elt[2][2]);
- rfZAngle = -(float)G3D_HALF_PI;
+ rfZAngle = -(float)halfPi();
rfYAngle = 0.0f;
return false;
}
@@ -1192,14 +1438,14 @@ bool Matrix3::toEulerAnglesYXZ (float& rfYAngle, float& rfXAngle,
} else {
// WARNING. Not unique. YA - ZA = atan2(r01,r00)
rfYAngle = G3D::aTan2(elt[0][1], elt[0][0]);
- rfXAngle = (float)G3D_HALF_PI;
+ rfXAngle = (float)halfPi();
rfZAngle = 0.0;
return false;
}
} else {
// WARNING. Not unique. YA + ZA = atan2(-r01,r00)
rfYAngle = G3D::aTan2( -elt[0][1], elt[0][0]);
- rfXAngle = -(float)G3D_HALF_PI;
+ rfXAngle = -(float)halfPi();
rfZAngle = 0.0f;
return false;
}
@@ -1221,14 +1467,14 @@ bool Matrix3::toEulerAnglesYZX (float& rfYAngle, float& rfZAngle,
} else {
// WARNING. Not unique. YA - XA = -atan2(r21,r22);
rfYAngle = -G3D::aTan2(elt[2][1], elt[2][2]);
- rfZAngle = -(float)G3D_HALF_PI;
+ rfZAngle = -(float)halfPi();
rfXAngle = 0.0;
return false;
}
} else {
// WARNING. Not unique. YA + XA = atan2(r21,r22)
rfYAngle = G3D::aTan2(elt[2][1], elt[2][2]);
- rfZAngle = (float)G3D_HALF_PI;
+ rfZAngle = (float)halfPi();
rfXAngle = 0.0f;
return false;
}
@@ -1250,14 +1496,14 @@ bool Matrix3::toEulerAnglesZXY (float& rfZAngle, float& rfXAngle,
} else {
// WARNING. Not unique. ZA - YA = -atan(r02,r00)
rfZAngle = -G3D::aTan2(elt[0][2], elt[0][0]);
- rfXAngle = -(float)G3D_HALF_PI;
+ rfXAngle = -(float)halfPi();
rfYAngle = 0.0f;
return false;
}
} else {
// WARNING. Not unique. ZA + YA = atan2(r02,r00)
rfZAngle = G3D::aTan2(elt[0][2], elt[0][0]);
- rfXAngle = (float)G3D_HALF_PI;
+ rfXAngle = (float)halfPi();
rfYAngle = 0.0f;
return false;
}
@@ -1279,14 +1525,14 @@ bool Matrix3::toEulerAnglesZYX (float& rfZAngle, float& rfYAngle,
} else {
// WARNING. Not unique. ZA - XA = -atan2(r01,r02)
rfZAngle = -G3D::aTan2(elt[0][1], elt[0][2]);
- rfYAngle = (float)G3D_HALF_PI;
+ rfYAngle = (float)halfPi();
rfXAngle = 0.0f;
return false;
}
} else {
// WARNING. Not unique. ZA + XA = atan2(-r01,-r02)
rfZAngle = G3D::aTan2( -elt[0][1], -elt[0][2]);
- rfYAngle = -(float)G3D_HALF_PI;
+ rfYAngle = -(float)halfPi();
rfXAngle = 0.0f;
return false;
}
@@ -1335,10 +1581,10 @@ Matrix3 Matrix3::fromEulerAnglesXZY (float fYAngle, float fPAngle,
//----------------------------------------------------------------------------
Matrix3 Matrix3::fromEulerAnglesYXZ(
- float fYAngle,
+ float fYAngle,
float fPAngle,
float fRAngle) {
-
+
float fCos, fSin;
fCos = cos(fYAngle);
@@ -1358,7 +1604,7 @@ Matrix3 Matrix3::fromEulerAnglesYXZ(
//----------------------------------------------------------------------------
Matrix3 Matrix3::fromEulerAnglesYZX(
- float fYAngle,
+ float fYAngle,
float fPAngle,
float fRAngle) {
@@ -1600,9 +1846,9 @@ void Matrix3::tensorProduct (const Vector3& rkU, const Vector3& rkV,
// Runs in 52 cycles on AMD, 76 cycles on Intel Centrino
//
-// The loop unrolling is necessary for performance.
+// The loop unrolling is necessary for performance.
// I was unable to improve performance further by flattening the matrices
-// into float*'s instead of 2D arrays.
+// into float*'s instead of 2D arrays.
//
// -morgan
void Matrix3::_mul(const Matrix3& A, const Matrix3& B, Matrix3& out) {
@@ -1669,12 +1915,13 @@ void Matrix3::_transpose(const Matrix3& A, Matrix3& out) {
//-----------------------------------------------------------------------------
std::string Matrix3::toString() const {
- return G3D::format("[%g, %g, %g; %g, %g, %g; %g, %g, %g]",
- elt[0][0], elt[0][1], elt[0][2],
- elt[1][0], elt[1][1], elt[1][2],
- elt[2][0], elt[2][1], elt[2][2]);
+ return G3D::format("[%g, %g, %g; %g, %g, %g; %g, %g, %g]",
+ elt[0][0], elt[0][1], elt[0][2],
+ elt[1][0], elt[1][1], elt[1][2],
+ elt[2][0], elt[2][1], elt[2][2]);
}
-} // namespace
+} // namespace
+
diff --git a/dep/src/g3dlite/Matrix4.cpp b/dep/src/g3dlite/Matrix4.cpp
new file mode 100644
index 00000000000..cd38a1a3602
--- /dev/null
+++ b/dep/src/g3dlite/Matrix4.cpp
@@ -0,0 +1,523 @@
+/**
+ @file Matrix4.cpp
+
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-10-02
+ @edited 2010-01-29
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Matrix4.h"
+#include "G3D/Matrix3.h"
+#include "G3D/Vector4.h"
+#include "G3D/Vector3.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/CoordinateFrame.h"
+#include "G3D/Rect2D.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+
+Matrix4::Matrix4(const Any& any) {
+ any.verifyName("Matrix4");
+ any.verifyType(Any::ARRAY);
+
+ const std::string& name = toLower(any.name());
+ if (name == "matrix4") {
+ any.verifySize(16);
+
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ elt[r][c] = any[r * 4 + c];
+ }
+ }
+ } else if (name == "matrix4::scale") {
+ if (any.size() == 1) {
+ *this = scale(any[0].number());
+ } else if (any.size() == 3) {
+ *this = scale(any[0], any[1], any[2]);
+ } else {
+ any.verify(false, "Matrix4::scale() takes either 1 or 3 arguments");
+ }
+ } else {
+ any.verify(false, "Expected Matrix4 constructor");
+ }
+}
+
+
+Matrix4::operator Any() const {
+ Any any(Any::ARRAY, "Matrix4");
+ any.resize(16);
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ any[r * 4 + c] = elt[r][c];
+ }
+ }
+
+ return any;
+}
+
+const Matrix4& Matrix4::identity() {
+ static Matrix4 m(
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1);
+ return m;
+}
+
+
+const Matrix4& Matrix4::zero() {
+ static Matrix4 m(
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0);
+ return m;
+}
+
+
+Matrix4::Matrix4(const class CoordinateFrame& cframe) {
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ elt[r][c] = cframe.rotation[r][c];
+ }
+ elt[r][3] = cframe.translation[r];
+ }
+ elt[3][0] = 0.0f;
+ elt[3][1] = 0.0f;
+ elt[3][2] = 0.0f;
+ elt[3][3] = 1.0f;
+}
+
+Matrix4::Matrix4(const Matrix3& upper3x3, const Vector3& lastCol) {
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ elt[r][c] = upper3x3[r][c];
+ }
+ elt[r][3] = lastCol[r];
+ }
+ elt[3][0] = 0.0f;
+ elt[3][1] = 0.0f;
+ elt[3][2] = 0.0f;
+ elt[3][3] = 1.0f;
+}
+
+
+Matrix3 Matrix4::upper3x3() const {
+ return Matrix3(elt[0][0], elt[0][1], elt[0][2],
+ elt[1][0], elt[1][1], elt[1][2],
+ elt[2][0], elt[2][1], elt[2][2]);
+}
+
+
+Matrix4 Matrix4::orthogonalProjection(
+ const class Rect2D& rect,
+ float nearval,
+ float farval,
+ float upDirection) {
+ return Matrix4::orthogonalProjection(rect.x0(), rect.x1(), rect.y1(), rect.y0(), nearval, farval, upDirection);
+}
+
+
+Matrix4 Matrix4::orthogonalProjection(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float nearval,
+ float farval,
+ float upDirection) {
+
+ // Adapted from Mesa. Note that Microsoft (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glfunc03_8qnj.asp)
+ // and Linux (http://www.xfree86.org/current/glOrtho.3.html) have different matrices shown in their documentation.
+
+ float x, y, z;
+ float tx, ty, tz;
+
+ x = 2.0f / (right-left);
+ y = 2.0f / (top-bottom);
+ z = -2.0f / (farval-nearval);
+ tx = -(right+left) / (right-left);
+ ty = -(top+bottom) / (top-bottom);
+ tz = -(farval+nearval) / (farval-nearval);
+
+ y *= upDirection;
+ ty *= upDirection;
+
+ return
+ Matrix4( x , 0.0f, 0.0f, tx,
+ 0.0f, y , 0.0f, ty,
+ 0.0f, 0.0f, z , tz,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+}
+
+
+Matrix4 Matrix4::perspectiveProjection(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float nearval,
+ float farval,
+ float upDirection) {
+
+ float x, y, a, b, c, d;
+
+ x = (2.0f*nearval) / (right-left);
+ y = (2.0f*nearval) / (top-bottom);
+ a = (right+left) / (right-left);
+ b = (top+bottom) / (top-bottom);
+
+ if (farval >= finf()) {
+ // Infinite view frustum
+ c = -1.0f;
+ d = -2.0f * nearval;
+ } else {
+ c = -(farval+nearval) / (farval-nearval);
+ d = -(2.0f*farval*nearval) / (farval-nearval);
+ }
+
+ debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");
+ y *= upDirection;
+ b *= upDirection;
+
+ return Matrix4(
+ x, 0, a, 0,
+ 0, y, b, 0,
+ 0, 0, c, d,
+ 0, 0, -1, 0);
+}
+
+
+void Matrix4::getPerspectiveProjectionParameters(
+ float& left,
+ float& right,
+ float& bottom,
+ float& top,
+ float& nearval,
+ float& farval,
+ float upDirection) const {
+
+ debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");
+
+ float x = elt[0][0];
+ float y = elt[1][1] * upDirection;
+ float a = elt[0][2];
+ float b = elt[1][2] * upDirection;
+ float c = elt[2][2];
+ float d = elt[2][3];
+
+ // Verify that this really is a projection matrix
+ debugAssertM(elt[3][2] == -1, "Not a projection matrix");
+ debugAssertM(elt[0][1] == 0, "Not a projection matrix");
+ debugAssertM(elt[0][3] == 0, "Not a projection matrix");
+ debugAssertM(elt[1][3] == 0, "Not a projection matrix");
+ debugAssertM(elt[3][3] == 0, "Not a projection matrix");
+ debugAssertM(elt[1][0] == 0, "Not a projection matrix");
+ debugAssertM(elt[2][0] == 0, "Not a projection matrix");
+ debugAssertM(elt[2][1] == 0, "Not a projection matrix");
+ debugAssertM(elt[3][0] == 0, "Not a projection matrix");
+ debugAssertM(elt[3][1] == 0, "Not a projection matrix");
+
+ if (c == -1) {
+ farval = finf();
+ nearval = -d / 2.0f;
+ } else {
+ nearval = d * ((c - 1.0f) / (c + 1.0f) - 1.0f) / (-2.0f * (c - 1.0f) / (c + 1.0f));
+ farval = nearval * ((c - 1.0f) / (c + 1.0f));
+ }
+
+
+ left = (a - 1.0f) * nearval / x;
+ right = 2.0f * nearval / x + left;
+
+ bottom = (b - 1.0f) * nearval / y;
+ top = 2.0f * nearval / y + bottom;
+}
+
+
+Matrix4::Matrix4(
+ float r1c1, float r1c2, float r1c3, float r1c4,
+ float r2c1, float r2c2, float r2c3, float r2c4,
+ float r3c1, float r3c2, float r3c3, float r3c4,
+ float r4c1, float r4c2, float r4c3, float r4c4) {
+ elt[0][0] = r1c1; elt[0][1] = r1c2; elt[0][2] = r1c3; elt[0][3] = r1c4;
+ elt[1][0] = r2c1; elt[1][1] = r2c2; elt[1][2] = r2c3; elt[1][3] = r2c4;
+ elt[2][0] = r3c1; elt[2][1] = r3c2; elt[2][2] = r3c3; elt[2][3] = r3c4;
+ elt[3][0] = r4c1; elt[3][1] = r4c2; elt[3][2] = r4c3; elt[3][3] = r4c4;
+}
+
+/**
+ init should be <B>row major</B>.
+ */
+Matrix4::Matrix4(const float* init) {
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ elt[r][c] = init[r * 4 + c];
+ }
+ }
+}
+
+
+Matrix4::Matrix4(const double* init) {
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ elt[r][c] = (float)init[r * 4 + c];
+ }
+ }
+}
+
+
+Matrix4::Matrix4() {
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ elt[r][c] = 0;
+ }
+ }
+}
+
+
+void Matrix4::setRow(int r, const Vector4& v) {
+ for (int c = 0; c < 4; ++c) {
+ elt[r][c] = v[c];
+ }
+}
+
+
+void Matrix4::setColumn(int c, const Vector4& v) {
+ for (int r = 0; r < 4; ++r) {
+ elt[r][c] = v[r];
+ }
+}
+
+
+const Vector4& Matrix4::row(int r) const {
+ return reinterpret_cast<const Vector4*>(elt[r])[0];
+}
+
+
+Vector4 Matrix4::column(int c) const {
+ Vector4 v;
+ for (int r = 0; r < 4; ++r) {
+ v[r] = elt[r][c];
+ }
+ return v;
+}
+
+
+Matrix4 Matrix4::operator*(const Matrix4& other) const {
+ Matrix4 result;
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ for (int i = 0; i < 4; ++i) {
+ result.elt[r][c] += elt[r][i] * other.elt[i][c];
+ }
+ }
+ }
+
+ return result;
+}
+
+
+Matrix4 Matrix4::operator*(const float s) const {
+ Matrix4 result;
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ result.elt[r][c] = elt[r][c] * s;
+ }
+ }
+
+ return result;
+}
+
+
+Vector3 Matrix4::homoMul(const class Vector3& v, float w) const {
+ Vector4 r = (*this) * Vector4(v, w);
+ return r.xyz() * (1.0f / r.w);
+}
+
+
+Vector4 Matrix4::operator*(const Vector4& vector) const {
+ Vector4 result(0,0,0,0);
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ result[r] += elt[r][c] * vector[c];
+ }
+ }
+
+ return result;
+}
+
+
+Matrix4 Matrix4::transpose() const {
+ Matrix4 result;
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ result.elt[c][r] = elt[r][c];
+ }
+ }
+
+ return result;
+}
+
+
+bool Matrix4::operator!=(const Matrix4& other) const {
+ return ! (*this == other);
+}
+
+
+bool Matrix4::operator==(const Matrix4& other) const {
+
+ // If the bit patterns are identical, they must be
+ // the same matrix. If not, they *might* still have
+ // equal elements due to floating point weirdness.
+ if (memcmp(this, &other, sizeof(Matrix4) == 0)) {
+ return true;
+ }
+
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ if (elt[r][c] != other.elt[r][c]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+float Matrix4::determinant() const {
+ // Determinant is the dot product of the first row and the first row
+ // of cofactors (i.e. the first col of the adjoint matrix)
+ return cofactor().row(0).dot(row(0));
+}
+
+
+Matrix4 Matrix4::adjoint() const {
+ return cofactor().transpose();
+}
+
+
+Matrix4 Matrix4::inverse() const {
+ // Inverse = adjoint / determinant
+
+ Matrix4 A = adjoint();
+
+ // Determinant is the dot product of the first row and the first row
+ // of cofactors (i.e. the first col of the adjoint matrix)
+ float det = A.column(0).dot(row(0));
+
+ return A * (1.0f / det);
+}
+
+
+Matrix4 Matrix4::cofactor() const {
+ Matrix4 out;
+
+ // We'll use i to incrementally compute -1 ^ (r+c)
+ int i = 1;
+
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ // Compute the determinant of the 3x3 submatrix
+ float det = subDeterminant(r, c);
+ out.elt[r][c] = i * det;
+ i = -i;
+ }
+ i = -i;
+ }
+
+ return out;
+}
+
+
+float Matrix4::subDeterminant(int excludeRow, int excludeCol) const {
+ // Compute non-excluded row and column indices
+ int row[3];
+ int col[3];
+
+ for (int i = 0; i < 3; ++i) {
+ row[i] = i;
+ col[i] = i;
+
+ if (i >= excludeRow) {
+ ++row[i];
+ }
+ if (i >= excludeCol) {
+ ++col[i];
+ }
+ }
+
+ // Compute the first row of cofactors
+ float cofactor00 =
+ elt[row[1]][col[1]] * elt[row[2]][col[2]] -
+ elt[row[1]][col[2]] * elt[row[2]][col[1]];
+
+ float cofactor10 =
+ elt[row[1]][col[2]] * elt[row[2]][col[0]] -
+ elt[row[1]][col[0]] * elt[row[2]][col[2]];
+
+ float cofactor20 =
+ elt[row[1]][col[0]] * elt[row[2]][col[1]] -
+ elt[row[1]][col[1]] * elt[row[2]][col[0]];
+
+ // Product of the first row and the cofactors along the first row
+ return
+ elt[row[0]][col[0]] * cofactor00 +
+ elt[row[0]][col[1]] * cofactor10 +
+ elt[row[0]][col[2]] * cofactor20;
+}
+
+
+CoordinateFrame Matrix4::approxCoordinateFrame() const {
+ CoordinateFrame cframe;
+
+ for (int r = 0; r < 3; ++r) {
+ for (int c = 0; c < 3; ++c) {
+ cframe.rotation[r][c] = elt[r][c];
+ }
+ cframe.translation[r] = elt[r][3];
+ }
+
+ // Ensure that the rotation matrix is orthonormal
+ cframe.rotation.orthonormalize();
+
+ return cframe;
+}
+
+
+void Matrix4::serialize(class BinaryOutput& b) const {
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ b.writeFloat32(elt[r][c]);
+ }
+ }
+}
+
+
+void Matrix4::deserialize(class BinaryInput& b) {
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ elt[r][c] = b.readFloat32();
+ }
+ }
+}
+
+std::string Matrix4::toString() const {
+ return G3D::format("[%g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g]",
+ elt[0][0], elt[0][1], elt[0][2], elt[0][3],
+ elt[1][0], elt[1][1], elt[1][2], elt[1][3],
+ elt[2][0], elt[2][1], elt[2][2], elt[2][3],
+ elt[3][0], elt[3][1], elt[3][2], elt[3][3]);
+}
+
+} // namespace
+
+
diff --git a/dep/src/g3dlite/MemoryManager.cpp b/dep/src/g3dlite/MemoryManager.cpp
new file mode 100644
index 00000000000..240188a1f0e
--- /dev/null
+++ b/dep/src/g3dlite/MemoryManager.cpp
@@ -0,0 +1,91 @@
+/**
+ @file MemoryManager.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2009-04-20
+ @edited 2009-05-29
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/MemoryManager.h"
+#include "G3D/System.h"
+
+namespace G3D {
+
+MemoryManager::MemoryManager() {}
+
+
+void* MemoryManager::alloc(size_t s) {
+ return System::malloc(s);
+}
+
+
+void MemoryManager::free(void* ptr) {
+ System::free(ptr);
+}
+
+
+bool MemoryManager::isThreadsafe() const {
+ return true;
+}
+
+
+MemoryManager::Ref MemoryManager::create() {
+ static MemoryManager::Ref m = new MemoryManager();
+ return m;
+}
+
+
+///////////////////////////////////////////////////
+
+AlignedMemoryManager::AlignedMemoryManager() {}
+
+
+void* AlignedMemoryManager::alloc(size_t s) {
+ return System::alignedMalloc(s, 16);
+}
+
+
+void AlignedMemoryManager::free(void* ptr) {
+ System::alignedFree(ptr);
+}
+
+
+bool AlignedMemoryManager::isThreadsafe() const {
+ return true;
+}
+
+
+AlignedMemoryManager::Ref AlignedMemoryManager::create() {
+ static AlignedMemoryManager::Ref m = new AlignedMemoryManager();
+ return m;
+}
+
+
+///////////////////////////////////////////////////
+
+CRTMemoryManager::CRTMemoryManager() {}
+
+
+void* CRTMemoryManager::alloc(size_t s) {
+ return ::malloc(s);
+}
+
+
+void CRTMemoryManager::free(void* ptr) {
+ return ::free(ptr);
+}
+
+
+bool CRTMemoryManager::isThreadsafe() const {
+ return true;
+}
+
+
+CRTMemoryManager::Ref CRTMemoryManager::create() {
+ static CRTMemoryManager::Ref m = new CRTMemoryManager();
+ return m;
+}
+}
diff --git a/dep/src/g3dlite/MeshAlg.cpp b/dep/src/g3dlite/MeshAlg.cpp
new file mode 100644
index 00000000000..626fed92920
--- /dev/null
+++ b/dep/src/g3dlite/MeshAlg.cpp
@@ -0,0 +1,637 @@
+/**
+ @file MeshAlg.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2003-09-14
+ @edited 2008-09-03
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+
+ */
+
+#include "G3D/MeshAlg.h"
+#include "G3D/Table.h"
+#include "G3D/Set.h"
+#include "G3D/Box.h"
+#include "G3D/Sphere.h"
+#include "G3D/vectorMath.h"
+#include "G3D/AABox.h"
+#include "G3D/Image1.h"
+
+#include <climits>
+
+namespace G3D {
+
+const int MeshAlg::Face::NONE = INT_MIN;
+
+void MeshAlg::generateGrid(
+ Array<Vector3>& vertex,
+ Array<Vector2>& texCoord,
+ Array<int>& index,
+ int wCells,
+ int hCells,
+ const Vector2& textureScale,
+ bool spaceCentered,
+ bool twoSided,
+ const CoordinateFrame& xform,
+ const Image1::Ref& height) {
+
+ vertex.fastClear();
+ texCoord.fastClear();
+ index.fastClear();
+
+ // Generate vertices
+ for (int z = 0; z <= hCells; ++z) {
+ for (int x = 0; x <= wCells; ++x) {
+ Vector3 v(x / (float)wCells, 0, z / (float)hCells);
+
+ Vector2 t = v.xz() * textureScale;
+
+ texCoord.append(t);
+
+ if (height.notNull()) {
+ v.y = height->nearest(v.x * (height->width() - 1), v.z * (height->height() - 1)).value;
+ }
+ if (spaceCentered) {
+ v -= Vector3(0.5f, 0, 0.5f);
+ }
+ v = xform.pointToWorldSpace(v);
+ vertex.append(v);
+ }
+ }
+
+ // Generate indices
+ for (int z = 0; z < hCells; ++z) {
+ for (int x = 0; x < wCells; ++x) {
+ int A = x + z * (wCells + 1);
+ int B = A + 1;
+ int C = A + (wCells + 1);
+ int D = C + 1;
+
+ // A B
+ // *-----*
+ // | \ |
+ // | \ |
+ // *-----*
+ // C D
+
+ index.append(A, D, B);
+ index.append(A, C, D);
+ }
+ }
+
+ if (twoSided) {
+ // The index array needs to have reversed winding for the bottom
+ // and offset by the original number of vertices
+ Array<int> ti = index;
+ ti.reverse();
+ for (int i = 0; i < ti.size(); ++i) {
+ ti[i] += vertex.size();
+ }
+ index.append(ti);
+
+ // Duplicate the arrays
+ vertex.append(Array<Vector3>(vertex));
+ texCoord.append(Array<Vector2>(texCoord));
+ }
+}
+
+MeshAlg::Face::Face() {
+ for (int i = 0; i < 3; ++i) {
+ edgeIndex[i] = 0;
+ vertexIndex[i] = 0;
+ }
+}
+
+
+MeshAlg::Edge::Edge() {
+ for (int i = 0; i < 2; ++i) {
+ vertexIndex[i] = 0;
+ // Negative face indices are faces that don't exist
+ faceIndex[i] = -1;
+ }
+}
+
+
+MeshAlg::Geometry& MeshAlg::Geometry::operator=(const MeshAlg::Geometry& src) {
+ vertexArray.resize(src.vertexArray.size());
+ normalArray.resize(src.vertexArray.size());
+
+ System::memcpy(vertexArray.getCArray(), src.vertexArray.getCArray(), sizeof(Vector3)*vertexArray.size());
+ System::memcpy(normalArray.getCArray(), src.normalArray.getCArray(), sizeof(Vector3)*normalArray.size());
+
+ return *this;
+}
+
+
+void MeshAlg::computeNormals(
+ Geometry& geometry,
+ const Array<int>& indexArray) {
+
+ Array<Face> faceArray;
+ Array<Vertex> vertexArray;
+ Array<Edge> edgeArray;
+ Array<Vector3> faceNormalArray;
+
+ computeAdjacency(geometry.vertexArray, indexArray, faceArray, edgeArray, vertexArray);
+
+ computeNormals(geometry.vertexArray, faceArray, vertexArray,
+ geometry.normalArray, faceNormalArray);
+}
+
+
+void MeshAlg::computeNormals(
+ const Array<Vector3>& vertexGeometry,
+ const Array<Face>& faceArray,
+ const Array< Array<int> >& adjacentFaceArray,
+ Array<Vector3>& vertexNormalArray,
+ Array<Vector3>& faceNormalArray) {
+
+ // Construct a fake vertex array for backwards compatibility
+ Array<Vertex> fakeVertexArray;
+ fakeVertexArray.resize(adjacentFaceArray.size());
+
+ for (int v = 0; v < adjacentFaceArray.size(); ++v) {
+ fakeVertexArray[v].faceIndex.resize(adjacentFaceArray[v].size());
+ for (int i = 0; i < fakeVertexArray[v].faceIndex.size(); ++i) {
+ fakeVertexArray[v].faceIndex[i] = adjacentFaceArray[v][i];
+ }
+ // We leave out the edges because they aren't used to compute normals
+ }
+
+ computeNormals(vertexGeometry, faceArray, fakeVertexArray,
+ vertexNormalArray, faceNormalArray);
+}
+
+
+void MeshAlg::computeNormals(
+ const Array<Vector3>& vertexGeometry,
+ const Array<Face>& faceArray,
+ const Array<Vertex>& vertexArray,
+ Array<Vector3>& vertexNormalArray,
+ Array<Vector3>& faceNormalArray) {
+
+ // Face normals (not unit length)
+ faceNormalArray.resize(faceArray.size());
+ for (int f = 0; f < faceArray.size(); ++f) {
+ const Face& face = faceArray[f];
+
+ Vector3 vertex[3];
+ for (int j = 0; j < 3; ++j) {
+ vertex[j] = vertexGeometry[face.vertexIndex[j]];
+ debugAssert(vertex[j].isFinite());
+ }
+
+ faceNormalArray[f] = (vertex[1] - vertex[0]).cross(vertex[2] - vertex[0]);
+# ifdef G3D_DEBUG
+ const Vector3& N = faceNormalArray[f];
+ debugAssert(N.isFinite());
+# endif
+ }
+
+ // Per-vertex normals, computed by averaging
+ vertexNormalArray.resize(vertexGeometry.size());
+ for (int v = 0; v < vertexNormalArray.size(); ++v) {
+ Vector3 sum = Vector3::zero();
+ for (int k = 0; k < vertexArray[v].faceIndex.size(); ++k) {
+ const int f = vertexArray[v].faceIndex[k];
+ sum += faceNormalArray[f];
+ }
+ vertexNormalArray[v] = sum.directionOrZero();
+# ifdef G3D_DEBUG
+ const Vector3& N = vertexNormalArray[v];
+ debugAssert(N.isUnit() || N.isZero());
+# endif
+ }
+
+
+ for (int f = 0; f < faceArray.size(); ++f) {
+ faceNormalArray[f] = faceNormalArray[f].directionOrZero();
+# ifdef G3D_DEBUG
+ const Vector3& N = faceNormalArray[f];
+ debugAssert(N.isUnit() || N.isZero());
+# endif
+ }
+
+}
+
+
+void MeshAlg::computeFaceNormals(
+ const Array<Vector3>& vertexArray,
+ const Array<MeshAlg::Face>& faceArray,
+ Array<Vector3>& faceNormals,
+ bool normalize) {
+
+ faceNormals.resize(faceArray.size());
+
+ for (int f = 0; f < faceArray.size(); ++f) {
+ const MeshAlg::Face& face = faceArray[f];
+
+ const Vector3& v0 = vertexArray[face.vertexIndex[0]];
+ const Vector3& v1 = vertexArray[face.vertexIndex[1]];
+ const Vector3& v2 = vertexArray[face.vertexIndex[2]];
+
+ faceNormals[f] = (v1 - v0).cross(v2 - v0);
+ }
+
+ if (normalize) {
+ for (int f = 0; f < faceArray.size(); ++f) {
+ faceNormals[f] = faceNormals[f].direction();
+ }
+ }
+}
+
+
+void MeshAlg::identifyBackfaces(
+ const Array<Vector3>& vertexArray,
+ const Array<MeshAlg::Face>& faceArray,
+ const Vector4& HP,
+ Array<bool>& backface) {
+
+ Vector3 P = HP.xyz();
+
+ backface.resize(faceArray.size());
+
+ if (fuzzyEq(HP.w, 0.0)) {
+ // Infinite case
+ for (int f = faceArray.size() - 1; f >= 0; --f) {
+ const MeshAlg::Face& face = faceArray[f];
+
+ const Vector3& v0 = vertexArray[face.vertexIndex[0]];
+ const Vector3& v1 = vertexArray[face.vertexIndex[1]];
+ const Vector3& v2 = vertexArray[face.vertexIndex[2]];
+
+ const Vector3 N = (v1 - v0).cross(v2 - v0);
+
+ backface[f] = N.dot(P) < 0;
+ }
+ } else {
+ // Finite case
+ for (int f = faceArray.size() - 1; f >= 0; --f) {
+ const MeshAlg::Face& face = faceArray[f];
+
+ const Vector3& v0 = vertexArray[face.vertexIndex[0]];
+ const Vector3& v1 = vertexArray[face.vertexIndex[1]];
+ const Vector3& v2 = vertexArray[face.vertexIndex[2]];
+
+ const Vector3 N = (v1 - v0).cross(v2 - v0);
+
+ backface[f] = N.dot(P - v0) < 0;
+ }
+ }
+}
+
+
+void MeshAlg::identifyBackfaces(
+ const Array<Vector3>& vertexArray,
+ const Array<MeshAlg::Face>& faceArray,
+ const Vector4& HP,
+ Array<bool>& backface,
+ const Array<Vector3>& faceNormals) {
+
+ Vector3 P = HP.xyz();
+
+ backface.resize(faceArray.size());
+
+ if (fuzzyEq(HP.w, 0.0)) {
+ // Infinite case
+ for (int f = faceArray.size() - 1; f >= 0; --f) {
+ const Vector3& N = faceNormals[f];
+ backface[f] = N.dot(P) < 0;
+ }
+ } else {
+ // Finite case
+ for (int f = faceArray.size() - 1; f >= 0; --f) {
+ const MeshAlg::Face& face = faceArray[f];
+ const Vector3& v0 = vertexArray[face.vertexIndex[0]];
+ const Vector3& N = faceNormals[f];
+
+ backface[f] = N.dot(P - v0) < 0;
+ }
+ }
+}
+
+
+void MeshAlg::createIndexArray(int n, Array<int>& array, int start, int run, int skip) {
+ debugAssert(skip >= 0);
+ debugAssert(run >= 0);
+
+ array.resize(n);
+ if (skip == 0) {
+ for (int i = 0; i < n; ++i) {
+ array[i] = start + i;
+ }
+ } else {
+ int rcount = 0;
+ int j = start;
+ for (int i = 0; i < n; ++i) {
+ array[i] = j;
+
+ ++j;
+ ++rcount;
+
+ if (rcount == run) {
+ rcount = 0;
+ j += skip;
+ }
+ }
+ }
+}
+
+
+void MeshAlg::computeAreaStatistics(
+ const Array<Vector3>& vertexArray,
+ const Array<int>& indexArray,
+ double& minEdgeLength,
+ double& meanEdgeLength,
+ double& medianEdgeLength,
+ double& maxEdgeLength,
+ double& minFaceArea,
+ double& meanFaceArea,
+ double& medianFaceArea,
+ double& maxFaceArea) {
+
+ debugAssert(indexArray.size() % 3 == 0);
+
+ Array<double> area;
+ area.resize(indexArray.size() / 3);
+ Array<double> magnitude;
+ magnitude.resize(indexArray.size());
+
+ for (int i = 0; i < indexArray.size(); i += 3) {
+ const Vector3& v0 = vertexArray[indexArray[i]];
+ const Vector3& v1 = vertexArray[indexArray[i + 1]];
+ const Vector3& v2 = vertexArray[indexArray[i + 2]];
+
+ area[i / 3] = (v1 - v0).cross(v2 - v0).magnitude() / 2.0;
+ magnitude[i] = (v1 - v0).magnitude();
+ magnitude[i + 1] = (v2 - v1).magnitude();
+ magnitude[i + 2] = (v0 - v2).magnitude();
+ }
+
+ area.sort();
+ magnitude.sort();
+
+ minEdgeLength = max(0.0, magnitude[0]);
+ maxEdgeLength = max(0.0, magnitude.last());
+ medianEdgeLength = max(0.0, magnitude[magnitude.size() / 2]);
+ meanEdgeLength = 0;
+ for (int i = 0; i < magnitude.size(); ++i) {
+ meanEdgeLength += magnitude[i];
+ }
+ meanEdgeLength /= magnitude.size();
+
+ minFaceArea = max(0.0, area[0]);
+ maxFaceArea = max(0.0, area.last());
+ medianFaceArea = max(0.0, area[area.size() / 2]);
+ meanFaceArea = 0;
+ for (int i = 0; i < area.size(); ++i) {
+ meanFaceArea += area[i];
+ }
+ meanFaceArea /= area.size();
+
+
+ // Make sure round-off hasn't pushed values less than zero
+ meanFaceArea = max(0.0, meanFaceArea);
+ meanEdgeLength = max(0.0, meanEdgeLength);
+}
+
+
+int MeshAlg::countBoundaryEdges(const Array<MeshAlg::Edge>& edgeArray) {
+ int b = 0;
+
+ for (int i = 0; i < edgeArray.size(); ++i) {
+ if ((edgeArray[i].faceIndex[0] == MeshAlg::Face::NONE) !=
+ (edgeArray[i].faceIndex[1] == MeshAlg::Face::NONE)) {
+ ++b;
+ }
+ }
+
+ return b;
+}
+
+void MeshAlg::computeBounds(
+ const Array<Vector3>& vertexArray,
+ const Array<int>& indexArray,
+ AABox& box,
+ Sphere& sphere) {
+
+ Array<Vector3> newArray;
+ newArray.resize(indexArray.size());
+ for (int i = 0; i < indexArray.size(); ++i) {
+ newArray[i] = vertexArray[indexArray[i]];
+ }
+ computeBounds(newArray, box, sphere);
+}
+
+
+void MeshAlg::computeBounds(
+ const Array<Vector3>& vertexArray,
+ AABox& box,
+ Sphere& sphere) {
+
+ Vector3 xmin, xmax, ymin, ymax, zmin, zmax;
+
+ // FIRST PASS: find 6 minima/maxima points
+ xmin.x = ymin.y = zmin.z = finf();
+ xmax.x = ymax.y = zmax.z = -finf();
+
+ for (int v = 0; v < vertexArray.size(); ++v) {
+ const Vector3& vertex = vertexArray[v];
+
+ if (vertex.x < xmin.x) {
+ xmin = vertex;
+ }
+
+ if (vertex.x > xmax.x) {
+ xmax = vertex;
+ }
+
+ if (vertex.y < ymin.y) {
+ ymin = vertex;
+ }
+
+ if (vertex.y > ymax.y) {
+ ymax = vertex;
+ }
+
+ if (vertex.z < zmin.z) {
+ zmin = vertex;
+ }
+
+ if (vertex.z > zmax.z) {
+ zmax = vertex;
+ }
+ }
+
+ // Set points dia1 & dia2 to the maximally separated pair
+ Vector3 dia1 = xmin;
+ Vector3 dia2 = xmax;
+ {
+ // Set xspan = distance between the 2 points xmin & xmax (squared)
+ double xspan = (xmax - xmin).squaredMagnitude();
+
+ // Same for y & z spans
+ double yspan = (ymax - ymin).squaredMagnitude();
+ double zspan = (zmax - zmin).squaredMagnitude();
+
+ double maxspan = xspan;
+
+ if (yspan > maxspan) {
+ maxspan = yspan;
+ dia1 = ymin;
+ dia2 = ymax;
+ }
+
+ if (zspan > maxspan) {
+ maxspan = zspan;
+ dia1 = zmin;
+ dia2 = zmax;
+ }
+ }
+
+
+ // dia1, dia2 is a diameter of initial sphere
+
+ // calc initial center
+ Vector3 center = (dia1 + dia2) / 2.0;
+
+ // calculate initial radius^2 and radius
+ Vector3 d = dia2 - sphere.center;
+
+ double radSq = d.squaredMagnitude();
+ double rad = sqrt(radSq);
+
+ // SECOND PASS: increment current sphere
+ double old_to_p, old_to_new;
+
+ for (int v = 0; v < vertexArray.size(); ++v) {
+ const Vector3& vertex = vertexArray[v];
+
+ d = vertex - center;
+
+ double old_to_p_sq = d.squaredMagnitude();
+
+ // do r^2 test first
+ if (old_to_p_sq > radSq) {
+ // this point is outside of current sphere
+ old_to_p = sqrt(old_to_p_sq);
+
+ // calc radius of new sphere
+ rad = (rad + old_to_p) / 2.0;
+
+ // for next r^2 compare
+ radSq = rad * rad;
+ old_to_new = old_to_p - rad;
+
+ // calc center of new sphere
+ center = (rad * center + old_to_new * vertex) / old_to_p;
+ }
+ }
+
+ const Vector3 min(xmin.x, ymin.y, zmin.z);
+ const Vector3 max(xmax.x, ymax.y, zmax.z);
+
+ box = AABox(min, max);
+
+ const float boxRadSq = (max - min).squaredMagnitude() * 0.25f;
+
+ if (boxRadSq >= radSq){
+ if (isNaN(center.x) || ! isFinite(rad)) {
+ sphere = Sphere(Vector3::zero(), finf());
+ } else {
+ sphere = Sphere(center, rad);
+ }
+ } else {
+ sphere = Sphere((max + min) * 0.5f, sqrt(boxRadSq));
+ }
+}
+
+void MeshAlg::computeTangentSpaceBasis(
+ const Array<Vector3>& vertexArray,
+ const Array<Vector2>& texCoordArray,
+ const Array<Vector3>& vertexNormalArray,
+ const Array<Face>& faceArray,
+ Array<Vector3>& tangent,
+ Array<Vector3>& binormal) {
+
+ debugAssertM(faceArray.size() != 0, "Unable to calculate valid tangent space without faces.");
+
+ tangent.resize(vertexArray.size());
+ binormal.resize(vertexArray.size());
+
+ // Zero the output arrays.
+ System::memset(tangent.getCArray(), 0, sizeof(Vector3) * tangent.size());
+ System::memset(binormal.getCArray(), 0, sizeof(Vector3) * binormal.size());
+
+ // Iterate over faces, computing the tangent vectors for each
+ // vertex. Accumulate those into the tangent and binormal arrays
+ // and then orthonormalize at the end.
+
+ for (int f = 0; f < faceArray.size(); ++f) {
+ const Face& face = faceArray[f];
+
+ const int i0 = face.vertexIndex[0];
+ const int i1 = face.vertexIndex[1];
+ const int i2 = face.vertexIndex[2];
+
+ const Vector3& v0 = vertexArray[i0];
+ const Vector3& v1 = vertexArray[i1];
+ const Vector3& v2 = vertexArray[i2];
+
+ const Vector2& t0 = texCoordArray[i0];
+ const Vector2& t1 = texCoordArray[i1];
+ const Vector2& t2 = texCoordArray[i2];
+
+ // See http://www.terathon.com/code/tangent.html for a derivation of the following code
+
+ // vertex edges
+ Vector3 ve1 = v1 - v0;
+ Vector3 ve2 = v2 - v0;
+
+ // texture edges
+ Vector2 te1 = t1 - t0;
+ Vector2 te2 = t2 - t0;
+
+ Vector3 n(ve1.cross(ve2).direction());
+ Vector3 t, b;
+
+ float r = te1.x * te2.y - te1.y * te2.x;
+ if (r == 0.0) {
+ // degenerate case
+ Vector3::generateOrthonormalBasis(t, b, n, true);
+ } else {
+ r = 1.0f / r;
+ t = (te2.y * ve1 - te1.y * ve2) * r;
+ b = (te2.x * ve1 - te1.x * ve2) * r;
+ }
+
+ for (int v = 0; v < 3; ++v) {
+ int i = face.vertexIndex[v];
+ tangent[i] += t;
+ binormal[i] += b;
+ }
+ }
+
+ // Normalize the basis vectors
+ for (int v = 0; v < vertexArray.size(); ++v) {
+ // Remove the component parallel to the normal
+ const Vector3& N = vertexNormalArray[v];
+ Vector3& T = tangent[v];
+ Vector3& B = binormal[v];
+
+ debugAssertM(N.isUnit() || N.isZero(), "Input normals must have unit length");
+
+ T -= T.dot(N) * N;
+ B -= B.dot(N) * N;
+
+ // Normalize
+ T = T.directionOrZero();
+ B = B.directionOrZero();
+ }
+}
+
+
+
+} // G3D namespace
diff --git a/dep/src/g3dlite/MeshAlgAdjacency.cpp b/dep/src/g3dlite/MeshAlgAdjacency.cpp
new file mode 100644
index 00000000000..24b5d207c88
--- /dev/null
+++ b/dep/src/g3dlite/MeshAlgAdjacency.cpp
@@ -0,0 +1,739 @@
+/**
+ @file MeshAlgAdjacency.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2003-09-14
+ @edited 2009-04-26
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+
+ */
+
+#include "G3D/Table.h"
+#include "G3D/MeshAlg.h"
+#include "G3D/Set.h"
+#include "G3D/Stopwatch.h"
+#include "G3D/SmallArray.h"
+
+namespace G3D {
+
+/** Two-level table mapping index 0 -> index 1 -> list of face indices */
+class MeshEdgeTable {
+public:
+
+ /** We expect 2 faces per edge. */
+ typedef SmallArray<int, 2> FaceIndexArray;
+
+ class Edge {
+ public:
+ int i1;
+
+ FaceIndexArray faceIndexArray;
+ };
+
+ /** We expect at most 6 edges per vertex; that matches a typical regular grid mesh */
+ typedef SmallArray<Edge, 6> EdgeArray;
+
+ typedef Array< EdgeArray > ET;
+
+private:
+
+ ET table;
+
+public:
+
+ void clear() {
+ table.clear();
+ }
+
+ void resize(int maxV) {
+ table.resize(maxV);
+ }
+
+ /**
+ Inserts the faceIndex into the edge's face list.
+ The index may be a negative number indicating a backface.
+
+ \param v0 Vertex index 0
+ \param v1 Vertex index 1
+ */
+ void insert(int v0, int v1, int faceIndex) {
+
+ debugAssert(v0 <= v1);
+ EdgeArray& edgeArray = table[v0];
+ for (int i = 0; i < edgeArray.size(); ++i) {
+ if (edgeArray[i].i1 == v1) {
+ edgeArray[i].faceIndexArray.push(faceIndex);
+ return;
+ }
+ }
+
+ Edge& p = edgeArray.next();
+ p.i1 = v1;
+ p.faceIndexArray.push(faceIndex);
+ }
+
+ class Iterator {
+ friend class MeshEdgeTable;
+ private:
+
+ int m_i0;
+ /** Pair index */
+ int m_p;
+ ET& m_array;
+ EdgeArray* m_edgeArray;
+ bool m_end;
+
+ public:
+
+ int i0() const {
+ return m_i0;
+ }
+
+ int i1() const {
+ return (*m_edgeArray)[m_p].i1;
+ }
+
+ FaceIndexArray& faceIndex() {
+ return (*m_edgeArray)[m_p].faceIndexArray;
+ }
+
+ Iterator& operator++() {
+ if ((m_i0 >= 0) && (m_p < m_edgeArray->size() - 1)) {
+ ++m_p;
+ } else {
+ // Skip over elements with no face array
+ do {
+ ++m_i0;
+ if (m_i0 == m_array.size()) {
+ m_end = true;
+ return *this;
+ } else {
+ m_edgeArray = &m_array[m_i0];
+ m_p = 0;
+ }
+ } while (m_edgeArray->size() == 0);
+ }
+
+ return *this;
+ }
+
+ bool hasMore() const {
+ return ! m_end;
+ }
+
+ private:
+
+ Iterator(ET& a) : m_i0(-1), m_p(-1), m_array(a), m_edgeArray(NULL), m_end(false) {
+ ++(*this);
+ }
+
+ };
+
+ Iterator begin() {
+ return Iterator(table);
+ }
+};
+
+
+/**
+ Assigns the edge index into the next unassigned edge
+ index. The edge index may be negative, indicating
+ a reverse edge.
+ */
+static void assignEdgeIndex(MeshAlg::Face& face, int e) {
+ for (int i = 0; i < 3; ++i) {
+ if (face.edgeIndex[i] == MeshAlg::Face::NONE) {
+ face.edgeIndex[i] = e;
+ return;
+ }
+ }
+
+ debugAssertM(false, "Face has already been assigned 3 edges");
+}
+
+
+void MeshAlg::computeAdjacency(
+ const Array<Vector3>& vertexGeometry,
+ const Array<int>& indexArray,
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array< Array<int> >& adjacentFaceArray) {
+
+ Array<Vertex> vertexArray;
+
+ computeAdjacency(vertexGeometry, indexArray, faceArray, edgeArray, vertexArray);
+
+ // Convert the vertexArray into adjacentFaceArray
+ adjacentFaceArray.clear();
+ adjacentFaceArray.resize(vertexArray.size());
+ for (int v = 0; v < adjacentFaceArray.size(); ++v) {
+ const SmallArray<int, 6>& src = vertexArray[v].faceIndex;
+ Array<int>& dst = adjacentFaceArray[v];
+ dst.resize(src.size());
+ for (int f = 0; f < dst.size(); ++f) {
+ dst[f] = src[f];
+ }
+ }
+}
+
+
+void MeshAlg::computeAdjacency(
+ const Array<Vector3>& vertexGeometry,
+ const Array<int>& indexArray,
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array<Vertex>& vertexArray) {
+
+ MeshEdgeTable edgeTable;
+
+ edgeArray.clear();
+ vertexArray.clear();
+ faceArray.clear();
+
+ // Face normals
+ Array<Vector3> faceNormal;
+ faceNormal.resize(indexArray.size() / 3);
+ faceArray.resize(faceNormal.size());
+
+ // This array has the same size as the vertex array
+ vertexArray.resize(vertexGeometry.size());
+
+ edgeTable.resize(vertexArray.size());
+
+ // Iterate through the triangle list
+ for (int q = 0, f = 0; q < indexArray.size(); ++f, q += 3) {
+
+ Vector3 vertex[3];
+ MeshAlg::Face& face = faceArray[f];
+
+ // Construct the face
+ for (int j = 0; j < 3; ++j) {
+ int v = indexArray[q + j];
+ face.vertexIndex[j] = v;
+ face.edgeIndex[j] = Face::NONE;
+
+ // Store back pointers in the vertices
+ vertexArray[v].faceIndex.append(f);
+
+ // We'll need these vertices to find the face normal
+ vertex[j] = vertexGeometry[v];
+ }
+
+ // Compute the face normal
+ const Vector3& N = (vertex[1] - vertex[0]).cross(vertex[2] - vertex[0]);
+ faceNormal[f] = N.directionOrZero();
+
+ static const int nextIndex[] = {1, 2, 0};
+
+ // Add each edge to the edge table.
+ for (int j = 0; j < 3; ++j) {
+ const int i0 = indexArray[q + j];
+ const int i1 = indexArray[q + nextIndex[j]];
+
+ if (i0 < i1) {
+ // The edge was directed in the same manner as in the face
+ edgeTable.insert(i0, i1, f);
+ } else {
+ // The edge was directed in the opposite manner as in the face
+ edgeTable.insert(i1, i0, ~f);
+ }
+ }
+ }
+
+ // For each edge in the edge table, create an edge in the edge array.
+ // Collapse every 2 edges from adjacent faces.
+
+ MeshEdgeTable::Iterator cur = edgeTable.begin();
+
+ Array<Edge> tempEdgeArray;
+ while (cur.hasMore()) {
+ MeshEdgeTable::FaceIndexArray& faceIndexArray = cur.faceIndex();
+
+ // Process this edge
+ while (faceIndexArray.size() > 0) {
+
+ // Remove the last index
+ int f0 = faceIndexArray.pop();
+
+ // Find the normal to that face
+ const Vector3& n0 = faceNormal[(f0 >= 0) ? f0 : ~f0];
+
+ bool found = false;
+
+ // We try to find the matching face with the closest
+ // normal. This ensures that we don't introduce a lot
+ // of artificial ridges into flat parts of a mesh.
+ float ndotn = -2;
+ int f1 = -1, i1 = -1;
+
+ // Try to find the face with the matching edge
+ for (int i = faceIndexArray.size() - 1; i >= 0; --i) {
+ int f = faceIndexArray[i];
+
+ if ((f >= 0) != (f0 >= 0)) {
+ // This face contains the oppositely oriented edge
+ // and has not been assigned too many edges
+
+ const Vector3& n1 = faceNormal[(f >= 0) ? f : ~f];
+ float d = n1.dot(n0);
+
+ if (found) {
+ // We previously found a good face; see if this
+ // one is better.
+ if (d > ndotn) {
+ // This face is better.
+ ndotn = d;
+ f1 = f;
+ i1 = i;
+ }
+ } else {
+ // This is the first face we've found
+ found = true;
+ ndotn = d;
+ f1 = f;
+ i1 = i;
+ }
+ }
+ }
+
+ // Create the new edge
+ int e = tempEdgeArray.size();
+ Edge& edge = tempEdgeArray.next();
+
+ edge.vertexIndex[0] = cur.i0();
+ edge.vertexIndex[1] = cur.i1();
+
+ if (f0 >= 0) {
+ edge.faceIndex[0] = f0;
+ edge.faceIndex[1] = Face::NONE;
+ assignEdgeIndex(faceArray[f0], e);
+ } else {
+ // The face indices above are two's complemented.
+ // this code restores them to regular indices.
+ debugAssert((~f0) >= 0);
+ edge.faceIndex[1] = ~f0;
+ edge.faceIndex[0] = Face::NONE;
+
+ // The edge index *does* need to be inverted, however.
+ assignEdgeIndex(faceArray[~f0], ~e);
+ }
+
+ if (found) {
+ // We found a matching face; remove both
+ // faces from the active list.
+ faceIndexArray.fastRemove(i1);
+
+ if (f1 >= 0) {
+ edge.faceIndex[0] = f1;
+ assignEdgeIndex(faceArray[f1], e);
+ } else {
+ edge.faceIndex[1] = ~f1;
+ assignEdgeIndex(faceArray[~f1], ~e);
+ }
+ }
+ }
+
+ ++cur;
+ }
+
+ edgeTable.clear();
+
+ // Move boundary edges to the end of the list and then
+ // clean up the face references into them
+ {
+ // Map old edge indices to new edge indices
+ Array<int> newIndex;
+ newIndex.resize(tempEdgeArray.size());
+
+ // Index of the start and end of the edge array
+ int i = 0;
+ int j = tempEdgeArray.size() - 1;
+
+ edgeArray.resize(tempEdgeArray.size());
+ for (int e = 0; e < tempEdgeArray.size(); ++e) {
+ if (tempEdgeArray[e].boundary()) {
+ newIndex[e] = j;
+ --j;
+ } else {
+ newIndex[e] = i;
+ ++i;
+ }
+ edgeArray[newIndex[e]] = tempEdgeArray[e];
+ }
+
+ debugAssertM(i == j + 1, "Counting from front and back of array did not match");
+
+ // Fix the faces
+ for (int f = 0; f < faceArray.size(); ++f) {
+ Face& face = faceArray[f];
+ for (int q = 0; q < 3; ++q) {
+ int e = face.edgeIndex[q];
+ if (e < 0) {
+ // Backwards edge; twiddle before and after conversion
+ face.edgeIndex[q] = ~newIndex[~e];
+ } else {
+ // Regular edge; remap the index
+ face.edgeIndex[q] = newIndex[e];
+ }
+ }
+ }
+ }
+
+ // Now order the edge indices inside the faces correctly.
+ for (int f = 0; f < faceArray.size(); ++f) {
+ Face& face = faceArray[f];
+ int e0 = face.edgeIndex[0];
+ int e1 = face.edgeIndex[1];
+ int e2 = face.edgeIndex[2];
+
+ // e0 will always remain first. The only
+ // question is whether e1 and e2 should be swapped.
+
+ // See if e1 begins at the vertex where e1 ends.
+ const int e0End = (e0 < 0) ?
+ edgeArray[~e0].vertexIndex[0] :
+ edgeArray[e0].vertexIndex[1];
+
+ const int e1Begin = (e1 < 0) ?
+ edgeArray[~e1].vertexIndex[1] :
+ edgeArray[e1].vertexIndex[0];
+
+ if (e0End != e1Begin) {
+ // We must swap e1 and e2
+ face.edgeIndex[1] = e2;
+ face.edgeIndex[2] = e1;
+ }
+ }
+
+ // Fill out the edge adjacency information in the vertex array
+ for (int e = 0; e < edgeArray.size(); ++e) {
+ const Edge& edge = edgeArray[e];
+ vertexArray[edge.vertexIndex[0]].edgeIndex.append(e);
+ vertexArray[edge.vertexIndex[1]].edgeIndex.append(~e);
+ }
+}
+
+
+void MeshAlg::weldBoundaryEdges(
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array<Vertex>& vertexArray) {
+
+ // Copy over the original edge array
+ Array<Edge> oldEdgeArray = edgeArray;
+
+ // newEdgeIndex[e] is the new index of the old edge with index e
+ // Note that newEdgeIndex[e] might be negative, indicating that
+ // the edge switched direction between the arrays.
+ Array<int> newEdgeIndex;
+ newEdgeIndex.resize(edgeArray.size());
+ edgeArray.resize(0);
+
+ // boundaryEdgeIndices[v_low] is an array of the indices of
+ // all boundary edges whose lower vertex is v_low.
+ Table<int, Array<int> > boundaryEdgeIndices;
+
+ // Copy over non-boundary edges to the new array
+ for (int e = 0; e < oldEdgeArray.size(); ++e) {
+ if (oldEdgeArray[e].boundary()) {
+
+ // Add to the boundary table
+ const int v_low = iMin(oldEdgeArray[e].vertexIndex[0], oldEdgeArray[e].vertexIndex[1]);
+ if (! boundaryEdgeIndices.containsKey(v_low)) {
+ boundaryEdgeIndices.set(v_low, Array<int>());
+ }
+ boundaryEdgeIndices[v_low].append(e);
+
+ // We'll fill out newEdgeIndex[e] later, when we find pairs
+
+ } else {
+
+ // Copy the edge to the new array
+ newEdgeIndex[e] = edgeArray.size();
+ edgeArray.append(oldEdgeArray[e]);
+
+ }
+ }
+
+
+ // Remove all edges from the table that have pairs.
+ Table<int, Array<int> >::Iterator cur = boundaryEdgeIndices.begin();
+ Table<int, Array<int> >::Iterator end = boundaryEdgeIndices.end();
+ while (cur != end) {
+ Array<int>& boundaryEdge = cur->value;
+
+ for (int i = 0; i < boundaryEdge.size(); ++i) {
+ int ei = boundaryEdge[i];
+ const Edge& edgei = oldEdgeArray[ei];
+
+ for (int j = i + 1; j < boundaryEdge.size(); ++j) {
+ int ej = boundaryEdge[j];
+ const Edge& edgej = oldEdgeArray[ej];
+
+ // See if edge ei is the reverse (match) of edge ej.
+
+ // True if the edges match
+ bool match = false;
+
+ // True if edgej's vertex indices are reversed from
+ // edgei's (usually true).
+ bool reversej = false;
+
+ int u = edgei.vertexIndex[0];
+ int v = edgei.vertexIndex[1];
+
+ if (edgei.faceIndex[0] != Face::NONE) {
+ // verts|faces
+ // edgei = [u v A /]
+
+ if (edgej.faceIndex[0] != Face::NONE) {
+ if ((edgej.vertexIndex[0] == v) && (edgej.vertexIndex[1] == u)) {
+ // This is the most common of the four cases
+
+ // edgej = [v u B /]
+ match = true;
+ reversej = true;
+ }
+ } else {
+ if ((edgej.vertexIndex[0] == u) && (edgej.vertexIndex[1] == v)) {
+ // edgej = [u v / B]
+ match = true;
+ }
+ }
+ } else {
+ // edgei = [u v / A]
+ if (edgej.faceIndex[0] != Face::NONE) {
+ if ((edgej.vertexIndex[0] == u) && (edgej.vertexIndex[1] == v)) {
+ // edgej = [u v B /]
+ match = true;
+ }
+ } else {
+ if ((edgej.vertexIndex[0] == v) && (edgej.vertexIndex[1] == u)) {
+ // edgej = [v u / B]
+ match = true;
+ reversej = true;
+ }
+ }
+ }
+
+ if (match) {
+ // ei and ej can be paired as a single edge
+ int e = edgeArray.size();
+ Edge& edge = edgeArray.next();
+
+ // Follow the direction of edgei.
+ edge = edgei;
+ newEdgeIndex[ei] = e;
+
+ // Insert the face index for edgej.
+ int fj = edgej.faceIndex[0];
+ if (fj == Face::NONE) {
+ fj = edgej.faceIndex[1];
+ }
+
+ if (edge.faceIndex[0] == Face::NONE) {
+ edge.faceIndex[0] = fj;
+ } else {
+ edge.faceIndex[1] = fj;
+ }
+
+ if (reversej) {
+ // The new edge is backwards of the old edge for ej
+ newEdgeIndex[ej] = ~e;
+ } else {
+ newEdgeIndex[ej] = e;
+ }
+
+ // Remove both ei and ej from being candidates for future pairing.
+ // Remove ej first since it comes later in the list (removing
+ // ei would decrease the index of ej to j - 1).
+ boundaryEdge.fastRemove(j);
+ boundaryEdge.fastRemove(i);
+
+ // Re-process element i, which is now a new edge index
+ --i;
+
+ // Jump out of the j for-loop
+ break;
+ }
+ }
+ }
+ ++cur;
+ }
+
+ // Anything remaining in the table is a real boundary edge; just copy it to
+ // the end of the array.
+ cur = boundaryEdgeIndices.begin();
+ end = boundaryEdgeIndices.end();
+ while (cur != end) {
+ Array<int>& boundaryEdge = cur->value;
+
+ for (int b = 0; b < boundaryEdge.size(); ++b) {
+ const int e = boundaryEdge[b];
+
+ newEdgeIndex[e] = edgeArray.size();
+ edgeArray.append(oldEdgeArray[e]);
+ }
+
+ ++cur;
+ }
+
+ // Finally, fix up edge indices in the face and vertex arrays
+ for (int f = 0; f < faceArray.size(); ++f) {
+ Face& face = faceArray[f];
+ for (int i = 0; i < 3; ++i) {
+ int e = face.edgeIndex[i];
+
+ if (e < 0) {
+ face.edgeIndex[i] = ~newEdgeIndex[~e];
+ } else {
+ face.edgeIndex[i] = newEdgeIndex[e];
+ }
+ }
+ }
+
+ for (int v = 0; v < vertexArray.size(); ++v) {
+ Vertex& vertex = vertexArray[v];
+ for (int i = 0; i < vertex.edgeIndex.size(); ++i) {
+ int e = vertex.edgeIndex[i];
+
+ if (e < 0) {
+ vertex.edgeIndex[i] = ~newEdgeIndex[~e];
+ } else {
+ vertex.edgeIndex[i] = newEdgeIndex[e];
+ }
+ }
+ }
+}
+
+
+void MeshAlg::weldAdjacency(
+ const Array<Vector3>& originalGeometry,
+ Array<Face>& faceArray,
+ Array<Edge>& edgeArray,
+ Array<Vertex>& vertexArray,
+ double radius) {
+
+ // Num vertices
+ const int n = originalGeometry.size();
+
+ // canonical[v] = first occurance of any vertex near oldVertexArray[v]
+ Array<int> canonical;
+ canonical.resize(n);
+
+ Array<int> toNew, toOld;
+ // Throw away the new vertex array
+ Array<Vector3> dummy;
+ computeWeld(originalGeometry, dummy, toNew, toOld, radius);
+
+ for (int v = 0; v < canonical.size(); ++v) {
+ // Round-trip through the toNew/toOld process. This will give
+ // us the original vertex.
+ canonical[v] = toOld[toNew[v]];
+ }
+
+ // Destroy vertexArray (we reconstruct it below)
+ vertexArray.clear();
+ vertexArray.resize(n);
+
+ bool hasBoundaryEdges = false;
+
+ // Fix edge vertex indices
+ for (int e = 0; e < edgeArray.size(); ++e) {
+ Edge& edge = edgeArray[e];
+
+ const int v0 = canonical[edge.vertexIndex[0]];
+ const int v1 = canonical[edge.vertexIndex[1]];
+
+ edge.vertexIndex[0] = v0;
+ edge.vertexIndex[1] = v1;
+
+ vertexArray[v0].edgeIndex.append(e);
+ vertexArray[v1].edgeIndex.append(~e);
+
+ hasBoundaryEdges = hasBoundaryEdges || edge.boundary();
+ }
+
+ // Fix face vertex indices
+ for (int f = 0; f < faceArray.size(); ++f) {
+ Face& face = faceArray[f];
+ for (int i = 0; i < 3; ++i) {
+ const int v = canonical[face.vertexIndex[i]];
+
+ face.vertexIndex[i] = v;
+
+ // Add the back pointer
+ vertexArray[v].faceIndex.append(f);
+ }
+ }
+
+ if (hasBoundaryEdges) {
+ // As a result of the welding, some of the boundary edges at
+ // the end of the array may now have mates and no longer be
+ // boundaries. Try to pair these up.
+
+ weldBoundaryEdges(faceArray, edgeArray, vertexArray);
+ }
+}
+
+
+void MeshAlg::debugCheckConsistency(
+ const Array<Face>& faceArray,
+ const Array<Edge>& edgeArray,
+ const Array<Vertex>& vertexArray) {
+
+#ifdef _DEBUG
+ for (int v = 0; v < vertexArray.size(); ++v) {
+ const MeshAlg::Vertex& vertex = vertexArray[v];
+
+ for (int i = 0; i < vertex.edgeIndex.size(); ++i) {
+ const int e = vertex.edgeIndex[i];
+ debugAssert(edgeArray[(e >= 0) ? e : ~e].containsVertex(v));
+ }
+
+ for (int i = 0; i < vertex.faceIndex.size(); ++i) {
+ const int f = vertex.faceIndex[i];
+ debugAssert(faceArray[f].containsVertex(v));
+ }
+
+ }
+
+ for (int e = 0; e < edgeArray.size(); ++e) {
+ const MeshAlg::Edge& edge = edgeArray[e];
+
+ for (int i = 0; i < 2; ++i) {
+ debugAssert((edge.faceIndex[i] == MeshAlg::Face::NONE) ||
+ faceArray[edge.faceIndex[i]].containsEdge(e));
+
+ debugAssert(vertexArray[edge.vertexIndex[i]].inEdge(e));
+ }
+ }
+
+ // Every face's edge must be on that face
+ for (int f = 0; f < faceArray.size(); ++f) {
+ const MeshAlg::Face& face = faceArray[f];
+ for (int i = 0; i < 3; ++i) {
+ int e = face.edgeIndex[i];
+ int ei = (e >= 0) ? e : ~e;
+ debugAssert(edgeArray[ei].inFace(f));
+
+ // Make sure the edge is oriented appropriately
+ if (e >= 0) {
+ debugAssert(edgeArray[ei].faceIndex[0] == (int)f);
+ } else {
+ debugAssert(edgeArray[ei].faceIndex[1] == (int)f);
+ }
+
+ debugAssert(vertexArray[face.vertexIndex[i]].inFace(f));
+ }
+ }
+#else
+ (void)faceArray;
+ (void)edgeArray;
+ (void)vertexArray;
+#endif // _DEBUG
+}
+
+} // G3D namespace
diff --git a/dep/src/g3dlite/MeshAlgWeld.cpp b/dep/src/g3dlite/MeshAlgWeld.cpp
new file mode 100644
index 00000000000..6067f17c2fb
--- /dev/null
+++ b/dep/src/g3dlite/MeshAlgWeld.cpp
@@ -0,0 +1,213 @@
+/**
+ @file MeshAlgWeld.cpp
+
+ The MeshAlg::computeWeld method.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2003-10-22
+ @edited 2005-02-24
+
+ Copyright 2000-2003, Morgan McGuire.
+ All rights reserved.
+
+ */
+
+#include "G3D/MeshAlg.h"
+#include "G3D/Table.h"
+#include "G3D/Set.h"
+
+namespace G3D {
+
+namespace _internal {
+
+class Welder {
+private:
+
+ // Intentionally illegal
+ Welder& operator=(const Welder& w);
+
+public:
+ /** Indices of newVertexArray elements in <B>or near</B> a grid cell. */
+ typedef Array<int> List;
+
+ enum {GRID_RES = 32};
+
+ List grid[GRID_RES][GRID_RES][GRID_RES];
+
+ const Array<Vector3>& oldVertexArray;
+ Array<Vector3>& newVertexArray;
+ Array<int>& toNew;
+ Array<int>& toOld;
+
+ /** Must be less than one grid cell, not checked */
+ const double radius;
+
+ /** (oldVertexArray[i] - offset) * scale is on the range [0, 1] */
+ Vector3 offset;
+ Vector3 scale;
+
+ Welder(
+ const Array<Vector3>& _oldVertexArray,
+ Array<Vector3>& _newVertexArray,
+ Array<int>& _toNew,
+ Array<int>& _toOld,
+ double _radius);
+
+ /**
+ Computes the grid index from an ordinate.
+ */
+ void toGridCoords(Vector3 v, int& x, int& y, int& z) const;
+
+ /** Gets the index of a vertex, adding it to
+ newVertexArray if necessary. */
+ int getIndex(const Vector3& vertex);
+
+ void weld();
+};
+
+} // namespace _internal
+
+} // namespace G3D
+
+template<> struct HashTrait<G3D::_internal::Welder::List*> {
+ static size_t hashCode(const G3D::_internal::Welder::List* key) { return reinterpret_cast<size_t>(key); }
+};
+
+namespace G3D {
+namespace _internal {
+
+Welder::Welder(
+ const Array<Vector3>& _oldVertexArray,
+ Array<Vector3>& _newVertexArray,
+ Array<int>& _toNew,
+ Array<int>& _toOld,
+ double _radius) :
+ oldVertexArray(_oldVertexArray),
+ newVertexArray(_newVertexArray),
+ toNew(_toNew),
+ toOld(_toOld),
+ radius(_radius) {
+
+ // Compute a scale factor that moves the range
+ // of all ordinates to [0, 1]
+ Vector3 minBound = Vector3::inf();
+ Vector3 maxBound = -minBound;
+
+ for (int i = 0; i < oldVertexArray.size(); ++i) {
+ minBound = minBound.min(oldVertexArray[i]);
+ maxBound = maxBound.max(oldVertexArray[i]);
+ }
+
+ offset = minBound;
+ scale = maxBound - minBound;
+ for (int i = 0; i < 3; ++i) {
+ // The model might have zero extent along some axis
+ if (fuzzyEq(scale[i], 0.0)) {
+ scale[i] = 1.0;
+ } else {
+ scale[i] = 1.0 / scale[i];
+ }
+ }
+}
+
+
+void Welder::toGridCoords(Vector3 v, int& x, int& y, int& z) const {
+ v = (v - offset) * scale;
+ x = iClamp(iFloor(v.x * GRID_RES), 0, GRID_RES - 1);
+ y = iClamp(iFloor(v.y * GRID_RES), 0, GRID_RES - 1);
+ z = iClamp(iFloor(v.z * GRID_RES), 0, GRID_RES - 1);
+}
+
+
+int Welder::getIndex(const Vector3& vertex) {
+
+ int closestIndex = -1;
+ double distanceSquared = inf();
+
+ int ix, iy, iz;
+ toGridCoords(vertex, ix, iy, iz);
+
+ // Check against all vertices within radius of this grid cube
+ const List& list = grid[ix][iy][iz];
+
+ for (int i = 0; i < list.size(); ++i) {
+ double d = (newVertexArray[list[i]] - vertex).squaredMagnitude();
+
+ if (d < distanceSquared) {
+ distanceSquared = d;
+ closestIndex = list[i];
+ }
+ }
+
+ if (distanceSquared <= radius * radius) {
+
+ return closestIndex;
+
+ } else {
+
+ // This is a new vertex
+ int newIndex = newVertexArray.size();
+ newVertexArray.append(vertex);
+
+ // Create a new vertex and store its index in the
+ // neighboring grid cells (usually, only 1 neighbor)
+
+ Set<List*> neighbors;
+
+ for (float dx = -1; dx <= +1; ++dx) {
+ for (float dy = -1; dy <= +1; ++dy) {
+ for (float dz = -1; dz <= +1; ++dz) {
+ int ix, iy, iz;
+ toGridCoords(vertex + Vector3(dx, dy, dz) * radius, ix, iy, iz);
+ neighbors.insert(&(grid[ix][iy][iz]));
+ }
+ }
+ }
+
+ Set<List*>::Iterator neighbor(neighbors.begin());
+ Set<List*>::Iterator none(neighbors.end());
+
+ while (neighbor != none) {
+ (*neighbor)->append(newIndex);
+ ++neighbor;
+ }
+
+ return newIndex;
+ }
+}
+
+
+void Welder::weld() {
+ newVertexArray.resize(0);
+
+ // Prime the vertex positions
+ for (int i = 0; i < oldVertexArray.size(); ++i) {
+ getIndex(oldVertexArray[i]);
+ }
+
+ // Now create the official remapping by snapping to
+ // nearby vertices.
+ toNew.resize(oldVertexArray.size());
+ toOld.resize(newVertexArray.size());
+
+ for (int oi = 0; oi < oldVertexArray.size(); ++oi) {
+ toNew[oi] = getIndex(oldVertexArray[oi]);
+ toOld[toNew[oi]] = oi;
+ }
+}
+
+} // internal namespace
+
+
+void MeshAlg::computeWeld(
+ const Array<Vector3>& oldVertexArray,
+ Array<Vector3>& newVertexArray,
+ Array<int>& toNew,
+ Array<int>& toOld,
+ double radius) {
+
+ _internal::Welder welder(oldVertexArray, newVertexArray, toNew, toOld, radius);
+ welder.weld();
+}
+
+} // G3D namespace
diff --git a/dep/src/g3dlite/MeshBuilder.cpp b/dep/src/g3dlite/MeshBuilder.cpp
new file mode 100644
index 00000000000..1bf2bab5d1c
--- /dev/null
+++ b/dep/src/g3dlite/MeshBuilder.cpp
@@ -0,0 +1,113 @@
+/**
+ @file MeshBuilder.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2002-02-27
+ @edited 2005-02-24
+ */
+
+#include "G3D/MeshBuilder.h"
+#include "G3D/MeshAlg.h"
+
+namespace G3D {
+
+void MeshBuilder::setName(const std::string& n) {
+ name = n;
+}
+
+
+void MeshBuilder::commit(std::string& n, Array<int>& indexArray, Array<Vector3>& outvertexArray) {
+ n = name;
+
+ // Make the data fit in a unit cube
+ centerTriList();
+
+ Array<int> toNew, toOld;
+
+ if (close == MeshBuilder::AUTO_WELD) {
+ Array<int> index;
+ MeshAlg::createIndexArray(triList.size(), index);
+ double minEdgeLen, maxEdgeLen, meanEdgeLen, medianEdgeLen;
+ double minFaceArea, maxFaceArea, meanFaceArea, medianFaceArea;
+ MeshAlg::computeAreaStatistics(triList, index,
+ minEdgeLen, meanEdgeLen, medianEdgeLen, maxEdgeLen,
+ minFaceArea, meanFaceArea, medianFaceArea, maxFaceArea);
+ close = minEdgeLen * 0.1;
+ }
+
+ MeshAlg::computeWeld(triList, outvertexArray, toNew, toOld, close);
+
+ // Construct triangles
+ for (int t = 0; t < triList.size(); t += 3) {
+ int index[3];
+
+ for (int i = 0; i < 3; ++i) {
+ index[i] = toNew[t + i];
+ }
+
+ // Throw out zero size triangles
+ if ((index[0] != index[1]) &&
+ (index[1] != index[2]) &&
+ (index[2] != index[0])) {
+ indexArray.append(index[0], index[1], index[2]);
+ }
+ }
+}
+
+
+void MeshBuilder::centerTriList() {
+ // Compute the range of the vertices
+ Vector3 vmin, vmax;
+
+ computeBounds(vmin, vmax);
+
+ Vector3 diagonal = vmax - vmin;
+ double scale = max(max(diagonal.x, diagonal.y), diagonal.z) / 2;
+ debugAssert(scale > 0);
+
+ Vector3 translation = vmin + diagonal / 2;
+
+ // Center and scale all vertices in the input list
+ int v;
+
+ //Matrix3 rot90 = Matrix3::fromAxisAngle(Vector3::UNIT_Y, toRadians(180)) * Matrix3::fromAxisAngle(Vector3::UNIT_X, toRadians(90));
+ for (v = 0; v < triList.size(); ++v) {
+ triList[v] = (triList[v] - translation) / scale;
+ //triList[v] = rot90 * triList[v];
+ }
+}
+
+
+void MeshBuilder::computeBounds(Vector3& min, Vector3& max) {
+ min = Vector3::inf();
+ max = -min;
+
+ int v;
+ for (v = 0; v < triList.size(); ++v) {
+ min = min.min(triList[v]);
+ max = max.max(triList[v]);
+ }
+}
+
+
+void MeshBuilder::addTriangle(const Vector3& a, const Vector3& b, const Vector3& c) {
+ triList.append(a, b, c);
+
+ if (_twoSided) {
+ triList.append(c, b, a);
+ }
+}
+
+
+void MeshBuilder::addQuad(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d) {
+ addTriangle(a, b, c);
+ addTriangle(a, c, d);
+}
+
+
+void MeshBuilder::addTriangle(const Triangle& t) {
+ addTriangle(t.vertex(0), t.vertex(1), t.vertex(2));
+}
+
+} // namespace
diff --git a/dep/src/g3dlite/NetAddress.cpp b/dep/src/g3dlite/NetAddress.cpp
new file mode 100644
index 00000000000..64d692d4763
--- /dev/null
+++ b/dep/src/g3dlite/NetAddress.cpp
@@ -0,0 +1,164 @@
+/**
+ @file NetMessage.cpp
+
+ @maintainer Morgan McGuire, morgan@cs.brown.edu
+ @created 2005-02-06
+ @edited 2005-02-06
+ */
+#include "G3D/platform.h"
+#include "G3D/NetAddress.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Array.h"
+#include "G3D/stringutils.h"
+#include "G3D/System.h"
+#include "G3D/NetworkDevice.h"
+
+#if defined(G3D_LINUX) || defined(G3D_OSX)
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <netinet/tcp.h>
+ #define _alloca alloca
+
+# ifndef SOCKADDR_IN
+# define SOCKADDR_IN struct sockaddr_in
+# endif
+# ifndef SOCKET
+# define SOCKET int
+# endif
+
+// SOCKADDR_IN is supposed to be defined in NetAddress.h
+#ifndef SOCKADDR_IN
+# error Network headers included in wrong order
+#endif
+#endif
+
+
+namespace G3D {
+
+NetAddress::NetAddress() {
+ System::memset(&addr, 0, sizeof(addr));
+}
+
+void NetAddress::init(uint32 host, uint16 port) {
+ if ((host != 0) || (port != 0)) {
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ if (host == 0) {
+ host = INADDR_ANY;
+ }
+ addr.sin_addr.s_addr = htonl(host);
+ } else {
+ System::memset(&addr, 0, sizeof(addr));
+ }
+}
+
+
+NetAddress::NetAddress(
+ const std::string& hostname,
+ uint16 port) {
+ init(hostname, port);
+}
+
+
+void NetAddress::init(
+ const std::string& hostname,
+ uint16 port) {
+
+ uint32 addr;
+
+ if (hostname == "") {
+ addr = INADDR_NONE;
+ } else {
+ addr = inet_addr(hostname.c_str());
+ }
+
+ // The address wasn't in numeric form, resolve it
+ if (addr == INADDR_NONE) {
+ // Get the IP address of the server and store it in host
+ struct hostent* host = gethostbyname(hostname.c_str());
+
+ if (host == NULL) {
+ init(0, 0);
+ return;
+ }
+
+ System::memcpy(&addr, host->h_addr_list[0], host->h_length);
+ }
+
+ if (addr != INADDR_NONE) {
+ addr = ntohl(addr);
+ }
+ init(addr, port);
+}
+
+
+NetAddress::NetAddress(uint32 hostip, uint16 port) {
+ init(hostip, port);
+}
+
+
+NetAddress NetAddress::broadcastAddress(uint16 port) {
+ return NetAddress(NetworkDevice::instance()->broadcastAddressArray()[0], port);
+}
+
+
+NetAddress::NetAddress(const std::string& hostnameAndPort) {
+
+ Array<std::string> part = stringSplit(hostnameAndPort, ':');
+
+ debugAssert(part.length() == 2);
+ init(part[0], atoi(part[1].c_str()));
+}
+
+
+NetAddress::NetAddress(const SOCKADDR_IN& a) {
+ addr = a;
+}
+
+
+NetAddress::NetAddress(const struct in_addr& addr, uint16 port) {
+ #ifdef G3D_WIN32
+ init(ntohl(addr.S_un.S_addr), port);
+ #else
+ init(htonl(addr.s_addr), port);
+ #endif
+}
+
+
+void NetAddress::serialize(class BinaryOutput& b) const {
+ b.writeUInt32(ip());
+ b.writeUInt16(port());
+}
+
+
+void NetAddress::deserialize(class BinaryInput& b) {
+ uint32 i;
+ uint16 p;
+
+ i = b.readUInt32();
+ p = b.readUInt16();
+
+ init(i, p);
+}
+
+
+bool NetAddress::ok() const {
+ return addr.sin_family != 0;
+}
+
+
+std::string NetAddress::ipString() const {
+ return format("%s", inet_ntoa(*(in_addr*)&(addr.sin_addr)));
+}
+
+
+std::string NetAddress::toString() const {
+ return ipString() + format(":%d", ntohs(addr.sin_port));
+}
+
+}
diff --git a/dep/src/g3dlite/NetworkDevice.cpp b/dep/src/g3dlite/NetworkDevice.cpp
new file mode 100644
index 00000000000..246c97d4dbf
--- /dev/null
+++ b/dep/src/g3dlite/NetworkDevice.cpp
@@ -0,0 +1,1362 @@
+/**
+ @file NetworkDevice.cpp
+
+ @maintainer Morgan McGuire, morgan@cs.brown.edu
+ @created 2002-11-22
+ @edited 2006-02-24
+ */
+
+#include <stdlib.h>
+#include <time.h>
+#include "G3D/platform.h"
+#include "G3D/TextOutput.h"
+#include "G3D/NetworkDevice.h"
+#include "G3D/NetAddress.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Log.h"
+#include "G3D/G3DGameUnits.h"
+#include "G3D/stringutils.h"
+#include "G3D/debug.h"
+
+#include <cstring>
+
+#if defined(G3D_LINUX) || defined(G3D_OSX) || defined(G3D_FREEBSD)
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <ifaddrs.h>
+# include <netinet/in.h>
+# include <net/if.h>
+# ifdef __linux__
+# include <sys/ioctl.h>
+# include <netinet/in.h>
+# include <unistd.h>
+# include <string.h>
+// Match Linux to FreeBSD
+# define AF_LINK AF_PACKET
+# else
+# include <net/if_dl.h>
+# include <sys/sockio.h>
+# endif
+
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <netinet/tcp.h>
+ #include <sys/ioctl.h>
+ #include <netinet/if_ether.h>
+ #include <net/ethernet.h>
+ #include <net/if.h>
+
+ #include <sys/types.h>
+
+ #define _alloca alloca
+
+ /** Define an error code for non-windows platforms. */
+ int WSAGetLastError() {
+ return -1;
+ }
+
+ #define SOCKET_ERROR -1
+
+ static std::string socketErrorCode(int code) {
+ return G3D::format("CODE %d: %s\n", code, strerror(code));
+ }
+
+ static std::string socketErrorCode() {
+ return socketErrorCode(errno);
+ }
+
+ static const int WSAEWOULDBLOCK = -100;
+
+ typedef int SOCKET;
+ typedef struct sockaddr_in SOCKADDR_IN;
+
+#else
+
+ // Windows
+ static std::string socketErrorCode(int code) {
+ LPTSTR formatMsg = NULL;
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ code,
+ 0,
+ (LPTSTR)&formatMsg,
+ 0,
+ NULL);
+
+ return G3D::format("CODE %d: %s\n", code, formatMsg);
+ }
+
+ static std::string socketErrorCode() {
+ return socketErrorCode(GetLastError());
+ }
+
+#endif
+
+
+#ifndef _SOCKLEN_T
+# if defined(G3D_WIN32) || defined(G3D_OSX)
+ typedef int socklen_t;
+# endif
+#endif
+
+namespace G3D {
+
+NetworkDevice* NetworkDevice::s_instance = NULL;
+
+std::ostream& operator<<(std::ostream& os, const NetAddress& a) {
+ return os << a.toString();
+}
+
+
+static void logSocketInfo(const SOCKET& sock) {
+ uint32 val;
+ socklen_t sz = 4;
+ int ret;
+
+ ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&val, (socklen_t*)&sz);
+ logPrintf("SOL_SOCKET/SO_RCVBUF = %d\n", val);
+
+ ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&val, (socklen_t*)&sz);
+ logPrintf("SOL_SOCKET/SO_SNDBUF = %d\n", val);
+
+ // Note: timeout = 0 means no timeout
+ ret = getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&val, (socklen_t*)&sz);
+ logPrintf("SOL_SOCKET/SO_RCVTIMEO = %d\n", val);
+
+ ret = getsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&val, (socklen_t*)&sz);
+ logPrintf("SOL_SOCKET/SO_SNDTIMEO = %d\n", val);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** Invokes select on one socket. Returns SOCKET_ERROR on error, 0 if
+ there is no read pending, sock if there a read pending. */
+static int selectOneReadSocket(const SOCKET& sock) {
+ // 0 time timeout is specified to poll and return immediately
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ // Create a set that contains just this one socket
+ fd_set socketSet;
+ FD_ZERO(&socketSet);
+ FD_SET(sock, &socketSet);
+
+ int ret = select(sock + 1, &socketSet, NULL, NULL, &timeout);
+
+ return ret;
+}
+
+
+/** Returns true if the socket has a read pending */
+static bool readWaiting(const SOCKET& sock) {
+ int ret = selectOneReadSocket(sock);
+
+ switch (ret) {
+ case SOCKET_ERROR:
+ logPrintf("ERROR: selectOneReadSocket returned "
+ "SOCKET_ERROR in readWaiting(). %s", socketErrorCode().c_str());
+ // Return true so that we'll force an error on read and close
+ // the socket.
+ return true;
+
+ case 0:
+ return false;
+
+ default:
+ return true;
+ }
+}
+
+
+/** Invokes select on one socket. */
+static int selectOneWriteSocket(const SOCKET& sock) {
+ // 0 time timeout is specified to poll and return immediately
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ // Create a set that contains just this one socket
+ fd_set socketSet;
+ FD_ZERO(&socketSet);
+ FD_SET(sock, &socketSet);
+
+ return select(sock + 1, NULL, &socketSet, NULL, &timeout);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+NetworkDevice* NetworkDevice::instance() {
+ if (s_instance == NULL) {
+ s_instance = new NetworkDevice();
+ if (! s_instance->init()) {
+ delete s_instance;
+ s_instance = NULL;
+ }
+ }
+ return s_instance;
+}
+
+
+void NetworkDevice::cleanup() {
+ if (s_instance) {
+ s_instance->_cleanup();
+ delete s_instance;
+ s_instance = NULL;
+ }
+}
+
+
+NetworkDevice::NetworkDevice() {
+ initialized = false;
+}
+
+
+NetworkDevice::~NetworkDevice() {
+}
+
+
+std::string NetworkDevice::localHostName() const {
+ char ac[128];
+ if (gethostname(ac, sizeof(ac)) == -1) {
+ Log::common()->printf("Error while getting local host name\n");
+ return "localhost";
+ }
+ return gethostbyname(ac)->h_name;
+}
+
+#ifndef G3D_WIN32
+const char* errnoToString() {
+ switch (errno) {
+ case EBADF:
+ return "file descriptor is invalid.";
+
+ case EINVAL:
+ return "Request or argp is not valid.";
+
+ case ENOTTY:
+ return
+ "file descriptor is not associated with a character special device OR "
+ "The specified request does not apply to the "
+ "kind of object that the descriptor fildes references.";
+
+ case EADDRNOTAVAIL:
+ return "Address not available.";
+
+ default:
+ {
+ static char buffer[20];
+ sprintf(buffer, "Error %d", errno);
+ return buffer;
+ }
+ }
+}
+#endif
+
+
+NetworkDevice::EthernetAdapter::EthernetAdapter() {
+ name = "";
+ ip = 0;
+ hostname = "";
+ subnet = 0;
+ broadcast = 0;
+ for (int i = 0; i < 6; ++i) {
+ mac[i] = 0;
+ }
+}
+
+void NetworkDevice::EthernetAdapter::describe(TextOutput& t) const {
+ t.writeSymbol("{");
+ t.pushIndent();
+ t.writeNewline();
+
+ t.writeSymbols("hostname", "=");
+ t.writeString(hostname);
+ t.writeNewline();
+
+ t.writeSymbols("name", "=");
+ t.writeString(name);
+ t.writeNewline();
+
+ t.writeSymbols("ip", "=");
+ t.writeSymbol(formatIP(ip));
+ t.writeNewline();
+
+ t.writeSymbols("subnet", "=");
+ t.writeSymbol(formatIP(subnet));
+ t.writeNewline();
+
+ t.writeSymbols("broadcast", "=");
+ t.writeSymbol(formatIP(broadcast));
+ t.writeNewline();
+
+ t.writeSymbols("mac", "=");
+ t.writeSymbol(formatMAC(mac));
+ t.writeNewline();
+
+ t.popIndent();
+ t.writeSymbol("}");
+ t.writeNewline();
+}
+
+
+void NetworkDevice::addAdapter(const EthernetAdapter& a) {
+ m_adapterArray.append(a);
+ if (a.broadcast != 0) {
+ int i = m_broadcastAddresses.findIndex(a.broadcast);
+ if (i == -1) {
+ m_broadcastAddresses.append(a.broadcast);
+ }
+ }
+}
+
+
+std::string NetworkDevice::formatIP(uint32 addr) {
+ return format("%3d.%3d.%3d.%3d", (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
+ (addr >> 8) & 0xFF, addr & 0xFF);
+}
+
+
+std::string NetworkDevice::formatMAC(const uint8 MAC[6]) {
+ return format("%02x:%02x:%02x:%02x:%02x:%02x", MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]);
+}
+
+
+#ifdef G3D_WIN32
+
+bool NetworkDevice::init() {
+ debugAssert(! initialized);
+
+ logPrintf("Network Startup");
+ logPrintf("Starting WinSock networking.\n");
+ WSADATA wsda;
+ WSAStartup(MAKEWORD(G3D_WINSOCK_MAJOR_VERSION, G3D_WINSOCK_MINOR_VERSION), &wsda);
+
+ std::string hostname = "localhost";
+ {
+ char ac[128];
+ if (gethostname(ac, sizeof(ac)) == -1) {
+ logPrintf("Warning: Error while getting local host name\n");
+ } else {
+ hostname = gethostbyname(ac)->h_name;
+ }
+ }
+
+ EthernetAdapter a;
+ a.hostname = hostname;
+ a.name = "";
+ a.ip = NetAddress(hostname, 0).ip();
+
+ // TODO: Find subnet on Win32
+ a.subnet = 0x0000FFFF;
+
+ // TODO: Find broadcast on Win32
+ a.broadcast = 0xFFFFFFFF;
+
+ // TODO: find MAC on Win32
+
+ addAdapter(a);
+
+ std::string machine = localHostName();
+ std::string addr = NetAddress(machine, 0).ipString();
+ logPrintf(
+ "Network:\n"
+ " Status: %s\n"
+ " Loaded winsock specification version %d (%d is "
+ "the highest available)\n"
+ " %d sockets available\n"
+ " Largest UDP datagram packet size is %d bytes\n\n",
+ wsda.szDescription,
+ wsda.szSystemStatus,
+ wsda.wVersion,
+ wsda.wHighVersion,
+ wsda.iMaxSockets,
+ wsda.iMaxUdpDg);
+
+ // TODO: WSAIoctl for subnet and broadcast addresses
+ // http://msdn.microsoft.com/en-us/library/ms741621(VS.85).aspx
+ //
+ // TODO: SIO_GET_INTERFACE_LIST
+
+ initialized = true;
+
+ return true;
+}
+#endif
+
+
+#if defined(G3D_LINUX) || defined(G3D_OSX) || defined(G3D_FREEBSD)
+
+const sockaddr_in* castToIP4(const sockaddr* addr) {
+ if (addr == NULL) {
+ return NULL;
+ } else if (addr->sa_family == AF_INET) {
+ // An IPv4 address
+ return reinterpret_cast<const sockaddr_in*>(addr);
+ } else {
+ // Not an IPv4 address
+ return NULL;
+ }
+}
+
+uint32 getIP(const sockaddr_in* addr) {
+ if (addr != NULL) {
+ return ntohl(addr->sin_addr.s_addr);
+ } else {
+ return 0;
+ }
+}
+
+
+bool NetworkDevice::init() {
+ debugAssert(! initialized);
+
+ // Used for combining the MAC and ip information
+ typedef Table<std::string, EthernetAdapter> AdapterTable;
+
+ AdapterTable table;
+
+ // Head of a linked list of network interfaces on this machine
+ ifaddrs* ifap = NULL;
+
+ int r = getifaddrs(&ifap);
+
+ if (r != 0) {
+ logPrintf("ERROR: getifaddrs returned %d\n", r);
+ return false;
+ }
+
+ ifaddrs* current = ifap;
+
+ if (current == NULL) {
+ logPrintf("WARNING: No network interfaces found\n");
+ EthernetAdapter a;
+ a.name = "fallback";
+ a.hostname = "localhost";
+ a.ip = (127 << 24) | 1;
+ a.broadcast = 0xFFFFFFFF;
+ a.subnet = 0x000000FF;
+ addAdapter(a);
+
+ } else {
+
+ while (current != NULL) {
+
+ bool up = (current->ifa_flags & IFF_UP);
+ bool loopback = (current->ifa_flags & IFF_LOOPBACK);
+
+ if (! up || loopback) {
+ // Skip this adapter; it is offline or is a loopback
+ current = current->ifa_next;
+ continue;
+ }
+
+ if (! table.containsKey(current->ifa_name)) {
+ EthernetAdapter a;
+ a.name = current->ifa_name;
+ table.set(a.name, a);
+ }
+
+ // This adapter must exist because it was created above
+ EthernetAdapter& adapter = table[current->ifa_name];
+
+ const sockaddr_in* interfaceAddress = castToIP4(current->ifa_addr);
+ const sockaddr_in* broadcastAddress = castToIP4(current->ifa_dstaddr);
+ const sockaddr_in* subnetMask = castToIP4(current->ifa_netmask);
+
+ uint32 ip = getIP(interfaceAddress);
+ uint32 ba = getIP(broadcastAddress);
+ uint32 sn = getIP(subnetMask);
+
+ if (ip != 0) {
+ adapter.ip = ip;
+ }
+
+ if (ba != 0) {
+ adapter.broadcast = ba;
+ }
+
+ if (sn != 0) {
+ adapter.subnet = sn;
+ }
+
+ uint8_t* MAC = NULL;
+ // Extract MAC address
+ if ((current->ifa_addr != NULL) && (current->ifa_addr->sa_family == AF_LINK)) {
+# ifdef __linux__
+ {
+ // Linux
+ struct ifreq ifr;
+
+ int fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ ifr.ifr_addr.sa_family = AF_INET;
+ strcpy(ifr.ifr_name, current->ifa_name);
+ ioctl(fd, SIOCGIFHWADDR, &ifr);
+ close(fd);
+
+ MAC = reinterpret_cast<uint8_t*>(ifr.ifr_hwaddr.sa_data);
+ }
+# else
+ {
+ // The MAC address and the interfaceAddress come in as
+ // different interfaces with the same name.
+
+ // Posix/FreeBSD/Mac OS
+ sockaddr_dl* sdl = (struct sockaddr_dl *)current->ifa_addr;
+ MAC = reinterpret_cast<uint8_t*>(LLADDR(sdl));
+ }
+# endif
+
+ // See if there was a MAC address
+ if (MAC != NULL) {
+ bool anyNonZero = false;
+ for (int i = 0; i < 6; ++i) {
+ anyNonZero = anyNonZero || (MAC[i] != 0);
+ }
+ if (anyNonZero) {
+ System::memcpy(adapter.mac, MAC, 6);
+ }
+ }
+ }
+
+ current = current->ifa_next;
+ }
+
+ freeifaddrs(ifap);
+ ifap = NULL;
+ }
+
+ // Extract all interesting adapters from the table
+ for (AdapterTable::Iterator it = table.begin(); it.hasMore(); ++it) {
+ const EthernetAdapter& adapter = it->value;
+
+ // Only add adapters that have IP addresses
+ if (adapter.ip != 0) {
+ addAdapter(adapter);
+ } else {
+ logPrintf("NetworkDevice: Ignored adapter %s because ip = 0\n", adapter.name.c_str());
+ }
+ }
+
+ initialized = true;
+
+ return true;
+}
+
+#endif
+
+
+void NetworkDevice::_cleanup() {
+ debugAssert(initialized);
+
+ logPrintf("Network Cleanup");
+# ifdef G3D_WIN32
+ WSACleanup();
+# endif
+ logPrintf("Network cleaned up.");
+}
+
+bool NetworkDevice::bind(SOCKET sock, const NetAddress& addr) const {
+ Log::common()->printf("Binding socket %d on port %d ",
+ sock, htons(addr.addr.sin_port));
+ if (::bind(sock, (struct sockaddr*)&(addr.addr), sizeof(addr.addr)) ==
+ SOCKET_ERROR) {
+
+ Log::common()->println("FAIL");
+ Log::common()->println(socketErrorCode());
+ closesocket(sock);
+ return false;
+ }
+
+ Log::common()->println("Ok");
+ return true;
+}
+
+
+void NetworkDevice::closesocket(SOCKET& sock) const {
+ if (sock != 0) {
+ #ifdef G3D_WIN32
+ ::closesocket(sock);
+ #else
+ close(sock);
+ #endif
+
+ Log::common()->printf("Closed socket %d\n", sock);
+ sock = 0;
+ }
+}
+
+
+void NetworkDevice::localHostAddresses(Array<NetAddress>& array) const {
+ array.resize(0);
+
+ char ac[128];
+
+ if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) {
+ Log::common()->printf("Error while getting local host name\n");
+ return;
+ }
+
+ struct hostent* phe = gethostbyname(ac);
+ if (phe == 0) {
+ Log::common()->printf("Error while getting local host address\n");
+ return;
+ }
+
+ for (int i = 0; (phe->h_addr_list[i] != 0); ++i) {
+ struct in_addr addr;
+ memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));
+ array.append(NetAddress(addr));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+Conduit::Conduit() : binaryOutput("<memory>", G3D_LITTLE_ENDIAN) {
+ sock = 0;
+ mSent = 0;
+ mReceived = 0;
+ bSent = 0;
+ bReceived = 0;
+}
+
+
+Conduit::~Conduit() {
+ NetworkDevice::instance()->closesocket(sock);
+}
+
+
+uint64 Conduit::bytesSent() const {
+ return bSent;
+}
+
+
+uint64 Conduit::bytesReceived() const {
+ return bReceived;
+}
+
+
+uint64 Conduit::messagesSent() const {
+ return mSent;
+}
+
+
+uint64 Conduit::messagesReceived() const {
+ return mReceived;
+}
+
+
+bool Conduit::ok() const {
+ return (sock != 0) && (sock != SOCKET_ERROR);
+}
+
+
+bool Conduit::messageWaiting() {
+ return readWaiting(sock);
+}
+
+
+/**
+ Increases the send and receive sizes of a socket to 2 MB from 8k
+ */
+static void increaseBufferSize(SOCKET sock) {
+
+ // Increase the buffer size; the default (8192) is too easy to
+ // overflow when the network latency is high.
+ {
+ uint32 val = 1024 * 1024 * 2;
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+ (char*)&val, sizeof(val)) == SOCKET_ERROR) {
+ Log::common()->printf("WARNING: Increasing socket "
+ "receive buffer to %d failed.\n", val);
+ Log::common()->println(socketErrorCode());
+ }
+
+ if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
+ (char*)&val, sizeof(val)) == SOCKET_ERROR) {
+ Log::common()->printf("WARNING: Increasing socket "
+ "send buffer to %d failed.\n", val);
+ Log::common()->println(socketErrorCode());
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+ReliableConduitRef ReliableConduit::create(const NetAddress& address) {
+ return new ReliableConduit(address);
+}
+
+
+ReliableConduit::ReliableConduit(
+ const NetAddress& _addr) : state(NO_MESSAGE), receiveBuffer(NULL),
+ receiveBufferTotalSize(0), receiveBufferUsedSize(0) {
+
+ NetworkDevice* nd = NetworkDevice::instance();
+
+ messageType = 0;
+
+ addr = _addr;
+ Log::common()->print("Creating a TCP socket ");
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+
+ if (sock == SOCKET_ERROR) {
+ Log::common()->println("FAIL");
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ return;
+ }
+
+ Log::common()->println("Ok");
+
+ // Setup socket options (both constructors should set the same options)
+
+ // Disable Nagle's algorithm (we send lots of small packets)
+ const int T = true;
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+ (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
+
+ Log::common()->println("WARNING: Disabling Nagel's "
+ "algorithm failed.");
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->println("Disabled Nagel's algorithm.");
+ }
+
+ // Set the NO LINGER option so the socket doesn't hang around if
+ // there is unsent data in the queue when it closes.
+ struct linger ling;
+ ling.l_onoff = 0;
+ ling.l_linger = 0;
+ if (setsockopt(sock, SOL_SOCKET, SO_LINGER,
+ (const char*)&ling, sizeof(ling)) == SOCKET_ERROR) {
+
+ Log::common()->println("WARNING: Setting socket no linger failed.");
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->println("Set socket option no_linger.");
+ }
+
+ // Set reuse address so that a new server can start up soon after
+ // an old one has closed.
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
+
+ Log::common()->println("WARNING: Setting socket reuseaddr failed.");
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->println("Set socket option reuseaddr.");
+ }
+
+ // Ideally, we'd like to specify IPTOS_LOWDELAY as well.
+
+ logSocketInfo(sock);
+
+ increaseBufferSize(sock);
+
+ Log::common()->printf("Created TCP socket %d\n", sock);
+
+ std::string x = addr.toString();
+ Log::common()->printf("Connecting to %s on TCP socket %d ", x.c_str(), sock);
+
+ int ret = connect(sock, (struct sockaddr *) &(addr.addr), sizeof(addr.addr));
+
+ if (ret == WSAEWOULDBLOCK) {
+ RealTime t = System::time() + 5.0;
+ // Non-blocking; we must wait until select returns non-zero
+ while ((selectOneWriteSocket(sock) == 0) && (System::time() < t)) {
+ System::sleep(0.02);
+ }
+
+ // TODO: check for failure on the select call
+
+ } else if (ret != 0) {
+ sock = (SOCKET)SOCKET_ERROR;
+ Log::common()->println("FAIL");
+ Log::common()->println(socketErrorCode());
+ return;
+ }
+
+ Log::common()->println("Ok");
+}
+
+
+ReliableConduit::ReliableConduit(
+ const SOCKET& _sock,
+ const NetAddress& _addr) :
+ state(NO_MESSAGE),
+ receiveBuffer(NULL),
+ receiveBufferTotalSize(0),
+ receiveBufferUsedSize(0) {
+ sock = _sock;
+ addr = _addr;
+
+ messageType = 0;
+
+ // Setup socket options (both constructors should set the same options)
+
+ // Disable Nagle's algorithm (we send lots of small packets)
+ const int T = true;
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+ (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
+
+ Log::common()->println("WARNING: Disabling Nagel's algorithm failed.");
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->println("Disabled Nagel's algorithm.");
+ }
+
+ // Set the NO LINGER option so the socket doesn't hang around if
+ // there is unsent data in the queue when it closes.
+ struct linger ling;
+ ling.l_onoff = 0;
+ ling.l_linger = 0;
+ if (setsockopt(sock, SOL_SOCKET, SO_LINGER,
+ (const char*)&ling, sizeof(ling)) == SOCKET_ERROR) {
+
+ Log::common()->println("WARNING: Setting socket no linger failed.");
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->println("Set socket option no_linger.");
+ }
+
+ // Set reuse address so that a new server can start up soon after
+ // an old one has closed.
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
+
+ Log::common()->println("WARNING: Setting socket reuseaddr failed.");
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->println("Set socket option reuseaddr.");
+ }
+
+ // Ideally, we'd like to specify IPTOS_LOWDELAY as well.
+
+ logSocketInfo(sock);
+}
+
+
+ReliableConduit::~ReliableConduit() {
+ free(receiveBuffer);
+ receiveBuffer = NULL;
+ receiveBufferTotalSize = 0;
+ receiveBufferUsedSize = 0;
+}
+
+
+bool ReliableConduit::messageWaiting() {
+ switch (state) {
+ case HOLDING:
+ // We've already read the message and are waiting
+ // for a receive call.
+ return true;
+
+ case RECEIVING:
+
+ if (! ok()) {
+ return false;
+ }
+ // We're currently receiving the message. Read a little more.
+ receiveIntoBuffer();
+
+ if (messageSize == receiveBufferUsedSize) {
+ // We've read the whole mesage. Switch to holding state
+ // and return true.
+ state = HOLDING;
+ return true;
+ } else {
+ // There are more bytes left to read. We'll read them on
+ // the next call. Because the *entire* message is not ready,
+ // return false.
+ return false;
+ }
+ break;
+
+ case NO_MESSAGE:
+ if (Conduit::messageWaiting()) {
+ // Message incoming. Read the header.
+
+ state = RECEIVING;
+ receiveHeader();
+
+ // Loop back around now that we're in the receive state; we
+ // may be able to read the whole message before returning
+ // to the caller.
+ return messageWaiting();
+ } else {
+ // No message incoming.
+ return false;
+ }
+ }
+
+ debugAssertM(false, "Should not reach this point");
+ return false;
+}
+
+
+uint32 ReliableConduit::waitingMessageType() {
+ // The messageWaiting call is what actually receives the message.
+ if (messageWaiting()) {
+ return messageType;
+ } else {
+ return 0;
+ }
+}
+
+
+void ReliableConduit::sendBuffer(const BinaryOutput& b) {
+ NetworkDevice* nd = NetworkDevice::instance();
+ int ret = ::send(sock, (const char*)b.getCArray(), b.size(), 0);
+
+ if (ret == SOCKET_ERROR) {
+ Log::common()->println("Error occured while sending message.");
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ return;
+ }
+
+ ++mSent;
+ bSent += b.size();
+
+ // Verify the packet was actually sent
+ // Conversion to unsigned is safe because -1 is caught earlier
+ debugAssert(ret == b.size());
+}
+
+
+/** Null serializer. Used by reliable conduit::send(type) */
+class Dummy {
+public:
+ void serialize(BinaryOutput& b) const { (void)b; }
+};
+
+
+void ReliableConduit::send(uint32 type) {
+ static Dummy dummy;
+ send(type, dummy);
+}
+
+
+
+NetAddress ReliableConduit::address() const {
+ return addr;
+}
+
+
+void ReliableConduit::receiveHeader() {
+ NetworkDevice* nd = NetworkDevice::instance();
+ debugAssert(state == RECEIVING);
+
+ // Read the type
+ uint32 tmp;
+ int ret = recv(sock, (char*)&tmp, sizeof(tmp), 0);
+
+ // The type is the first four bytes. It is little endian.
+ if (System::machineEndian() == G3D_LITTLE_ENDIAN) {
+ messageType = tmp;
+ } else {
+ // Swap the byte order
+ for (int i = 0; i < 4; ++i) {
+ ((char*)&messageType)[i] = ((char*)&tmp)[3 - i];
+ }
+ }
+
+ if ((ret == SOCKET_ERROR) || (ret != sizeof(messageType))) {
+ Log::common()->printf("Call to recv failed. ret = %d,"
+ " sizeof(messageType) = %d\n",
+ (int)ret, (int)sizeof(messageType));
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ messageType = 0;
+ return;
+ }
+
+ // Read the size
+ ret = recv(sock, (char*)&messageSize, sizeof(messageSize), 0);
+
+ if ((ret == SOCKET_ERROR) || (ret != sizeof(messageSize))) {
+ Log::common()->printf("Call to recv failed. ret = %d,"
+ " sizeof(len) = %d\n", (int)ret,
+ (int)sizeof(messageSize));
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ messageType = 0;
+ return;
+ }
+
+ messageSize = ntohl(messageSize);
+ debugAssert(messageSize < 6e7);
+
+ debugAssert(receiveBufferUsedSize == 0);
+
+ // Extend the size of the buffer.
+ if (messageSize > receiveBufferTotalSize) {
+ receiveBuffer = realloc(receiveBuffer, messageSize);
+ receiveBufferTotalSize = messageSize;
+ }
+
+ if (receiveBuffer == NULL) {
+ Log::common()->println("Could not allocate a memory buffer "
+ "during receivePacket.");
+ nd->closesocket(sock);
+ }
+
+ bReceived += 4;
+}
+
+
+void ReliableConduit::receiveIntoBuffer() {
+ NetworkDevice* nd = NetworkDevice::instance();
+
+ debugAssert(state == RECEIVING);
+ debugAssert(messageType != 0);
+ debugAssertM(receiveBufferUsedSize < messageSize, "Message already received.");
+ debugAssertM(messageSize >= receiveBufferUsedSize, "Message size overflow.");
+
+ // Read the data itself
+ int ret = 0;
+ uint32 left = messageSize - receiveBufferUsedSize;
+ int count = 0;
+ while ((ret != SOCKET_ERROR) && (left > 0) && (count < 100)) {
+
+ ret = recv(sock, ((char*)receiveBuffer) + receiveBufferUsedSize, left, 0);
+
+ if (ret > 0) {
+ left -= ret;
+ receiveBufferUsedSize += ret;
+ bReceived += ret;
+
+ if (left > 0) {
+ // There's still more. Give the machine a chance to read
+ // more data, but don't wait forever.
+
+ ++count;
+ System::sleep(0.001);
+ }
+ } else {
+ // Something went wrong; our blocking read returned nothing.
+ break;
+ }
+ }
+
+ if ((ret == 0) || (ret == SOCKET_ERROR)) {
+
+ if (ret == SOCKET_ERROR) {
+ Log::common()->printf("Call to recv failed. ret = %d,"
+ " sizeof(messageSize) = %d\n", ret, messageSize);
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->printf("recv returned 0\n");
+ }
+ nd->closesocket(sock);
+ return;
+ }
+
+ ++mReceived;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+LightweightConduitRef LightweightConduit::create(
+ uint16 receivePort,
+ bool enableReceive,
+ bool enableBroadcast) {
+
+ return new LightweightConduit(receivePort, enableReceive, enableBroadcast);
+}
+
+LightweightConduit::LightweightConduit(
+ uint16 port,
+ bool enableReceive,
+ bool enableBroadcast) {
+ NetworkDevice* nd = NetworkDevice::instance();
+
+ Log::common()->print("Creating a UDP socket ");
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ if (sock == SOCKET_ERROR) {
+ sock = 0;
+ Log::common()->println("FAIL");
+ Log::common()->println(socketErrorCode());
+ return;
+ }
+ Log::common()->println("Ok");
+
+ if (enableReceive) {
+ debugAssert(port != 0);
+ if (! nd->bind(sock, NetAddress(0, port))) {
+ nd->closesocket(sock);
+ sock = (SOCKET)SOCKET_ERROR;
+ }
+ }
+
+ // Figuring out the MTU seems very complicated, so we just set it to 1000,
+ // which is likely to be safe. See IP_MTU for more information.
+ MTU = 1000;
+
+ increaseBufferSize(sock);
+
+ if (enableBroadcast) {
+ int TR = true;
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
+ (const char*)&TR, sizeof(TR)) != 0) {
+ Log::common()->println("Call to setsockopt failed");
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ sock = 0;
+ return;
+ }
+ }
+
+ Log::common()->printf("Done creating UDP socket %d\n", sock);
+
+ alreadyReadMessage = false;
+}
+
+
+LightweightConduit::~LightweightConduit() {
+}
+
+
+bool LightweightConduit::receive(NetAddress& sender) {
+ // This both checks to ensure that a message was waiting and
+ // actively consumes the message from the network stream if
+ // it has not been read yet.
+ uint32 t = waitingMessageType();
+ if (t == 0) {
+ return false;
+ }
+
+ sender = messageSender;
+ alreadyReadMessage = false;
+
+ if (messageBuffer.size() < 4) {
+ // Something went wrong
+ return false;
+ }
+
+ return true;
+}
+
+
+void LightweightConduit::sendBuffer(const NetAddress& a, BinaryOutput& b) {
+ NetworkDevice* nd = NetworkDevice::instance();
+ if (sendto(sock, (const char*)b.getCArray(), b.size(), 0,
+ (struct sockaddr *) &(a.addr), sizeof(a.addr)) == SOCKET_ERROR) {
+ Log::common()->printf("Error occured while sending packet "
+ "to %s\n", inet_ntoa(a.addr.sin_addr));
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ } else {
+ ++mSent;
+ bSent += b.size();
+ }
+}
+
+
+bool LightweightConduit::messageWaiting() {
+ // We may have already pulled the message off the network stream
+ return alreadyReadMessage || Conduit::messageWaiting();
+}
+
+
+uint32 LightweightConduit::waitingMessageType() {
+ NetworkDevice* nd = NetworkDevice::instance();
+ if (! messageWaiting()) {
+ return 0;
+ }
+
+ if (! alreadyReadMessage) {
+ messageBuffer.resize(8192);
+
+ SOCKADDR_IN remote_addr;
+ int iRemoteAddrLen = sizeof(sockaddr);
+
+ int ret = recvfrom(sock, (char*)messageBuffer.getCArray(),
+ messageBuffer.size(), 0, (struct sockaddr *) &remote_addr,
+ (socklen_t*)&iRemoteAddrLen);
+
+ if (ret == SOCKET_ERROR) {
+ Log::common()->println("Error: recvfrom failed in "
+ "LightweightConduit::waitingMessageType().");
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ messageBuffer.resize(0);
+ messageSender = NetAddress();
+ messageType = 0;
+ return 0;
+ }
+
+ messageSender = NetAddress(remote_addr);
+
+ ++mReceived;
+ bReceived += ret;
+
+ messageBuffer.resize(ret, DONT_SHRINK_UNDERLYING_ARRAY);
+
+ // The type is the first four bytes. It is little endian.
+ if (System::machineEndian() == G3D_LITTLE_ENDIAN) {
+ messageType = *((uint32*)messageBuffer.getCArray());
+ } else {
+ // Swap the byte order
+ for (int i = 0; i < 4; ++i) {
+ ((char*)&messageType)[i] = messageBuffer[3 - i];
+ }
+ }
+
+ alreadyReadMessage = true;
+ }
+
+ return messageType;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+NetListenerRef NetListener::create(const uint16 port) {
+ return new NetListener(port);
+}
+
+
+NetListener::NetListener(uint16 port) {
+ NetworkDevice* nd = NetworkDevice::instance();
+
+ // Start the listener socket
+ Log::common()->print("Creating a listener ");
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+
+ if (sock == SOCKET_ERROR) {
+ Log::common()->printf("FAIL");
+ Log::common()->println(socketErrorCode());
+ return;
+ }
+ Log::common()->println("Ok");
+
+ const int T = true;
+
+ // Set reuse address so that a new server can start up soon after
+ // an old one has closed.
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
+
+ Log::common()->println("WARNING: Setting socket reuseaddr failed.");
+ Log::common()->println(socketErrorCode());
+ } else {
+ Log::common()->println("Set socket option reuseaddr.");
+ }
+
+
+ if (! nd->bind(sock, NetAddress(0, port))) {
+ Log::common()->printf("Unable to bind!\n");
+ nd->closesocket(sock);
+ sock = (SOCKET)SOCKET_ERROR;
+ return;
+ }
+
+ Log::common()->printf("Listening on port %5d ", port);
+
+ // listen is supposed to return 0 when there is no error.
+ // The 2nd argument is the number of connections to allow pending
+ // at any time.
+ int L = listen(sock, 100);
+ if (L == SOCKET_ERROR) {
+ Log::common()->println("FAIL");
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ sock = (SOCKET)SOCKET_ERROR;
+ return;
+ }
+ Log::common()->println("Ok");
+ Log::common()->printf("Now listening on socket %d.\n\n", sock);
+}
+
+
+NetListener::~NetListener() {
+ NetworkDevice* nd = NetworkDevice::instance();
+ nd->closesocket(sock);
+}
+
+
+ReliableConduitRef NetListener::waitForConnection() {
+ NetworkDevice* nd = NetworkDevice::instance();
+ // The address of the connecting host
+ SOCKADDR_IN remote_addr;
+ int iAddrLen = sizeof(remote_addr);
+
+ Log::common()->println("Blocking in NetListener::waitForConnection().");
+
+ SOCKET sClient = accept(sock, (struct sockaddr*) &remote_addr,
+ (socklen_t*)&iAddrLen);
+
+ if (sClient == SOCKET_ERROR) {
+ Log::common()->println("Error in NetListener::acceptConnection.");
+ Log::common()->println(socketErrorCode());
+ nd->closesocket(sock);
+ return NULL;
+ }
+
+ Log::common()->printf("%s connected, transferred to socket %d.\n",
+ inet_ntoa(remote_addr.sin_addr), sClient);
+
+ #ifndef G3D_WIN32
+ return new ReliableConduit(sClient,
+ NetAddress(htonl(remote_addr.sin_addr.s_addr),
+ ntohs(remote_addr.sin_port)));
+ #else
+ return new ReliableConduit(sClient,
+ NetAddress(ntohl(remote_addr.sin_addr.S_un.S_addr),
+ ntohs(remote_addr.sin_port)));
+ #endif
+}
+
+
+bool NetListener::ok() const {
+ return (sock != 0) && (sock != SOCKET_ERROR);
+}
+
+
+bool NetListener::clientWaiting() const {
+ return readWaiting(sock);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+void NetworkDevice::describeSystem(
+ TextOutput& t) {
+
+ t.writeSymbols("Network", "{");
+ t.writeNewline();
+ t.pushIndent();
+
+ for (int i = 0; i < m_adapterArray.size(); ++i) {
+ m_adapterArray[i].describe(t);
+ }
+
+
+ t.popIndent();
+ t.writeSymbols("}");
+ t.writeNewline();
+ t.writeNewline();
+}
+
+
+void NetworkDevice::describeSystem(
+ std::string& s) {
+
+ TextOutput t;
+ describeSystem(t);
+ t.commitString(s);
+}
+
+} // namespace
diff --git a/dep/src/g3dlite/PhysicsFrame.cpp b/dep/src/g3dlite/PhysicsFrame.cpp
new file mode 100644
index 00000000000..28ba8f8d477
--- /dev/null
+++ b/dep/src/g3dlite/PhysicsFrame.cpp
@@ -0,0 +1,77 @@
+/**
+ @file PhysicsFrame.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2002-07-09
+ @edited 2006-01-25
+*/
+
+#include "G3D/platform.h"
+#include "G3D/PhysicsFrame.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+PhysicsFrame::PhysicsFrame() {
+ translation = Vector3::zero();
+ rotation = Quat();
+}
+
+
+PhysicsFrame::PhysicsFrame(
+ const CoordinateFrame& coordinateFrame) {
+
+ translation = coordinateFrame.translation;
+ rotation = Quat(coordinateFrame.rotation);
+}
+
+
+PhysicsFrame PhysicsFrame::operator*(const PhysicsFrame& other) const {
+ PhysicsFrame result;
+
+ result.rotation = rotation * other.rotation;
+ result.translation = translation + rotation.toRotationMatrix() * other.translation;
+
+ return result;
+}
+
+
+CoordinateFrame PhysicsFrame::toCoordinateFrame() const {
+ CoordinateFrame f;
+
+ f.translation = translation;
+ f.rotation = rotation.toRotationMatrix();
+
+ return f;
+}
+
+
+PhysicsFrame PhysicsFrame::lerp(
+ const PhysicsFrame& other,
+ float alpha) const {
+
+ PhysicsFrame result;
+
+ result.translation = translation.lerp(other.translation, alpha);
+ result.rotation = rotation.slerp(other.rotation, alpha);
+
+ return result;
+}
+
+
+void PhysicsFrame::deserialize(class BinaryInput& b) {
+ translation.deserialize(b);
+ rotation.deserialize(b);
+}
+
+
+void PhysicsFrame::serialize(class BinaryOutput& b) const {
+ translation.serialize(b);
+ rotation.serialize(b);
+}
+
+
+}; // namespace
+
diff --git a/dep/src/g3dlite/Plane.cpp b/dep/src/g3dlite/Plane.cpp
index 5ae60b0f762..9b7991c0333 100644
--- a/dep/src/g3dlite/Plane.cpp
+++ b/dep/src/g3dlite/Plane.cpp
@@ -1,33 +1,51 @@
/**
@file Plane.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2003-02-06
@edited 2006-01-29
*/
#include "G3D/platform.h"
-#include "G3D/format.h"
#include "G3D/Plane.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/BinaryInput.h"
#include "G3D/stringutils.h"
namespace G3D {
+Plane::Plane(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Plane::serialize(class BinaryOutput& b) const {
+ _normal.serialize(b);
+ b.writeFloat64(_distance);
+}
+
+
+void Plane::deserialize(class BinaryInput& b) {
+ _normal.deserialize(b);
+ _distance = (float)b.readFloat64();
+}
+
+
Plane::Plane(
Vector4 point0,
Vector4 point1,
Vector4 point2) {
debugAssertM(
- point0.w != 0 ||
- point1.w != 0 ||
+ point0.w != 0 ||
+ point1.w != 0 ||
point2.w != 0,
"At least one point must be finite.");
// Rotate the points around so that the finite points come first.
- while ((point0.w == 0) &&
+ while ((point0.w == 0) &&
((point1.w == 0) || (point2.w != 0))) {
Vector4 temp = point0;
point0 = point1;
@@ -60,6 +78,7 @@ Plane::Plane(
_distance = _normal.dot(point0.xyz());
}
+
Plane::Plane(
const Vector3& point0,
const Vector3& point1,
@@ -69,14 +88,16 @@ Plane::Plane(
_distance = _normal.dot(point0);
}
+
Plane::Plane(
const Vector3& __normal,
const Vector3& point) {
- _normal = __normal.direction();
+ _normal = __normal.direction();
_distance = _normal.dot(point);
}
+
Plane Plane::fromEquation(float a, float b, float c, float d) {
Vector3 n(a, b, c);
float magnitude = n.magnitude();
@@ -85,11 +106,13 @@ Plane Plane::fromEquation(float a, float b, float c, float d) {
return Plane(n, -d);
}
+
void Plane::flip() {
_normal = -_normal;
_distance = -_distance;
}
+
void Plane::getEquation(Vector3& n, float& d) const {
double _d;
getEquation(n, _d);
@@ -101,6 +124,7 @@ void Plane::getEquation(Vector3& n, double& d) const {
d = -_distance;
}
+
void Plane::getEquation(float& a, float& b, float& c, float& d) const {
double _a, _b, _c, _d;
getEquation(_a, _b, _c, _d);
@@ -117,9 +141,9 @@ void Plane::getEquation(double& a, double& b, double& c, double& d) const {
d = -_distance;
}
+
std::string Plane::toString() const {
return format("Plane(%g, %g, %g, %g)", _normal.x, _normal.y, _normal.z, _distance);
}
}
-
diff --git a/dep/src/g3dlite/PrecomputedRandom.cpp b/dep/src/g3dlite/PrecomputedRandom.cpp
new file mode 100644
index 00000000000..387ded35195
--- /dev/null
+++ b/dep/src/g3dlite/PrecomputedRandom.cpp
@@ -0,0 +1,125 @@
+/**
+ @file PrecomputedRandom.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-03-31
+ @edited 2009-07-01
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/PrecomputedRandom.h"
+#include "G3D/System.h"
+
+namespace G3D {
+
+PrecomputedRandom::PrecomputedRandom(int dataSize, uint32 seed) :
+ Random((void*)NULL),
+ m_hemiUniform(NULL),
+ m_sphereBits(NULL),
+ m_modMask(dataSize - 1),
+ m_freeData(true) {
+
+ alwaysAssertM(isPow2(dataSize), "dataSize must be a power of 2");
+ m_index = seed & m_modMask;
+
+ HemiUniformData* h;
+ SphereBitsData* s;
+ m_hemiUniform = h = (HemiUniformData*) System::malloc(sizeof(HemiUniformData) * dataSize);
+ m_sphereBits = s = (SphereBitsData*) System::malloc(sizeof(SphereBitsData) * dataSize);
+
+ Random r;
+
+ for (int i = 0; i < dataSize; ++i) {
+ h[i].uniform = r.uniform();
+ r.cosHemi(h[i].cosHemiX, h[i].cosHemiY, h[i].cosHemiZ);
+
+ s[i].bits = r.bits();
+ r.sphere(s[i].sphereX, s[i].sphereY, s[i].sphereZ);
+ }
+
+}
+
+
+PrecomputedRandom::PrecomputedRandom(const HemiUniformData* data1, const SphereBitsData* data2, int dataSize, uint32 seed) :
+ Random((void*)NULL),
+ m_hemiUniform(data1),
+ m_sphereBits(data2),
+ m_modMask(dataSize - 1),
+ m_freeData(false) {
+
+ m_index = seed & m_modMask;
+ alwaysAssertM(isPow2(dataSize), "dataSize must be a power of 2");
+}
+
+
+PrecomputedRandom::~PrecomputedRandom() {
+ if (m_freeData) {
+ System::free(const_cast<HemiUniformData*>(m_hemiUniform));
+ System::free(const_cast<SphereBitsData*>(m_sphereBits));
+ }
+}
+
+float PrecomputedRandom::uniform(float low, float high) {
+ m_index = (m_index + 1) & m_modMask;
+ return low + m_hemiUniform[m_index].uniform * (high - low);
+}
+
+
+float PrecomputedRandom::uniform() {
+ m_index = (m_index + 1) & m_modMask;
+ return m_hemiUniform[m_index].uniform;
+}
+
+
+void PrecomputedRandom::cosHemi(float& x, float& y, float& z) {
+ m_index = (m_index + 1) & m_modMask;
+ x = m_hemiUniform[m_index].cosHemiX;
+ y = m_hemiUniform[m_index].cosHemiY;
+ z = m_hemiUniform[m_index].cosHemiZ;
+}
+
+void PrecomputedRandom::cosPowHemi(const float k, float& x, float& y, float& z) {
+ // Computing a cosPowHemi costs 4 slow functions (pow, sqrt, sin,
+ // cos). We can do it with two, given a cosHemi sample, basically
+ // saving the cost of sin and cos and making a single 128-byte
+ // memory read (for a vector) instead of two (for adjacent uniform
+ // floats).
+
+ // cos^1 distribution sample
+ float cos1;
+ cosHemi(x, y, cos1);
+
+ // Fix the distribution by adjusting the cosine:
+ // rnd(cos^k t) = (rnd(cos(t))^2)^(1/k)
+
+ // produces cos^k distribution sample
+ z = pow(cos1, 2.0f / (1.0f + k));
+
+ // Rescale x and y by sqrt(1.0f - square(z)) / sqrt(x*x + y*y).
+ // Add a very tiny offset to handle the (almost impossibly unlikely) case where
+ // z = 1 and x^2+y^2 = 0.
+ static const float eps = 0.000001f;
+ const float s = sqrt((1.0f + eps - square(z)) / (square(x) + square(y) + eps));
+
+ x *= s;
+ y *= s;
+}
+
+
+uint32 PrecomputedRandom::bits() {
+ m_index = (m_index + 1) & m_modMask;
+ return m_sphereBits[m_index].bits;
+}
+
+
+void PrecomputedRandom::sphere(float& x, float& y, float& z) {
+ m_index = (m_index + 1) & m_modMask;
+ x = m_sphereBits[m_index].sphereX;
+ y = m_sphereBits[m_index].sphereY;
+ z = m_sphereBits[m_index].sphereZ;
+}
+
+}
diff --git a/dep/src/g3dlite/Quat.cpp b/dep/src/g3dlite/Quat.cpp
new file mode 100644
index 00000000000..225c5b51acc
--- /dev/null
+++ b/dep/src/g3dlite/Quat.cpp
@@ -0,0 +1,583 @@
+/**
+ @file Quat.cpp
+
+ Quaternion implementation based on Watt & Watt page 363
+
+ @author Morgan McGuire, graphics3d.com
+
+ @created 2002-01-23
+ @edited 2006-01-31
+ */
+
+#include "G3D/Quat.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+Quat Quat::fromAxisAngleRotation(
+ const Vector3& axis,
+ float angle) {
+
+ Quat q;
+
+ q.w = cos(angle / 2.0f);
+ q.imag() = axis.direction() * sin(angle / 2.0f);
+
+ return q;
+}
+
+
+Quat::Quat(
+ const Matrix3& rot) {
+
+ static const int plus1mod3[] = {1, 2, 0};
+
+ // Find the index of the largest diagonal component
+ // These ? operations hopefully compile to conditional
+ // move instructions instead of branches.
+ int i = (rot[1][1] > rot[0][0]) ? 1 : 0;
+ i = (rot[2][2] > rot[i][i]) ? 2 : i;
+
+ // Find the indices of the other elements
+ int j = plus1mod3[i];
+ int k = plus1mod3[j];
+
+ // Index the elements of the vector part of the quaternion as a float*
+ float* v = (float*)(this);
+
+ // If we attempted to pre-normalize and trusted the matrix to be
+ // perfectly orthonormal, the result would be:
+ //
+ // double c = sqrt((rot[i][i] - (rot[j][j] + rot[k][k])) + 1.0)
+ // v[i] = -c * 0.5
+ // v[j] = -(rot[i][j] + rot[j][i]) * 0.5 / c
+ // v[k] = -(rot[i][k] + rot[k][i]) * 0.5 / c
+ // w = (rot[j][k] - rot[k][j]) * 0.5 / c
+ //
+ // Since we're going to pay the sqrt anyway, we perform a post normalization, which also
+ // fixes any poorly normalized input. Multiply all elements by 2*c in the above, giving:
+
+ // nc2 = -c^2
+ double nc2 = ((rot[j][j] + rot[k][k]) - rot[i][i]) - 1.0;
+ v[i] = nc2;
+ w = (rot[j][k] - rot[k][j]);
+ v[j] = -(rot[i][j] + rot[j][i]);
+ v[k] = -(rot[i][k] + rot[k][i]);
+
+ // We now have the correct result with the wrong magnitude, so normalize it:
+ float s = sqrt(x*x + y*y + z*z + w*w);
+ if (s > 0.00001f) {
+ s = 1.0f / s;
+ x *= s;
+ y *= s;
+ z *= s;
+ w *= s;
+ } else {
+ // The quaternion is nearly zero. Make it 0 0 0 1
+ x = 0.0f;
+ y = 0.0f;
+ z = 0.0f;
+ w = 1.0f;
+ }
+}
+
+
+void Quat::toAxisAngleRotation(
+ Vector3& axis,
+ double& angle) const {
+
+ // Decompose the quaternion into an angle and an axis.
+
+ axis = Vector3(x, y, z);
+ angle = 2 * acos(w);
+
+ float len = sqrt(1.0f - w * w);
+
+ if (fuzzyGt(abs(len), 0.0f)) {
+ axis /= len;
+ }
+
+ // Reduce the range of the angle.
+
+ if (angle < 0) {
+ angle = -angle;
+ axis = -axis;
+ }
+
+ while (angle > twoPi()) {
+ angle -= twoPi();
+ }
+
+ if (abs(angle) > pi()) {
+ angle -= twoPi();
+ }
+
+ // Make the angle positive.
+
+ if (angle < 0.0f) {
+ angle = -angle;
+ axis = -axis;
+ }
+}
+
+
+Matrix3 Quat::toRotationMatrix() const {
+ Matrix3 out = Matrix3::zero();
+
+ toRotationMatrix(out);
+
+ return out;
+}
+
+
+void Quat::toRotationMatrix(
+ Matrix3& rot) const {
+
+ rot = Matrix3(*this);
+}
+
+
+Quat Quat::slerp(
+ const Quat& _quat1,
+ float alpha,
+ float threshold) const {
+
+ // From: Game Physics -- David Eberly pg 538-540
+ // Modified to include lerp for small angles, which
+ // is a common practice.
+
+ // See also:
+ // http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/index.html
+
+ const Quat& quat0 = *this;
+ Quat quat1 = _quat1;
+
+ // angle between quaternion rotations
+ float phi;
+ float cosphi = quat0.dot(quat1);
+
+
+ if (cosphi < 0) {
+ // Change the sign and fix the dot product; we need to
+ // loop the other way to get the shortest path
+ quat1 = -quat1;
+ cosphi = -cosphi;
+ }
+
+ // Using G3D::aCos will clamp the angle to 0 and pi
+ phi = static_cast<float>(G3D::aCos(cosphi));
+
+ if (phi >= threshold) {
+ // For large angles, slerp
+ float scale0, scale1;
+
+ scale0 = sin((1.0f - alpha) * phi);
+ scale1 = sin(alpha * phi);
+
+ return ( (quat0 * scale0) + (quat1 * scale1) ) / sin(phi);
+ } else {
+ // For small angles, linear interpolate
+ return quat0.nlerp(quat1, alpha);
+ }
+}
+
+
+Quat Quat::nlerp(
+ const Quat& quat1,
+ float alpha) const {
+
+ Quat result = (*this) * (1.0f - alpha) + quat1 * alpha;
+ return result / result.magnitude();
+}
+
+
+Quat Quat::operator*(const Quat& other) const {
+
+ // Following Watt & Watt, page 360
+ const Vector3& v1 = imag();
+ const Vector3& v2 = other.imag();
+ float s1 = w;
+ float s2 = other.w;
+
+ return Quat(s1*v2 + s2*v1 + v1.cross(v2), s1*s2 - v1.dot(v2));
+}
+
+
+// From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III.
+Quat Quat::unitRandom() {
+ float x0 = uniformRandom();
+ float r1 = sqrtf(1 - x0),
+ r2 = sqrtf(x0);
+ float t1 = (float)G3D::twoPi() * uniformRandom();
+ float t2 = (float)G3D::twoPi() * uniformRandom();
+ float c1 = cosf(t1),
+ s1 = sinf(t1);
+ float c2 = cosf(t2),
+ s2 = sinf(t2);
+ return Quat(s1 * r1, c1 * r1, s2 * r2, c2 * r2);
+}
+
+
+void Quat::deserialize(class BinaryInput& b) {
+ x = b.readFloat32();
+ y = b.readFloat32();
+ z = b.readFloat32();
+ w = b.readFloat32();
+}
+
+
+void Quat::serialize(class BinaryOutput& b) const {
+ b.writeFloat32(x);
+ b.writeFloat32(y);
+ b.writeFloat32(z);
+ b.writeFloat32(w);
+}
+
+
+// 2-char swizzles
+
+Vector2 Quat::xx() const { return Vector2 (x, x); }
+Vector2 Quat::yx() const { return Vector2 (y, x); }
+Vector2 Quat::zx() const { return Vector2 (z, x); }
+Vector2 Quat::wx() const { return Vector2 (w, x); }
+Vector2 Quat::xy() const { return Vector2 (x, y); }
+Vector2 Quat::yy() const { return Vector2 (y, y); }
+Vector2 Quat::zy() const { return Vector2 (z, y); }
+Vector2 Quat::wy() const { return Vector2 (w, y); }
+Vector2 Quat::xz() const { return Vector2 (x, z); }
+Vector2 Quat::yz() const { return Vector2 (y, z); }
+Vector2 Quat::zz() const { return Vector2 (z, z); }
+Vector2 Quat::wz() const { return Vector2 (w, z); }
+Vector2 Quat::xw() const { return Vector2 (x, w); }
+Vector2 Quat::yw() const { return Vector2 (y, w); }
+Vector2 Quat::zw() const { return Vector2 (z, w); }
+Vector2 Quat::ww() const { return Vector2 (w, w); }
+
+// 3-char swizzles
+
+Vector3 Quat::xxx() const { return Vector3 (x, x, x); }
+Vector3 Quat::yxx() const { return Vector3 (y, x, x); }
+Vector3 Quat::zxx() const { return Vector3 (z, x, x); }
+Vector3 Quat::wxx() const { return Vector3 (w, x, x); }
+Vector3 Quat::xyx() const { return Vector3 (x, y, x); }
+Vector3 Quat::yyx() const { return Vector3 (y, y, x); }
+Vector3 Quat::zyx() const { return Vector3 (z, y, x); }
+Vector3 Quat::wyx() const { return Vector3 (w, y, x); }
+Vector3 Quat::xzx() const { return Vector3 (x, z, x); }
+Vector3 Quat::yzx() const { return Vector3 (y, z, x); }
+Vector3 Quat::zzx() const { return Vector3 (z, z, x); }
+Vector3 Quat::wzx() const { return Vector3 (w, z, x); }
+Vector3 Quat::xwx() const { return Vector3 (x, w, x); }
+Vector3 Quat::ywx() const { return Vector3 (y, w, x); }
+Vector3 Quat::zwx() const { return Vector3 (z, w, x); }
+Vector3 Quat::wwx() const { return Vector3 (w, w, x); }
+Vector3 Quat::xxy() const { return Vector3 (x, x, y); }
+Vector3 Quat::yxy() const { return Vector3 (y, x, y); }
+Vector3 Quat::zxy() const { return Vector3 (z, x, y); }
+Vector3 Quat::wxy() const { return Vector3 (w, x, y); }
+Vector3 Quat::xyy() const { return Vector3 (x, y, y); }
+Vector3 Quat::yyy() const { return Vector3 (y, y, y); }
+Vector3 Quat::zyy() const { return Vector3 (z, y, y); }
+Vector3 Quat::wyy() const { return Vector3 (w, y, y); }
+Vector3 Quat::xzy() const { return Vector3 (x, z, y); }
+Vector3 Quat::yzy() const { return Vector3 (y, z, y); }
+Vector3 Quat::zzy() const { return Vector3 (z, z, y); }
+Vector3 Quat::wzy() const { return Vector3 (w, z, y); }
+Vector3 Quat::xwy() const { return Vector3 (x, w, y); }
+Vector3 Quat::ywy() const { return Vector3 (y, w, y); }
+Vector3 Quat::zwy() const { return Vector3 (z, w, y); }
+Vector3 Quat::wwy() const { return Vector3 (w, w, y); }
+Vector3 Quat::xxz() const { return Vector3 (x, x, z); }
+Vector3 Quat::yxz() const { return Vector3 (y, x, z); }
+Vector3 Quat::zxz() const { return Vector3 (z, x, z); }
+Vector3 Quat::wxz() const { return Vector3 (w, x, z); }
+Vector3 Quat::xyz() const { return Vector3 (x, y, z); }
+Vector3 Quat::yyz() const { return Vector3 (y, y, z); }
+Vector3 Quat::zyz() const { return Vector3 (z, y, z); }
+Vector3 Quat::wyz() const { return Vector3 (w, y, z); }
+Vector3 Quat::xzz() const { return Vector3 (x, z, z); }
+Vector3 Quat::yzz() const { return Vector3 (y, z, z); }
+Vector3 Quat::zzz() const { return Vector3 (z, z, z); }
+Vector3 Quat::wzz() const { return Vector3 (w, z, z); }
+Vector3 Quat::xwz() const { return Vector3 (x, w, z); }
+Vector3 Quat::ywz() const { return Vector3 (y, w, z); }
+Vector3 Quat::zwz() const { return Vector3 (z, w, z); }
+Vector3 Quat::wwz() const { return Vector3 (w, w, z); }
+Vector3 Quat::xxw() const { return Vector3 (x, x, w); }
+Vector3 Quat::yxw() const { return Vector3 (y, x, w); }
+Vector3 Quat::zxw() const { return Vector3 (z, x, w); }
+Vector3 Quat::wxw() const { return Vector3 (w, x, w); }
+Vector3 Quat::xyw() const { return Vector3 (x, y, w); }
+Vector3 Quat::yyw() const { return Vector3 (y, y, w); }
+Vector3 Quat::zyw() const { return Vector3 (z, y, w); }
+Vector3 Quat::wyw() const { return Vector3 (w, y, w); }
+Vector3 Quat::xzw() const { return Vector3 (x, z, w); }
+Vector3 Quat::yzw() const { return Vector3 (y, z, w); }
+Vector3 Quat::zzw() const { return Vector3 (z, z, w); }
+Vector3 Quat::wzw() const { return Vector3 (w, z, w); }
+Vector3 Quat::xww() const { return Vector3 (x, w, w); }
+Vector3 Quat::yww() const { return Vector3 (y, w, w); }
+Vector3 Quat::zww() const { return Vector3 (z, w, w); }
+Vector3 Quat::www() const { return Vector3 (w, w, w); }
+
+// 4-char swizzles
+
+Vector4 Quat::xxxx() const { return Vector4 (x, x, x, x); }
+Vector4 Quat::yxxx() const { return Vector4 (y, x, x, x); }
+Vector4 Quat::zxxx() const { return Vector4 (z, x, x, x); }
+Vector4 Quat::wxxx() const { return Vector4 (w, x, x, x); }
+Vector4 Quat::xyxx() const { return Vector4 (x, y, x, x); }
+Vector4 Quat::yyxx() const { return Vector4 (y, y, x, x); }
+Vector4 Quat::zyxx() const { return Vector4 (z, y, x, x); }
+Vector4 Quat::wyxx() const { return Vector4 (w, y, x, x); }
+Vector4 Quat::xzxx() const { return Vector4 (x, z, x, x); }
+Vector4 Quat::yzxx() const { return Vector4 (y, z, x, x); }
+Vector4 Quat::zzxx() const { return Vector4 (z, z, x, x); }
+Vector4 Quat::wzxx() const { return Vector4 (w, z, x, x); }
+Vector4 Quat::xwxx() const { return Vector4 (x, w, x, x); }
+Vector4 Quat::ywxx() const { return Vector4 (y, w, x, x); }
+Vector4 Quat::zwxx() const { return Vector4 (z, w, x, x); }
+Vector4 Quat::wwxx() const { return Vector4 (w, w, x, x); }
+Vector4 Quat::xxyx() const { return Vector4 (x, x, y, x); }
+Vector4 Quat::yxyx() const { return Vector4 (y, x, y, x); }
+Vector4 Quat::zxyx() const { return Vector4 (z, x, y, x); }
+Vector4 Quat::wxyx() const { return Vector4 (w, x, y, x); }
+Vector4 Quat::xyyx() const { return Vector4 (x, y, y, x); }
+Vector4 Quat::yyyx() const { return Vector4 (y, y, y, x); }
+Vector4 Quat::zyyx() const { return Vector4 (z, y, y, x); }
+Vector4 Quat::wyyx() const { return Vector4 (w, y, y, x); }
+Vector4 Quat::xzyx() const { return Vector4 (x, z, y, x); }
+Vector4 Quat::yzyx() const { return Vector4 (y, z, y, x); }
+Vector4 Quat::zzyx() const { return Vector4 (z, z, y, x); }
+Vector4 Quat::wzyx() const { return Vector4 (w, z, y, x); }
+Vector4 Quat::xwyx() const { return Vector4 (x, w, y, x); }
+Vector4 Quat::ywyx() const { return Vector4 (y, w, y, x); }
+Vector4 Quat::zwyx() const { return Vector4 (z, w, y, x); }
+Vector4 Quat::wwyx() const { return Vector4 (w, w, y, x); }
+Vector4 Quat::xxzx() const { return Vector4 (x, x, z, x); }
+Vector4 Quat::yxzx() const { return Vector4 (y, x, z, x); }
+Vector4 Quat::zxzx() const { return Vector4 (z, x, z, x); }
+Vector4 Quat::wxzx() const { return Vector4 (w, x, z, x); }
+Vector4 Quat::xyzx() const { return Vector4 (x, y, z, x); }
+Vector4 Quat::yyzx() const { return Vector4 (y, y, z, x); }
+Vector4 Quat::zyzx() const { return Vector4 (z, y, z, x); }
+Vector4 Quat::wyzx() const { return Vector4 (w, y, z, x); }
+Vector4 Quat::xzzx() const { return Vector4 (x, z, z, x); }
+Vector4 Quat::yzzx() const { return Vector4 (y, z, z, x); }
+Vector4 Quat::zzzx() const { return Vector4 (z, z, z, x); }
+Vector4 Quat::wzzx() const { return Vector4 (w, z, z, x); }
+Vector4 Quat::xwzx() const { return Vector4 (x, w, z, x); }
+Vector4 Quat::ywzx() const { return Vector4 (y, w, z, x); }
+Vector4 Quat::zwzx() const { return Vector4 (z, w, z, x); }
+Vector4 Quat::wwzx() const { return Vector4 (w, w, z, x); }
+Vector4 Quat::xxwx() const { return Vector4 (x, x, w, x); }
+Vector4 Quat::yxwx() const { return Vector4 (y, x, w, x); }
+Vector4 Quat::zxwx() const { return Vector4 (z, x, w, x); }
+Vector4 Quat::wxwx() const { return Vector4 (w, x, w, x); }
+Vector4 Quat::xywx() const { return Vector4 (x, y, w, x); }
+Vector4 Quat::yywx() const { return Vector4 (y, y, w, x); }
+Vector4 Quat::zywx() const { return Vector4 (z, y, w, x); }
+Vector4 Quat::wywx() const { return Vector4 (w, y, w, x); }
+Vector4 Quat::xzwx() const { return Vector4 (x, z, w, x); }
+Vector4 Quat::yzwx() const { return Vector4 (y, z, w, x); }
+Vector4 Quat::zzwx() const { return Vector4 (z, z, w, x); }
+Vector4 Quat::wzwx() const { return Vector4 (w, z, w, x); }
+Vector4 Quat::xwwx() const { return Vector4 (x, w, w, x); }
+Vector4 Quat::ywwx() const { return Vector4 (y, w, w, x); }
+Vector4 Quat::zwwx() const { return Vector4 (z, w, w, x); }
+Vector4 Quat::wwwx() const { return Vector4 (w, w, w, x); }
+Vector4 Quat::xxxy() const { return Vector4 (x, x, x, y); }
+Vector4 Quat::yxxy() const { return Vector4 (y, x, x, y); }
+Vector4 Quat::zxxy() const { return Vector4 (z, x, x, y); }
+Vector4 Quat::wxxy() const { return Vector4 (w, x, x, y); }
+Vector4 Quat::xyxy() const { return Vector4 (x, y, x, y); }
+Vector4 Quat::yyxy() const { return Vector4 (y, y, x, y); }
+Vector4 Quat::zyxy() const { return Vector4 (z, y, x, y); }
+Vector4 Quat::wyxy() const { return Vector4 (w, y, x, y); }
+Vector4 Quat::xzxy() const { return Vector4 (x, z, x, y); }
+Vector4 Quat::yzxy() const { return Vector4 (y, z, x, y); }
+Vector4 Quat::zzxy() const { return Vector4 (z, z, x, y); }
+Vector4 Quat::wzxy() const { return Vector4 (w, z, x, y); }
+Vector4 Quat::xwxy() const { return Vector4 (x, w, x, y); }
+Vector4 Quat::ywxy() const { return Vector4 (y, w, x, y); }
+Vector4 Quat::zwxy() const { return Vector4 (z, w, x, y); }
+Vector4 Quat::wwxy() const { return Vector4 (w, w, x, y); }
+Vector4 Quat::xxyy() const { return Vector4 (x, x, y, y); }
+Vector4 Quat::yxyy() const { return Vector4 (y, x, y, y); }
+Vector4 Quat::zxyy() const { return Vector4 (z, x, y, y); }
+Vector4 Quat::wxyy() const { return Vector4 (w, x, y, y); }
+Vector4 Quat::xyyy() const { return Vector4 (x, y, y, y); }
+Vector4 Quat::yyyy() const { return Vector4 (y, y, y, y); }
+Vector4 Quat::zyyy() const { return Vector4 (z, y, y, y); }
+Vector4 Quat::wyyy() const { return Vector4 (w, y, y, y); }
+Vector4 Quat::xzyy() const { return Vector4 (x, z, y, y); }
+Vector4 Quat::yzyy() const { return Vector4 (y, z, y, y); }
+Vector4 Quat::zzyy() const { return Vector4 (z, z, y, y); }
+Vector4 Quat::wzyy() const { return Vector4 (w, z, y, y); }
+Vector4 Quat::xwyy() const { return Vector4 (x, w, y, y); }
+Vector4 Quat::ywyy() const { return Vector4 (y, w, y, y); }
+Vector4 Quat::zwyy() const { return Vector4 (z, w, y, y); }
+Vector4 Quat::wwyy() const { return Vector4 (w, w, y, y); }
+Vector4 Quat::xxzy() const { return Vector4 (x, x, z, y); }
+Vector4 Quat::yxzy() const { return Vector4 (y, x, z, y); }
+Vector4 Quat::zxzy() const { return Vector4 (z, x, z, y); }
+Vector4 Quat::wxzy() const { return Vector4 (w, x, z, y); }
+Vector4 Quat::xyzy() const { return Vector4 (x, y, z, y); }
+Vector4 Quat::yyzy() const { return Vector4 (y, y, z, y); }
+Vector4 Quat::zyzy() const { return Vector4 (z, y, z, y); }
+Vector4 Quat::wyzy() const { return Vector4 (w, y, z, y); }
+Vector4 Quat::xzzy() const { return Vector4 (x, z, z, y); }
+Vector4 Quat::yzzy() const { return Vector4 (y, z, z, y); }
+Vector4 Quat::zzzy() const { return Vector4 (z, z, z, y); }
+Vector4 Quat::wzzy() const { return Vector4 (w, z, z, y); }
+Vector4 Quat::xwzy() const { return Vector4 (x, w, z, y); }
+Vector4 Quat::ywzy() const { return Vector4 (y, w, z, y); }
+Vector4 Quat::zwzy() const { return Vector4 (z, w, z, y); }
+Vector4 Quat::wwzy() const { return Vector4 (w, w, z, y); }
+Vector4 Quat::xxwy() const { return Vector4 (x, x, w, y); }
+Vector4 Quat::yxwy() const { return Vector4 (y, x, w, y); }
+Vector4 Quat::zxwy() const { return Vector4 (z, x, w, y); }
+Vector4 Quat::wxwy() const { return Vector4 (w, x, w, y); }
+Vector4 Quat::xywy() const { return Vector4 (x, y, w, y); }
+Vector4 Quat::yywy() const { return Vector4 (y, y, w, y); }
+Vector4 Quat::zywy() const { return Vector4 (z, y, w, y); }
+Vector4 Quat::wywy() const { return Vector4 (w, y, w, y); }
+Vector4 Quat::xzwy() const { return Vector4 (x, z, w, y); }
+Vector4 Quat::yzwy() const { return Vector4 (y, z, w, y); }
+Vector4 Quat::zzwy() const { return Vector4 (z, z, w, y); }
+Vector4 Quat::wzwy() const { return Vector4 (w, z, w, y); }
+Vector4 Quat::xwwy() const { return Vector4 (x, w, w, y); }
+Vector4 Quat::ywwy() const { return Vector4 (y, w, w, y); }
+Vector4 Quat::zwwy() const { return Vector4 (z, w, w, y); }
+Vector4 Quat::wwwy() const { return Vector4 (w, w, w, y); }
+Vector4 Quat::xxxz() const { return Vector4 (x, x, x, z); }
+Vector4 Quat::yxxz() const { return Vector4 (y, x, x, z); }
+Vector4 Quat::zxxz() const { return Vector4 (z, x, x, z); }
+Vector4 Quat::wxxz() const { return Vector4 (w, x, x, z); }
+Vector4 Quat::xyxz() const { return Vector4 (x, y, x, z); }
+Vector4 Quat::yyxz() const { return Vector4 (y, y, x, z); }
+Vector4 Quat::zyxz() const { return Vector4 (z, y, x, z); }
+Vector4 Quat::wyxz() const { return Vector4 (w, y, x, z); }
+Vector4 Quat::xzxz() const { return Vector4 (x, z, x, z); }
+Vector4 Quat::yzxz() const { return Vector4 (y, z, x, z); }
+Vector4 Quat::zzxz() const { return Vector4 (z, z, x, z); }
+Vector4 Quat::wzxz() const { return Vector4 (w, z, x, z); }
+Vector4 Quat::xwxz() const { return Vector4 (x, w, x, z); }
+Vector4 Quat::ywxz() const { return Vector4 (y, w, x, z); }
+Vector4 Quat::zwxz() const { return Vector4 (z, w, x, z); }
+Vector4 Quat::wwxz() const { return Vector4 (w, w, x, z); }
+Vector4 Quat::xxyz() const { return Vector4 (x, x, y, z); }
+Vector4 Quat::yxyz() const { return Vector4 (y, x, y, z); }
+Vector4 Quat::zxyz() const { return Vector4 (z, x, y, z); }
+Vector4 Quat::wxyz() const { return Vector4 (w, x, y, z); }
+Vector4 Quat::xyyz() const { return Vector4 (x, y, y, z); }
+Vector4 Quat::yyyz() const { return Vector4 (y, y, y, z); }
+Vector4 Quat::zyyz() const { return Vector4 (z, y, y, z); }
+Vector4 Quat::wyyz() const { return Vector4 (w, y, y, z); }
+Vector4 Quat::xzyz() const { return Vector4 (x, z, y, z); }
+Vector4 Quat::yzyz() const { return Vector4 (y, z, y, z); }
+Vector4 Quat::zzyz() const { return Vector4 (z, z, y, z); }
+Vector4 Quat::wzyz() const { return Vector4 (w, z, y, z); }
+Vector4 Quat::xwyz() const { return Vector4 (x, w, y, z); }
+Vector4 Quat::ywyz() const { return Vector4 (y, w, y, z); }
+Vector4 Quat::zwyz() const { return Vector4 (z, w, y, z); }
+Vector4 Quat::wwyz() const { return Vector4 (w, w, y, z); }
+Vector4 Quat::xxzz() const { return Vector4 (x, x, z, z); }
+Vector4 Quat::yxzz() const { return Vector4 (y, x, z, z); }
+Vector4 Quat::zxzz() const { return Vector4 (z, x, z, z); }
+Vector4 Quat::wxzz() const { return Vector4 (w, x, z, z); }
+Vector4 Quat::xyzz() const { return Vector4 (x, y, z, z); }
+Vector4 Quat::yyzz() const { return Vector4 (y, y, z, z); }
+Vector4 Quat::zyzz() const { return Vector4 (z, y, z, z); }
+Vector4 Quat::wyzz() const { return Vector4 (w, y, z, z); }
+Vector4 Quat::xzzz() const { return Vector4 (x, z, z, z); }
+Vector4 Quat::yzzz() const { return Vector4 (y, z, z, z); }
+Vector4 Quat::zzzz() const { return Vector4 (z, z, z, z); }
+Vector4 Quat::wzzz() const { return Vector4 (w, z, z, z); }
+Vector4 Quat::xwzz() const { return Vector4 (x, w, z, z); }
+Vector4 Quat::ywzz() const { return Vector4 (y, w, z, z); }
+Vector4 Quat::zwzz() const { return Vector4 (z, w, z, z); }
+Vector4 Quat::wwzz() const { return Vector4 (w, w, z, z); }
+Vector4 Quat::xxwz() const { return Vector4 (x, x, w, z); }
+Vector4 Quat::yxwz() const { return Vector4 (y, x, w, z); }
+Vector4 Quat::zxwz() const { return Vector4 (z, x, w, z); }
+Vector4 Quat::wxwz() const { return Vector4 (w, x, w, z); }
+Vector4 Quat::xywz() const { return Vector4 (x, y, w, z); }
+Vector4 Quat::yywz() const { return Vector4 (y, y, w, z); }
+Vector4 Quat::zywz() const { return Vector4 (z, y, w, z); }
+Vector4 Quat::wywz() const { return Vector4 (w, y, w, z); }
+Vector4 Quat::xzwz() const { return Vector4 (x, z, w, z); }
+Vector4 Quat::yzwz() const { return Vector4 (y, z, w, z); }
+Vector4 Quat::zzwz() const { return Vector4 (z, z, w, z); }
+Vector4 Quat::wzwz() const { return Vector4 (w, z, w, z); }
+Vector4 Quat::xwwz() const { return Vector4 (x, w, w, z); }
+Vector4 Quat::ywwz() const { return Vector4 (y, w, w, z); }
+Vector4 Quat::zwwz() const { return Vector4 (z, w, w, z); }
+Vector4 Quat::wwwz() const { return Vector4 (w, w, w, z); }
+Vector4 Quat::xxxw() const { return Vector4 (x, x, x, w); }
+Vector4 Quat::yxxw() const { return Vector4 (y, x, x, w); }
+Vector4 Quat::zxxw() const { return Vector4 (z, x, x, w); }
+Vector4 Quat::wxxw() const { return Vector4 (w, x, x, w); }
+Vector4 Quat::xyxw() const { return Vector4 (x, y, x, w); }
+Vector4 Quat::yyxw() const { return Vector4 (y, y, x, w); }
+Vector4 Quat::zyxw() const { return Vector4 (z, y, x, w); }
+Vector4 Quat::wyxw() const { return Vector4 (w, y, x, w); }
+Vector4 Quat::xzxw() const { return Vector4 (x, z, x, w); }
+Vector4 Quat::yzxw() const { return Vector4 (y, z, x, w); }
+Vector4 Quat::zzxw() const { return Vector4 (z, z, x, w); }
+Vector4 Quat::wzxw() const { return Vector4 (w, z, x, w); }
+Vector4 Quat::xwxw() const { return Vector4 (x, w, x, w); }
+Vector4 Quat::ywxw() const { return Vector4 (y, w, x, w); }
+Vector4 Quat::zwxw() const { return Vector4 (z, w, x, w); }
+Vector4 Quat::wwxw() const { return Vector4 (w, w, x, w); }
+Vector4 Quat::xxyw() const { return Vector4 (x, x, y, w); }
+Vector4 Quat::yxyw() const { return Vector4 (y, x, y, w); }
+Vector4 Quat::zxyw() const { return Vector4 (z, x, y, w); }
+Vector4 Quat::wxyw() const { return Vector4 (w, x, y, w); }
+Vector4 Quat::xyyw() const { return Vector4 (x, y, y, w); }
+Vector4 Quat::yyyw() const { return Vector4 (y, y, y, w); }
+Vector4 Quat::zyyw() const { return Vector4 (z, y, y, w); }
+Vector4 Quat::wyyw() const { return Vector4 (w, y, y, w); }
+Vector4 Quat::xzyw() const { return Vector4 (x, z, y, w); }
+Vector4 Quat::yzyw() const { return Vector4 (y, z, y, w); }
+Vector4 Quat::zzyw() const { return Vector4 (z, z, y, w); }
+Vector4 Quat::wzyw() const { return Vector4 (w, z, y, w); }
+Vector4 Quat::xwyw() const { return Vector4 (x, w, y, w); }
+Vector4 Quat::ywyw() const { return Vector4 (y, w, y, w); }
+Vector4 Quat::zwyw() const { return Vector4 (z, w, y, w); }
+Vector4 Quat::wwyw() const { return Vector4 (w, w, y, w); }
+Vector4 Quat::xxzw() const { return Vector4 (x, x, z, w); }
+Vector4 Quat::yxzw() const { return Vector4 (y, x, z, w); }
+Vector4 Quat::zxzw() const { return Vector4 (z, x, z, w); }
+Vector4 Quat::wxzw() const { return Vector4 (w, x, z, w); }
+Vector4 Quat::xyzw() const { return Vector4 (x, y, z, w); }
+Vector4 Quat::yyzw() const { return Vector4 (y, y, z, w); }
+Vector4 Quat::zyzw() const { return Vector4 (z, y, z, w); }
+Vector4 Quat::wyzw() const { return Vector4 (w, y, z, w); }
+Vector4 Quat::xzzw() const { return Vector4 (x, z, z, w); }
+Vector4 Quat::yzzw() const { return Vector4 (y, z, z, w); }
+Vector4 Quat::zzzw() const { return Vector4 (z, z, z, w); }
+Vector4 Quat::wzzw() const { return Vector4 (w, z, z, w); }
+Vector4 Quat::xwzw() const { return Vector4 (x, w, z, w); }
+Vector4 Quat::ywzw() const { return Vector4 (y, w, z, w); }
+Vector4 Quat::zwzw() const { return Vector4 (z, w, z, w); }
+Vector4 Quat::wwzw() const { return Vector4 (w, w, z, w); }
+Vector4 Quat::xxww() const { return Vector4 (x, x, w, w); }
+Vector4 Quat::yxww() const { return Vector4 (y, x, w, w); }
+Vector4 Quat::zxww() const { return Vector4 (z, x, w, w); }
+Vector4 Quat::wxww() const { return Vector4 (w, x, w, w); }
+Vector4 Quat::xyww() const { return Vector4 (x, y, w, w); }
+Vector4 Quat::yyww() const { return Vector4 (y, y, w, w); }
+Vector4 Quat::zyww() const { return Vector4 (z, y, w, w); }
+Vector4 Quat::wyww() const { return Vector4 (w, y, w, w); }
+Vector4 Quat::xzww() const { return Vector4 (x, z, w, w); }
+Vector4 Quat::yzww() const { return Vector4 (y, z, w, w); }
+Vector4 Quat::zzww() const { return Vector4 (z, z, w, w); }
+Vector4 Quat::wzww() const { return Vector4 (w, z, w, w); }
+Vector4 Quat::xwww() const { return Vector4 (x, w, w, w); }
+Vector4 Quat::ywww() const { return Vector4 (y, w, w, w); }
+Vector4 Quat::zwww() const { return Vector4 (z, w, w, w); }
+Vector4 Quat::wwww() const { return Vector4 (w, w, w, w); }
+}
+
diff --git a/dep/src/g3dlite/Random.cpp b/dep/src/g3dlite/Random.cpp
new file mode 100644
index 00000000000..2dda744a1ac
--- /dev/null
+++ b/dep/src/g3dlite/Random.cpp
@@ -0,0 +1,212 @@
+/**
+ @file Random.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-01-02
+ @edited 2009-03-29
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#include "G3D/Random.h"
+
+namespace G3D {
+
+Random& Random::common() {
+ static Random r;
+ return r;
+}
+
+Random::Random(void* x) : state(NULL), m_threadsafe(false) {
+ (void)x;
+}
+
+
+Random::Random(uint32 seed, bool threadsafe) : m_threadsafe(threadsafe) {
+ const uint32 X = 1812433253UL;
+
+ state = new uint32[N];
+ state[0] = seed;
+ for (index = 1; index < (int)N; ++index) {
+ state[index] = X * (state[index - 1] ^ (state[index - 1] >> 30)) + index;
+ }
+}
+
+
+Random::~Random() {
+ delete[] state;
+ state = NULL;
+}
+
+
+uint32 Random::bits() {
+ // See http://en.wikipedia.org/wiki/Mersenne_twister
+
+ // Make a local copy of the index variable to ensure that it
+ // is not out of bounds
+ int localIndex = index;
+
+ // Automatically checks for index < 0 if corrupted
+ // by unsynchronized threads.
+ if ((unsigned int)localIndex >= (unsigned int)N) {
+ generate();
+ localIndex = 0;
+ }
+ // Increment the global index. It may go out of bounds on
+ // multiple threads, but the above check ensures that the
+ // array index actually used never goes out of bounds.
+ // It doesn't matter if we grab the same array index twice
+ // on two threads, since the distribution of random numbers
+ // will still be uniform.
+ ++index;
+ // Return the next random in the sequence
+ uint32 r = state[localIndex];
+
+ // Temper the result
+ r ^= r >> U;
+ r ^= (r << S) & B;
+ r ^= (r << T) & C;
+ r ^= r >> L;
+
+ return r;
+}
+
+
+/** Generate the next N ints, and store them for readback later */
+void Random::generate() {
+ // Lower R bits
+ static const uint32 LOWER_MASK = (1LU << R) - 1;
+
+ // Upper (32 - R) bits
+ static const uint32 UPPER_MASK = 0xFFFFFFFF << R;
+ static const uint32 mag01[2] = {0UL, (uint32)A};
+
+ if (m_threadsafe) {
+ bool contention = ! lock.lock();
+ if (contention) {
+ // Another thread just generated a set of numbers; no need for
+ // this thread to do it too
+ lock.unlock();
+ return;
+ }
+ }
+
+ // First N - M
+ for (unsigned int i = 0; i < N - M; ++i) {
+ uint32 x = (state[i] & UPPER_MASK) | (state[i + 1] & LOWER_MASK);
+ state[i] = state[i + M] ^ (x >> 1) ^ mag01[x & 1];
+ }
+
+ // Rest
+ for (unsigned int i = N - M + 1; i < N - 1; ++i) {
+ uint32 x = (state[i] & UPPER_MASK) | (state[i + 1] & LOWER_MASK);
+ state[i] = state[i + (M - N)] ^ (x >> 1) ^ mag01[x & 1];
+ }
+
+ uint32 y = (state[N - 1] & UPPER_MASK) | (state[0] & LOWER_MASK);
+ state[N - 1] = state[M - 1] ^ (y >> 1) ^ mag01[y & 1];
+ index = 0;
+
+ if (m_threadsafe) {
+ lock.unlock();
+ }
+}
+
+
+int Random::integer(int low, int high) {
+ int r = iFloor(low + (high - low + 1) * (double)bits() / 0xFFFFFFFFUL);
+
+ // There is a *very small* chance of generating
+ // a number larger than high.
+ if (r > high) {
+ return high;
+ } else {
+ return r;
+ }
+}
+
+
+float Random::gaussian(float mean, float stdev) {
+
+ // Using Box-Mueller method from http://www.taygeta.com/random/gaussian.html
+ // Modified to specify standard deviation and mean of distribution
+ float w, x1, x2;
+
+ // Loop until w is less than 1 so that log(w) is negative
+ do {
+ x1 = uniform(-1.0, 1.0);
+ x2 = uniform(-1.0, 1.0);
+
+ w = float(square(x1) + square(x2));
+ } while (w > 1.0f);
+
+ // Transform to gassian distribution
+ // Multiply by sigma (stdev ^ 2) and add mean.
+ return x2 * (float)square(stdev) * sqrtf((-2.0f * logf(w) ) / w) + mean;
+}
+
+
+void Random::cosHemi(float& x, float& y, float& z) {
+ const float e1 = uniform();
+ const float e2 = uniform();
+
+ // Jensen's method
+ const float sin_theta = sqrtf(1.0f - e1);
+ const float cos_theta = sqrtf(e1);
+ const float phi = 6.28318531f * e2;
+
+ x = cos(phi) * sin_theta;
+ y = sin(phi) * sin_theta;
+ z = cos_theta;
+
+ // We could also use Malley's method (pbrt p.657), since they are the same cost:
+ //
+ // r = sqrt(e1);
+ // t = 2*pi*e2;
+ // x = cos(t)*r;
+ // y = sin(t)*r;
+ // z = sqrt(1.0 - x*x + y*y);
+}
+
+
+void Random::cosPowHemi(const float k, float& x, float& y, float& z) {
+ const float e1 = uniform();
+ const float e2 = uniform();
+
+ const float cos_theta = pow(e1, 1.0f / (k + 1.0f));
+ const float sin_theta = sqrtf(1.0f - square(cos_theta));
+ const float phi = 6.28318531f * e2;
+
+ x = cos(phi) * sin_theta;
+ y = sin(phi) * sin_theta;
+ z = cos_theta;
+}
+
+
+void Random::hemi(float& x, float& y, float& z) {
+ sphere(x, y, z);
+ z = fabsf(z);
+}
+
+
+void Random::sphere(float& x, float& y, float& z) {
+ // Squared magnitude
+ float m2;
+
+ // Rejection sample
+ do {
+ x = uniform() * 2.0f - 1.0f,
+ y = uniform() * 2.0f - 1.0f,
+ z = uniform() * 2.0f - 1.0f;
+ m2 = x*x + y*y + z*z;
+ } while (m2 >= 1.0f);
+
+ // Divide by magnitude to produce a unit vector
+ float s = rsqrt(m2);
+ x *= s;
+ y *= s;
+ z *= s;
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/Ray.cpp b/dep/src/g3dlite/Ray.cpp
new file mode 100644
index 00000000000..0436ef0b323
--- /dev/null
+++ b/dep/src/g3dlite/Ray.cpp
@@ -0,0 +1,218 @@
+/**
+ @file Ray.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2002-07-12
+ @edited 2004-03-19
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Ray.h"
+#include "G3D/Plane.h"
+#include "G3D/Sphere.h"
+#include "G3D/CollisionDetection.h"
+
+namespace G3D {
+
+void Ray::set(const Vector3& origin, const Vector3& direction) {
+ m_origin = origin;
+ m_direction = direction;
+ debugAssert(direction.isUnit());
+
+ m_invDirection = Vector3::one() / direction;
+
+ // ray slope
+ ibyj = m_direction.x * m_invDirection.y;
+ jbyi = m_direction.y * m_invDirection.x;
+ jbyk = m_direction.y * m_invDirection.z;
+ kbyj = m_direction.z * m_invDirection.y;
+ ibyk = m_direction.x * m_invDirection.z;
+ kbyi = m_direction.z * m_invDirection.x;
+
+ // precomputed terms
+ c_xy = m_origin.y - jbyi * m_origin.x;
+ c_xz = m_origin.z - kbyi * m_origin.x;
+ c_yx = m_origin.x - ibyj * m_origin.y;
+ c_yz = m_origin.z - kbyj * m_origin.y;
+ c_zx = m_origin.x - ibyk * m_origin.z;
+ c_zy = m_origin.y - jbyk * m_origin.z;
+
+ //ray slope classification
+ if (m_direction.x < 0) {
+ if (m_direction.y < 0) {
+ if (m_direction.z < 0) {
+ classification = MMM;
+ } else if (m_direction.z > 0) {
+ classification = MMP;
+ } else { //(m_direction.z >= 0)
+ classification = MMO;
+ }
+ } else { //(m_direction.y >= 0)
+ if (m_direction.z < 0) {
+ if (m_direction.y == 0) {
+ classification = MOM;
+ } else {
+ classification = MPM;
+ }
+ } else { //(m_direction.z >= 0)
+ if ((m_direction.y == 0) && (m_direction.z == 0)) {
+ classification = MOO;
+ } else if (m_direction.z == 0) {
+ classification = MPO;
+ } else if (m_direction.y == 0) {
+ classification = MOP;
+ } else {
+ classification = MPP;
+ }
+ }
+ }
+ } else { //(m_direction.x >= 0)
+ if (m_direction.y < 0) {
+ if (m_direction.z < 0) {
+ if (m_direction.x == 0) {
+ classification = OMM;
+ } else {
+ classification = PMM;
+ }
+ } else { //(m_direction.z >= 0)
+ if ((m_direction.x == 0) && (m_direction.z == 0)) {
+ classification = OMO;
+ } else if (m_direction.z == 0) {
+ classification = PMO;
+ } else if (m_direction.x == 0) {
+ classification = OMP;
+ } else {
+ classification = PMP;
+ }
+ }
+ } else { //(m_direction.y >= 0)
+ if (m_direction.z < 0) {
+ if ((m_direction.x == 0) && (m_direction.y == 0)) {
+ classification = OOM;
+ } else if (m_direction.x == 0) {
+ classification = OPM;
+ } else if (m_direction.y == 0) {
+ classification = POM;
+ } else {
+ classification = PPM;
+ }
+ } else { //(m_direction.z > 0)
+ if (m_direction.x == 0) {
+ if (m_direction.y == 0) {
+ classification = OOP;
+ } else if (m_direction.z == 0) {
+ classification = OPO;
+ } else {
+ classification = OPP;
+ }
+ } else {
+ if ((m_direction.y == 0) && (m_direction.z == 0)) {
+ classification = POO;
+ } else if (m_direction.y == 0) {
+ classification = POP;
+ } else if (m_direction.z == 0) {
+ classification = PPO;
+ } else {
+ classification = PPP;
+ }
+ }
+ }
+ }
+ }
+}
+
+Ray::Ray(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Ray::serialize(class BinaryOutput& b) const {
+ m_origin.serialize(b);
+ m_direction.serialize(b);
+}
+
+
+void Ray::deserialize(class BinaryInput& b) {
+ m_origin.deserialize(b);
+ m_direction.deserialize(b);
+ set(m_origin, m_direction);
+}
+
+
+Ray Ray::refract(
+ const Vector3& newOrigin,
+ const Vector3& normal,
+ float iInside,
+ float iOutside) const {
+
+ Vector3 D = m_direction.refractionDirection(normal, iInside, iOutside);
+ return Ray(newOrigin + (m_direction + normal * (float)sign(m_direction.dot(normal))) * 0.001f, D);
+}
+
+
+Ray Ray::reflect(
+ const Vector3& newOrigin,
+ const Vector3& normal) const {
+
+ Vector3 D = m_direction.reflectionDirection(normal);
+ return Ray(newOrigin + (D + normal) * 0.001f, D);
+}
+
+
+Vector3 Ray::intersection(const Plane& plane) const {
+ float d;
+ Vector3 normal = plane.normal();
+ plane.getEquation(normal, d);
+ float rate = m_direction.dot(normal);
+
+ if (rate >= 0.0f) {
+ return Vector3::inf();
+ } else {
+ float t = -(d + m_origin.dot(normal)) / rate;
+ return m_origin + m_direction * t;
+ }
+}
+
+
+float Ray::intersectionTime(const class Sphere& sphere, bool solid) const {
+ Vector3 dummy;
+ return CollisionDetection::collisionTimeForMovingPointFixedSphere(
+ m_origin, m_direction, sphere, dummy, dummy, solid);
+}
+
+
+float Ray::intersectionTime(const class Plane& plane) const {
+ Vector3 dummy;
+ return CollisionDetection::collisionTimeForMovingPointFixedPlane(
+ m_origin, m_direction, plane, dummy);
+}
+
+
+float Ray::intersectionTime(const class Box& box) const {
+ Vector3 dummy;
+ float time = CollisionDetection::collisionTimeForMovingPointFixedBox(
+ m_origin, m_direction, box, dummy);
+
+ if ((time == finf()) && (box.contains(m_origin))) {
+ return 0.0f;
+ } else {
+ return time;
+ }
+}
+
+
+float Ray::intersectionTime(const class AABox& box) const {
+ Vector3 dummy;
+ bool inside;
+ float time = CollisionDetection::collisionTimeForMovingPointFixedAABox(
+ m_origin, m_direction, box, dummy, inside);
+
+ if ((time == finf()) && inside) {
+ return 0.0f;
+ } else {
+ return time;
+ }
+}
+
+}
diff --git a/dep/src/g3dlite/Rect2D.cpp b/dep/src/g3dlite/Rect2D.cpp
new file mode 100644
index 00000000000..e4148315a58
--- /dev/null
+++ b/dep/src/g3dlite/Rect2D.cpp
@@ -0,0 +1,41 @@
+/**
+ @file Rect2D.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-11-13
+ @created 2009-11-16
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Rect2D.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+/** \param any Must either Rect2D::xywh(#, #, #, #) or Rect2D::xyxy(#, #, #, #)*/
+Rect2D::Rect2D(const Any& any) {
+ any.verifyName("Rect2D");
+ any.verifyType(Any::ARRAY);
+ any.verifySize(4);
+ if (toUpper(any.name()) == "RECT2D::XYWH") {
+ *this = Rect2D::xywh(any[0], any[1], any[2], any[3]);
+ } else {
+ any.verifyName("Rect2D::xyxy");
+ *this = Rect2D::xyxy(any[0], any[1], any[2], any[3]);
+ }
+}
+
+
+/** Converts the Rect2D to an Any. */
+Rect2D::operator Any() const {
+ Any any(Any::ARRAY, "Rect2D::xywh");
+ any.append(x0(), y0(), width(), height());
+ return any;
+}
+
+}
diff --git a/dep/src/g3dlite/ReferenceCount.cpp b/dep/src/g3dlite/ReferenceCount.cpp
new file mode 100644
index 00000000000..2e1f117e0d9
--- /dev/null
+++ b/dep/src/g3dlite/ReferenceCount.cpp
@@ -0,0 +1,61 @@
+/**
+ @file ReferenceCount.cpp
+
+ Reference Counting Garbage Collector for C++
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Adapted and extended from Justin Miller's "RGC" class that appeared in BYTE magazine.
+ @cite See also http://www.jelovic.com/articles/cpp_without_memory_errors_slides.htm
+
+ @created 2001-10-23
+ @edited 2009-04-25
+*/
+#include "G3D/platform.h"
+#include "G3D/ReferenceCount.h"
+
+namespace G3D {
+
+ReferenceCountedObject::ReferenceCountedObject() :
+ ReferenceCountedObject_refCount(0),
+ ReferenceCountedObject_weakPointer(0) {
+
+ debugAssertM(isValidHeapPointer(this),
+ "Reference counted objects must be allocated on the heap.");
+}
+
+void ReferenceCountedObject::ReferenceCountedObject_zeroWeakPointers() {
+ // Tell all of my weak pointers that I'm gone.
+
+ _WeakPtrLinkedList* node = ReferenceCountedObject_weakPointer;
+
+ while (node != NULL) {
+ // Notify the weak pointer that it is going away
+ node->weakPtr->objectCollected();
+
+ // Free the node and advance
+ _WeakPtrLinkedList* tmp = node;
+ node = node->next;
+ delete tmp;
+ }
+}
+
+ReferenceCountedObject::~ReferenceCountedObject() {}
+
+
+ReferenceCountedObject::ReferenceCountedObject(const ReferenceCountedObject& notUsed) :
+ ReferenceCountedObject_refCount(0),
+ ReferenceCountedObject_weakPointer(0) {
+ (void)notUsed;
+ debugAssertM(G3D::isValidHeapPointer(this),
+ "Reference counted objects must be allocated on the heap.");
+}
+
+ReferenceCountedObject& ReferenceCountedObject::operator=(const ReferenceCountedObject& other) {
+ (void)other;
+ // Nothing changes when I am assigned; the reference count on
+ // both objects is the same (although my super-class probably
+ // changes).
+ return *this;
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/RegistryUtil.cpp b/dep/src/g3dlite/RegistryUtil.cpp
new file mode 100644
index 00000000000..fc4cebc2ee5
--- /dev/null
+++ b/dep/src/g3dlite/RegistryUtil.cpp
@@ -0,0 +1,290 @@
+/**
+ @file RegistryUtil.cpp
+
+ @created 2006-04-06
+ @edited 2006-04-24
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+*/
+
+#include "G3D/platform.h"
+
+// This file is only used on Windows
+#ifdef G3D_WIN32
+
+#include "G3D/RegistryUtil.h"
+#include "G3D/System.h"
+
+namespace G3D {
+
+// static helpers
+static HKEY getRootKeyFromString(const char* str, size_t length);
+
+
+bool RegistryUtil::keyExists(const std::string& key) {
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if (hkey == NULL) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
+
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ RegCloseKey(openKey);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool RegistryUtil::valueExists(const std::string& key, const std::string& value) {
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if ( hkey == NULL ) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ uint32 dataSize = 0;
+ result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast<LPDWORD>(&dataSize));
+
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+ RegCloseKey(openKey);
+ }
+ return (result == ERROR_SUCCESS);
+}
+
+
+bool RegistryUtil::readInt32(const std::string& key, const std::string& value, int32& data) {
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if ( hkey == NULL ) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ uint32 dataSize = sizeof(int32);
+ result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&data), reinterpret_cast<LPDWORD>(&dataSize));
+
+ debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
+
+ RegCloseKey(openKey);
+ }
+ return (result == ERROR_SUCCESS);
+}
+
+bool RegistryUtil::readBytes(const std::string& key, const std::string& value, uint8* data, uint32& dataSize) {
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if (hkey == NULL) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ if (data == NULL) {
+ result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast<LPDWORD>(&dataSize));
+ } else {
+ result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&data), reinterpret_cast<LPDWORD>(&dataSize));
+ }
+
+ debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
+
+ RegCloseKey(openKey);
+ }
+ return (result == ERROR_SUCCESS);
+}
+
+bool RegistryUtil::readString(const std::string& key, const std::string& value, std::string& data) {
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if (hkey == NULL) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ uint32 dataSize = 0;
+
+ result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast<LPDWORD>(&dataSize));
+ debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
+
+ // increment datasize to allow for non null-terminated strings in registry
+ dataSize += 1;
+
+ if (result == ERROR_SUCCESS) {
+ char* tmpStr = static_cast<char*>(System::malloc(dataSize));
+ System::memset(tmpStr, 0, dataSize);
+
+ result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(tmpStr), reinterpret_cast<LPDWORD>(&dataSize));
+ debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
+
+ if (result == ERROR_SUCCESS) {
+ data = tmpStr;
+ }
+
+ RegCloseKey(openKey);
+ System::free(tmpStr);
+ }
+ }
+ return (result == ERROR_SUCCESS);
+}
+
+bool RegistryUtil::writeInt32(const std::string& key, const std::string& value, int32 data) {
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if (hkey == NULL) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey);
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ result = RegSetValueExA(openKey, value.c_str(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&data), sizeof(int32));
+
+ debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value.");
+
+ RegCloseKey(openKey);
+ }
+ return (result == ERROR_SUCCESS);
+}
+
+bool RegistryUtil::writeBytes(const std::string& key, const std::string& value, const uint8* data, uint32 dataSize) {
+ debugAssert(data);
+
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if (hkey == NULL) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey);
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ if (data) {
+ result = RegSetValueExA(openKey, value.c_str(), 0, REG_BINARY, reinterpret_cast<const BYTE*>(data), dataSize);
+ }
+
+ debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value.");
+
+ RegCloseKey(openKey);
+ }
+ return (result == ERROR_SUCCESS);
+}
+
+bool RegistryUtil::writeString(const std::string& key, const std::string& value, const std::string& data) {
+ size_t pos = key.find('\\', 0);
+ if (pos == std::string::npos) {
+ return false;
+ }
+
+ HKEY hkey = getRootKeyFromString(key.c_str(), pos);
+
+ if (hkey == NULL) {
+ return false;
+ }
+
+ HKEY openKey;
+ int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey);
+ debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
+
+ if (result == ERROR_SUCCESS) {
+ result = RegSetValueExA(openKey, value.c_str(), 0, REG_SZ, reinterpret_cast<const BYTE*>(data.c_str()), (data.size() + 1));
+ debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value.");
+
+ RegCloseKey(openKey);
+ }
+ return (result == ERROR_SUCCESS);
+}
+
+
+// static helpers
+static HKEY getRootKeyFromString(const char* str, size_t length) {
+ debugAssert(str);
+
+ if (str) {
+ if ( strncmp(str, "HKEY_CLASSES_ROOT", length) == 0 ) {
+ return HKEY_CLASSES_ROOT;
+ } else if ( strncmp(str, "HKEY_CURRENT_CONFIG", length) == 0 ) {
+ return HKEY_CURRENT_CONFIG;
+ } else if ( strncmp(str, "HKEY_CURRENT_USER", length) == 0 ) {
+ return HKEY_CURRENT_USER;
+ } else if ( strncmp(str, "HKEY_LOCAL_MACHINE", length) == 0 ) {
+ return HKEY_LOCAL_MACHINE;
+ } else if ( strncmp(str, "HKEY_PERFORMANCE_DATA", length) == 0 ) {
+ return HKEY_PERFORMANCE_DATA;
+ } else if ( strncmp(str, "HKEY_PERFORMANCE_NLSTEXT", length) == 0 ) {
+ return HKEY_PERFORMANCE_NLSTEXT;
+ } else if ( strncmp(str, "HKEY_PERFORMANCE_TEXT", length) == 0 ) {
+ return HKEY_PERFORMANCE_TEXT;
+ } else if ( strncmp(str, "HKEY_CLASSES_ROOT", length) == 0 ) {
+ return HKEY_CLASSES_ROOT;
+ } else {
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+} // namespace G3D
+
+#endif // G3D_WIN32
diff --git a/dep/src/g3dlite/Sphere.cpp b/dep/src/g3dlite/Sphere.cpp
new file mode 100644
index 00000000000..4ed0811cb29
--- /dev/null
+++ b/dep/src/g3dlite/Sphere.cpp
@@ -0,0 +1,223 @@
+/**
+ @file Sphere.cpp
+
+ Sphere class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-04-17
+ @edited 2009-01-20
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Sphere.h"
+#include "G3D/stringutils.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/AABox.h"
+#include "G3D/Plane.h"
+
+namespace G3D {
+
+int32 Sphere::dummy;
+
+Sphere::Sphere(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Sphere::serialize(class BinaryOutput& b) const {
+ center.serialize(b);
+ b.writeFloat64(radius);
+}
+
+
+void Sphere::deserialize(class BinaryInput& b) {
+ center.deserialize(b);
+ radius = (float)b.readFloat64();
+}
+
+
+std::string Sphere::toString() const {
+ return format("Sphere(<%g, %g, %g>, %g)",
+ center.x, center.y, center.z, radius);
+}
+
+
+bool Sphere::contains(const Vector3& point) const {
+ float distance = (center - point).squaredMagnitude();
+ return distance <= square(radius);
+}
+
+
+bool Sphere::contains(const Sphere& other) const {
+ float distance = (center - other.center).squaredMagnitude();
+ return (radius >= other.radius) && (distance <= square(radius - other.radius));
+}
+
+
+bool Sphere::intersects(const Sphere& other) const {
+ return (other.center - center).length() <= (radius + other.radius);
+}
+
+
+void Sphere::merge(const Sphere& other) {
+ if (other.contains(*this)) {
+ *this = other;
+ } else if (! contains(other)) {
+ // The farthest distance is along the axis between the centers, which
+ // must not be colocated since neither contains the other.
+ Vector3 toMe = center - other.center;
+ // Get a point on the axis from each
+ toMe = toMe.direction();
+ const Vector3& A = center + toMe * radius;
+ const Vector3& B = other.center - toMe * other.radius;
+
+ // Now just bound the A->B segment
+ center = (A + B) * 0.5f;
+ radius = (A - B).length();
+ }
+ // (if this contains other, we're done)
+}
+
+
+bool Sphere::culledBy(
+ const Array<Plane>& plane,
+ int& cullingPlaneIndex,
+ const uint32 inMask,
+ uint32& outMask) const {
+
+ return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask);
+}
+
+
+bool Sphere::culledBy(
+ const Array<Plane>& plane,
+ int& cullingPlaneIndex,
+ const uint32 inMask) const {
+
+ return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask);
+}
+
+
+bool Sphere::culledBy(
+ const class Plane* plane,
+ int numPlanes,
+ int& cullingPlane,
+ const uint32 _inMask,
+ uint32& childMask) const {
+
+ if (radius == finf()) {
+ // No plane can cull the infinite box
+ return false;
+ }
+
+ uint32 inMask = _inMask;
+ assert(numPlanes < 31);
+
+ childMask = 0;
+
+ // See if there is one plane for which all of the
+ // vertices are in the negative half space.
+ for (int p = 0; p < numPlanes; p++) {
+
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
+ bool culledLow = ! plane[p].halfSpaceContainsFinite(center + plane[p].normal() * radius);
+ bool culledHigh = ! plane[p].halfSpaceContainsFinite(center - plane[p].normal() * radius);
+
+ if (culledLow) {
+ // Plane p culled the sphere
+ cullingPlane = p;
+
+ // The caller should not recurse into the children,
+ // since the parent is culled. If they do recurse,
+ // make them only test against this one plane, which
+ // will immediately cull the volume.
+ childMask = 1 << p;
+ return true;
+
+ } else if (culledHigh) {
+ // The bounding volume straddled the plane; we have
+ // to keep testing against this plane
+ childMask |= (1 << p);
+ }
+ }
+
+ // Move on to the next bit.
+ inMask = inMask >> 1;
+ }
+
+ // None of the planes could cull this box
+ cullingPlane = -1;
+ return false;
+}
+
+
+bool Sphere::culledBy(
+ const class Plane* plane,
+ int numPlanes,
+ int& cullingPlane,
+ const uint32 _inMask) const {
+
+ uint32 inMask = _inMask;
+ assert(numPlanes < 31);
+
+ // See if there is one plane for which all of the
+ // vertices are in the negative half space.
+ for (int p = 0; p < numPlanes; p++) {
+
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+ bool culled = ! plane[p].halfSpaceContains(center + plane[p].normal() * radius);
+ if (culled) {
+ // Plane p culled the sphere
+ cullingPlane = p;
+ return true;
+ }
+ }
+
+ // Move on to the next bit.
+ inMask = inMask >> 1;
+ }
+
+ // None of the planes could cull this box
+ cullingPlane = -1;
+ return false;
+}
+
+
+Vector3 Sphere::randomSurfacePoint() const {
+ return Vector3::random() * radius + center;
+}
+
+
+Vector3 Sphere::randomInteriorPoint() const {
+ Vector3 result;
+ do {
+ result = Vector3(uniformRandom(-1, 1),
+ uniformRandom(-1, 1),
+ uniformRandom(-1, 1));
+ } while (result.squaredMagnitude() >= 1.0f);
+
+ return result * radius + center;
+}
+
+
+float Sphere::volume() const {
+ return (float)pi() * (4.0f / 3.0f) * powf((float)radius, 3.0f);
+}
+
+
+float Sphere::area() const {
+ return (float)pi() * 4.0f * powf((float)radius, 2.0f);
+}
+
+
+void Sphere::getBounds(AABox& out) const {
+ Vector3 extent(radius, radius, radius);
+ out = AABox(center - extent, center + extent);
+}
+
+} // namespace
diff --git a/dep/src/g3dlite/SplineBase.cpp b/dep/src/g3dlite/SplineBase.cpp
new file mode 100644
index 00000000000..41221624b06
--- /dev/null
+++ b/dep/src/g3dlite/SplineBase.cpp
@@ -0,0 +1,162 @@
+#include "G3D/platform.h"
+#include "G3D/Spline.h"
+
+namespace G3D {
+
+float SplineBase::getFinalInterval() const {
+ if (! cyclic) {
+ return 0;
+ } else if (finalInterval <= 0) {
+ int N = time.size();
+ if (N >= 2) {
+ return (time[1] - time[0] + time[N - 1] - time[N - 2]) * 0.5f;
+ } else {
+ return 1.0f;
+ }
+ } else {
+ return finalInterval;
+ }
+}
+
+
+Matrix4 SplineBase::computeBasis() {
+ // The standard Catmull-Rom spline basis (e.g., Watt & Watt p108)
+ // is for [u^3 u^2 u^1 u^0] * B * [p[0] p[1] p[2] p[3]]^T.
+ // We need a basis formed for:
+ //
+ // U * C * [2*p'[1] p[1] p[2] 2*p'[2]]^T
+ //
+ // U * C * [p2-p0 p1 p2 p3-p1]^T
+ //
+ // To make this transformation, compute the differences of columns in C:
+ // For [p0 p1 p2 p3]
+ Matrix4 basis =
+ Matrix4( -1, 3, -3, 1,
+ 2, -5, 4, -1,
+ -1, 0, 1, 0,
+ 0, 2, 0, 0) * 0.5f;
+
+ // For [-p0 p1 p2 p3]^T
+ basis.setColumn(0, -basis.column(0));
+
+ // For [-p0 p1 p2 p3-p1]^T
+ basis.setColumn(1, basis.column(1) + basis.column(3));
+
+ // For [p2-p0 p1 p2 p3-p1]^T
+ basis.setColumn(2, basis.column(2) - basis.column(0));
+
+ return basis;
+}
+
+
+float SplineBase::duration() const {
+ if (time.size() == 0) {
+ return 0;
+ } else {
+ return time.last() - time[0] + getFinalInterval();
+ }
+}
+
+
+void SplineBase::computeIndexInBounds(float s, int& i, float& u) const {
+ int N = time.size();
+ float t0 = time[0];
+ float tn = time[N - 1];
+
+ i = iFloor((N - 1) * (s - t0) / (tn - t0));
+
+ // Inclusive bounds for binary search
+ int hi = N - 1;
+ int lo = 0;
+
+ while ((time[i] > s) || (time[i + 1] <= s)) {
+
+ if (time[i] > s) {
+ // too big
+ hi = i - 1;
+ } else if (time[i + 1] <= s) {
+ // too small
+ lo = i + 1;
+ }
+
+ i = (hi + lo) / 2;
+ }
+
+ // Having exited the above loop, i must be correct, so compute u.
+ u = (s - time[i]) / (time[i + 1] - time[i]);
+}
+
+
+void SplineBase::computeIndex(float s, int& i, float& u) const {
+ int N = time.size();
+ debugAssertM(N > 0, "No control points");
+ float t0 = time[0];
+ float tn = time[N - 1];
+
+ if (N < 2) {
+ // No control points to work with
+ i = 0;
+ u = 0.0;
+ } else if (cyclic) {
+ float fi = getFinalInterval();
+
+ // Cyclic spline
+ if ((s < t0) || (s >= tn + fi)) {
+ // Cyclic, off the bottom or top
+
+ // Compute offset and reduce to the in-bounds case
+
+ float d = duration();
+ // Number of times we wrapped around the cyclic array
+ int wraps = iFloor((s - t0) / d);
+
+ debugAssert(s - d * wraps >= t0);
+ debugAssert(s - d * wraps < tn + getFinalInterval());
+
+ computeIndex(s - d * wraps, i, u);
+ i += wraps * N;
+
+ } else if (s >= tn) {
+ debugAssert(s < tn + fi);
+ // Cyclic, off the top but before the end of the last interval
+ i = N - 1;
+ u = (s - tn) / fi;
+
+ } else {
+ // Cyclic, in bounds
+ computeIndexInBounds(s, i, u);
+ }
+
+ } else {
+ // Non-cyclic
+
+ if (s < t0) {
+ // Non-cyclic, off the bottom. Assume points are spaced
+ // following the first time interval.
+
+ float dt = time[1] - t0;
+ float x = (s - t0) / dt;
+ i = iFloor(x);
+ u = x - i;
+
+ } else if (s >= tn) {
+ // Non-cyclic, off the top. Assume points are spaced following
+ // the last time interval.
+
+ float dt = tn - time[N - 2];
+ float x = N - 1 + (s - tn) / dt;
+ i = iFloor(x);
+ u = x - i;
+
+ } else {
+ // In bounds, non-cyclic. Assume a regular
+ // distribution (which gives O(1) for uniform spacing)
+ // and then binary search to handle the general case
+ // efficiently.
+ computeIndexInBounds(s, i, u);
+
+ } // if in bounds
+ } // if cyclic
+}
+
+}
diff --git a/dep/src/g3dlite/Stopwatch.cpp b/dep/src/g3dlite/Stopwatch.cpp
new file mode 100644
index 00000000000..9b785d50295
--- /dev/null
+++ b/dep/src/g3dlite/Stopwatch.cpp
@@ -0,0 +1,119 @@
+/**
+ @file Stopwatch.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2005-10-05
+ @edited 2009-03-14
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/Stopwatch.h"
+#include "G3D/System.h"
+
+namespace G3D {
+
+Stopwatch::Stopwatch(const std::string& myName) :
+ myName(myName),
+ inBetween(false), lastTockTime(-1),
+ lastDuration(0), lastCycleCount(0), m_fps(0), emwaFPS(0),
+ m_smoothFPS(0), emwaDuration(0) {
+ computeOverhead();
+ reset();
+}
+
+
+void Stopwatch::computeOverhead() {
+ cycleOverhead = 0;
+ tick();
+ tock();
+ cycleOverhead = elapsedCycles();
+}
+
+
+void Stopwatch::tick() {
+ // This is 'alwaysAssert' instead of 'debugAssert'
+ // since people rarely profile in debug mode.
+ alwaysAssertM(! inBetween, "Stopwatch::tick() called twice in a row.");
+ inBetween = true;
+
+ // We read RDTSC twice here, but it is more abstract to implement this
+ // way and at least we're reading the cycle count last.
+ timeStart = System::time();
+ System::beginCycleCount(cycleStart);
+}
+
+
+void Stopwatch::tock() {
+ System::endCycleCount(cycleStart);
+ RealTime now = System::time();
+ lastDuration = now - timeStart;
+ if (abs(emwaDuration - lastDuration) > max(emwaDuration, lastDuration) * 0.50) {
+ // Off by more than 50%
+ emwaDuration = lastDuration;
+ } else {
+ emwaDuration = lastDuration * 0.05 + emwaDuration * 0.95;
+ }
+
+ lastCycleCount = cycleStart - cycleOverhead;
+ if (lastCycleCount < 0) {
+ lastCycleCount = 0;
+ }
+
+ if (lastTockTime != -1.0) {
+ m_fps = 1.0 / (now - lastTockTime);
+
+ const double blend = 0.01;
+ emwaFPS = m_fps * blend + emwaFPS * (1.0 - blend);
+
+ double maxDiscrepancyPercentage = 0.25;
+ if (abs(emwaFPS - m_fps) > max(emwaFPS, m_fps) * maxDiscrepancyPercentage) {
+ // The difference between emwa and m_fps is way off, so
+ // update emwa directly.
+ emwaFPS = m_fps * 0.20 + emwaFPS * 0.80;
+ }
+
+ // Update m_smoothFPS only when the value varies significantly.
+ // We round so as to not mislead the user as to the accuracy of
+ // the number.
+ if (m_smoothFPS == 0) {
+ m_smoothFPS = m_fps;
+ } else if (emwaFPS <= 20) {
+ if (::fabs(m_smoothFPS - emwaFPS) > 0.75) {
+ // Small number and display is off by more than 0.75; round to the nearest 0.1
+ m_smoothFPS = floor(emwaFPS * 10.0 + 0.5) / 10.0;
+ }
+ } else if (::fabs(m_smoothFPS - emwaFPS) > 1.25) {
+ // Large number and display is off by more than 1.25; round to the nearest 1.0
+ m_smoothFPS = floor(emwaFPS + 0.5);
+ }
+ }
+ lastTockTime = now;
+
+ alwaysAssertM(inBetween, "Stopwatch::tock() called without matching tick.");
+ inBetween = false;
+}
+
+
+void Stopwatch::reset() {
+ prevTime = startTime = System::time();
+ prevMark = "start";
+}
+
+
+void Stopwatch::after(const std::string& s) {
+ RealTime now = System::time();
+ debugPrintf("%s: %10s - %8fs since %s (%fs since start)\n",
+ myName.c_str(),
+ s.c_str(),
+ now - prevTime,
+ prevMark.c_str(),
+ now - startTime);
+ prevTime = now;
+ prevMark = s;
+}
+
+}
+
diff --git a/dep/src/g3dlite/System.cpp b/dep/src/g3dlite/System.cpp
index e55be13adc5..e03c4e8c6fa 100644
--- a/dep/src/g3dlite/System.cpp
+++ b/dep/src/g3dlite/System.cpp
@@ -1,7 +1,7 @@
-/**
+/**
@file System.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
Note: every routine must call init() first.
@@ -10,44 +10,56 @@
can be used at all. At runtime, processor detection is used to
determine if we can safely call the routines that use that assembly.
- @cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm
- @cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1
- @cite Michael Herf http://www.stereopsis.com/memcpy.html
-
@created 2003-01-25
- @edited 2006-05-17
+ @edited 2010-01-03
*/
#include "G3D/platform.h"
#include "G3D/System.h"
#include "G3D/debug.h"
-#include "G3D/format.h"
-
-#if defined(__OpenBSD__)
- #include <stdint.h>
+#include "G3D/fileutils.h"
+#include "G3D/TextOutput.h"
+#include "G3D/G3DGameUnits.h"
+#include "G3D/Crypto.h"
+#include "G3D/prompt.h"
+#include "G3D/stringutils.h"
+#include "G3D/Log.h"
+#include "G3D/Table.h"
+#include "G3D/GMutex.h"
+#include "G3D/units.h"
+#include <time.h>
+
+#include <cstring>
+#include <cstdio>
+
+// Uncomment the following line to turn off G3D::System memory
+// allocation and use the operating system's malloc.
+//#define NO_BUFFERPOOL
+
+#if defined(__i386__) || defined(__x86_64__) || defined(G3D_WIN32)
+# define G3D_NOT_OSX_PPC
#endif
-#ifdef G3D_WIN32
+#include <cstdlib>
- #include <conio.h>
- #include <sys/timeb.h>
- #include "G3D/RegistryUtil.h"
+#ifdef G3D_WIN32
-#elif defined(G3D_LINUX)
+# include <conio.h>
+# include <sys/timeb.h>
+# include "G3D/RegistryUtil.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/select.h>
- #include <termios.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <sys/time.h>
- #include <pthread.h>
+#elif defined(G3D_LINUX)
- // #include <assert.h>
+# include <stdlib.h>
+# include <stdio.h>
+# include <errno.h>
+# include <sys/types.h>
+# include <sys/select.h>
+# include <termios.h>
+# include <unistd.h>
+# include <sys/ioctl.h>
+# include <sys/time.h>
+# include <pthread.h>
#elif defined(G3D_OSX)
@@ -67,50 +79,847 @@
#include <CoreServices/CoreServices.h>
#endif
-#if defined(SSE)
- #include <xmmintrin.h>
+// SIMM include
+#ifdef __SSE__
+#include <xmmintrin.h>
#endif
namespace G3D {
-static char versionCstr[1024];
-System::OutOfMemoryCallback System::outOfMemoryCallback = NULL;
-void System::init() {
- // Cannot use most G3D data structures or utility functions in here because
- // they are not initialized.
+/** Checks if the CPUID command is available on the processor (called from init) */
+static bool checkForCPUID();
- static bool initialized = false;
+/** Called from init */
+static void getG3DVersion(std::string& s);
+
+/** Called from init */
+static G3DEndian checkEndian();
- if (initialized) {
+
+System& System::instance() {
+ static System thesystem;
+ return thesystem;
+}
+
+
+System::System() :
+ m_initialized(false),
+ m_cpuSpeed(0),
+ m_hasCPUID(false),
+ m_hasRDTSC(false),
+ m_hasMMX(false),
+ m_hasSSE(false),
+ m_hasSSE2(false),
+ m_hasSSE3(false),
+ m_has3DNOW(false),
+ m_has3DNOW2(false),
+ m_hasAMDMMX(false),
+ m_cpuVendor("Uninitialized"),
+ m_numCores(1),
+ m_machineEndian(G3D_LITTLE_ENDIAN),
+ m_cpuArch("Uninitialized"),
+ m_operatingSystem("Uninitialized"),
+ m_version("Uninitialized"),
+ m_outOfMemoryCallback(NULL),
+ m_realWorldGetTickTime0(0),
+ m_highestCPUIDFunction(0) {
+
+ init();
+}
+
+
+void System::init() {
+ // NOTE: Cannot use most G3D data structures or utility functions
+ // in here because they are not initialized.
+
+ if (m_initialized) {
return;
+ } else {
+ m_initialized = true;
}
- initialized = true;
+ getG3DVersion(m_version);
+
+ m_machineEndian = checkEndian();
+
+ m_hasCPUID = checkForCPUID();
+ // Process the CPUID information
+ if (m_hasCPUID) {
+ // We read the standard CPUID level 0x00000000 which should
+ // be available on every x86 processor. This fills out
+ // a string with the processor vendor tag.
+ unsigned int eaxreg = 0, ebxreg = 0, ecxreg = 0, edxreg = 0;
+
+ cpuid(CPUID_VENDOR_ID, eaxreg, ebxreg, ecxreg, edxreg);
+
+ {
+ char c[100];
+ // Then we connect the single register values to the vendor string
+ *((unsigned int*) c) = ebxreg;
+ *((unsigned int*) (c + 4)) = edxreg;
+ *((unsigned int*) (c + 8)) = ecxreg;
+ c[12] = '\0';
+ m_cpuVendor = c;
+ }
+
+ switch (ebxreg) {
+ case 0x756E6547: // GenuineIntel
+ m_cpuArch = "Intel Processor";
+ break;
+
+ case 0x68747541: // AuthenticAMD
+ m_cpuArch = "AMD Processor";
+ break;
+
+ case 0x69727943: // CyrixInstead
+ m_cpuArch = "Cyrix Processor";
+ break;
+
+ default:
+ m_cpuArch = "Unknown Processor Vendor";
+ break;
+ }
+
+
+ unsigned int highestFunction = eaxreg;
+ if (highestFunction >= CPUID_NUM_CORES) {
+ cpuid(CPUID_NUM_CORES, eaxreg, ebxreg, ecxreg, edxreg);
+ // Number of cores is in (eax>>26) + 1
+ m_numCores = (eaxreg >> 26) + 1;
+ }
+ cpuid(CPUID_GET_HIGHEST_FUNCTION, m_highestCPUIDFunction, ebxreg, ecxreg, edxreg);
+ }
+
+
+ // Get the operating system name (also happens to read some other information)
+# ifdef G3D_WIN32
+ // Note that this overrides some of the values computed above
+ bool success = RegistryUtil::readInt32
+ ("HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
+ "~MHz", m_cpuSpeed);
+
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ const char* arch = NULL;
+ switch (systemInfo.wProcessorArchitecture) {
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ arch = "Intel";
+ break;
+
+ case PROCESSOR_ARCHITECTURE_MIPS:
+ arch = "MIPS";
+ break;
+
+ case PROCESSOR_ARCHITECTURE_ALPHA:
+ arch = "Alpha";
+ break;
+
+ case PROCESSOR_ARCHITECTURE_PPC:
+ arch = "Power PC";
+ break;
+
+ default:
+ arch = "Unknown";
+ }
+
+ m_numCores = systemInfo.dwNumberOfProcessors;
+ uint32 maxAddr = (uint32)systemInfo.lpMaximumApplicationAddress;
+ {
+ char c[1024];
+ sprintf(c, "%d x %d-bit %s processor",
+ systemInfo.dwNumberOfProcessors,
+ (int)(::log((double)maxAddr) / ::log(2.0) + 2.0),
+ arch);
+ m_cpuArch = c;
+ }
+
+ OSVERSIONINFO osVersionInfo;
+ osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ success = GetVersionEx(&osVersionInfo) != 0;
+
+ if (success) {
+ char c[1000];
+ sprintf(c, "Windows %d.%d build %d Platform %d %s",
+ osVersionInfo.dwMajorVersion,
+ osVersionInfo.dwMinorVersion,
+ osVersionInfo.dwBuildNumber,
+ osVersionInfo.dwPlatformId,
+ osVersionInfo.szCSDVersion);
+ m_operatingSystem = c;
+ } else {
+ m_operatingSystem = "Windows";
+ }
+
+# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
+
+ {
+ // Find the operating system using the 'uname' command
+ FILE* f = popen("uname -a", "r");
+
+ int len = 100;
+ char* r = (char*)::malloc(len * sizeof(char));
+ fgets(r, len, f);
+ // Remove trailing newline
+ if (r[strlen(r) - 1] == '\n') {
+ r[strlen(r) - 1] = '\0';
+ }
+ fclose(f);
+
+ m_operatingSystem = r;
+ ::free(r);
+ }
+
+# elif defined(G3D_OSX)
+
+ // Operating System:
+ SInt32 macVersion;
+ Gestalt(gestaltSystemVersion, &macVersion);
+
+ int major = (macVersion >> 8) & 0xFF;
+ int minor = (macVersion >> 4) & 0xF;
+ int revision = macVersion & 0xF;
+
+ {
+ char c[1000];
+ sprintf(c, "OS X %x.%x.%x", major, minor, revision);
+ m_operatingSystem = c;
+ }
+
+ // Clock Cycle Timing Information:
+ Gestalt('pclk', &m_OSXCPUSpeed);
+ m_cpuSpeed = iRound((double)m_OSXCPUSpeed / (1024 * 1024));
+ m_secondsPerNS = 1.0 / 1.0e9;
+
+ // System Architecture:
+ const NXArchInfo* pInfo = NXGetLocalArchInfo();
+
+ if (pInfo) {
+ m_cpuArch = pInfo->description;
+
+ switch (pInfo->cputype) {
+ case CPU_TYPE_POWERPC:
+ switch(pInfo->cpusubtype){
+ case CPU_SUBTYPE_POWERPC_750:
+ case CPU_SUBTYPE_POWERPC_7400:
+ case CPU_SUBTYPE_POWERPC_7450:
+ m_cpuVendor = "Motorola";
+ break;
+ case CPU_SUBTYPE_POWERPC_970:
+ m_cpuVendor = "IBM";
+ break;
+ }
+ break;
+
+ case CPU_TYPE_I386:
+ m_cpuVendor = "Intel";
+ break;
+ }
+ }
+# endif
+
+ initTime();
+
+ getStandardProcessorExtensions();
+}
+
+
+void getG3DVersion(std::string& s) {
+ char cstr[100];
if ((G3D_VER % 100) != 0) {
- sprintf(versionCstr, "G3D %d.%02d beta %d",
- G3D_VER / 10000,
- (G3D_VER / 100) % 100,
- G3D_VER % 100);
+ sprintf(cstr, "G3D %d.%02d beta %d",
+ G3D_VER / 10000,
+ (G3D_VER / 100) % 100,
+ G3D_VER % 100);
} else {
- sprintf(versionCstr, "G3D %d.%02d",
- G3D_VER / 10000,
- (G3D_VER / 100) % 100);
+ sprintf(cstr, "G3D %d.%02d",
+ G3D_VER / 10000,
+ (G3D_VER / 100) % 100);
}
+ s = cstr;
+}
+
+#if 0 // TODO: delete
+struct Directory {
+ std::string path;
+ Array<std::string> contents;
+};
+static bool maybeAddDirectory(const std::string& newPath, Array<Directory>& directoryArray, bool recurse = true) {
+ if (fileExists(newPath)) {
+ Directory& d = directoryArray.next();
+ d.path = newPath;
+ getFiles(pathConcat(newPath, "*"), d.contents);
+ Array<std::string> dirs;
+ getDirs(pathConcat(newPath, "*"), dirs);
+ d.contents.append(dirs);
+
+ if (recurse) {
+ // Look for subdirectories
+ static const std::string subdirs[] =
+ {"font", "gui", "SuperShader", "cubemap", "icon", "material", "image", "md2", "md3", "ifs", "3ds", "sky", ""};
+
+ for (int j = 0; j < dirs.size(); ++j) {
+ for (int i = 0; ! subdirs[i].empty(); ++i) {
+ if (dirs[j] == subdirs[i]) {
+ maybeAddDirectory(pathConcat(newPath, dirs[j]), directoryArray, false);
+ }
+ }
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
}
+#endif
+
+std::string System::findDataFile
+(const std::string& full,
+ bool errorIfNotFound) {
+
+ // Places where specific files were most recently found. This is
+ // used to cache seeking of common files.
+ static Table<std::string, std::string> lastFound;
+
+ // First check if the file exists as requested. This will go
+ // through the FileSystemCache, so most calls do not touch disk.
+ if (fileExists(full)) {
+ return full;
+ }
+
+ // Now check where we previously found this file.
+ std::string* last = lastFound.getPointer(full);
+ if (last != NULL) {
+ if (fileExists(*last)) {
+ // Even if cwd has changed the file is still present.
+ // We won't notice if it has been deleted, however.
+ return *last;
+ } else {
+ // Remove this from the cache it is invalid
+ lastFound.remove(full);
+ }
+ }
+
+ // Places to look
+ static Array<std::string> directoryArray;
+
+ if (directoryArray.size() == 0) {
+ // Initialize the directory array
+ RealTime t0 = System::time();
+
+ Array<std::string> baseDirArray;
+
+ std::string initialAppDataDir(instance().m_appDataDir);
+
+ baseDirArray.append("");
+ if (! initialAppDataDir.empty()) {
+ baseDirArray.append(initialAppDataDir);
+ }
+
+ const char* g3dPath = getenv("G3DDATA");
+
+ if (g3dPath && (initialAppDataDir != g3dPath)) {
+ baseDirArray.append(g3dPath);
+ }
+
+ static const std::string subdirs[] =
+ {"font", "gui", "SuperShader", "cubemap", "icon", "material", "image", "md2", "md3", "ifs", "3ds", "sky", ""};
+ for (int j = 0; j < baseDirArray.size(); ++j) {
+ std::string d = baseDirArray[j];
+ if (fileExists(d)) {
+ directoryArray.append(d);
+ for (int i = 0; ! subdirs[i].empty(); ++i) {
+ const std::string& p = pathConcat(d, subdirs[i]);
+ if (fileExists(p)) {
+ directoryArray.append(p);
+ }
+ }
+ }
+ }
+
+ logLazyPrintf("Initializing System::findDataFile took %fs\n", System::time() - t0);
+ }
+
+ for (int i = 0; i < directoryArray.size(); ++i) {
+ const std::string& p = pathConcat(directoryArray[i], full);
+ if (fileExists(p)) {
+ lastFound.set(full, p);
+ return p;
+ }
+ }
+
+ if (errorIfNotFound) {
+ // Generate an error message
+ std::string locations;
+ for (int i = 0; i < directoryArray.size(); ++i) {
+ locations += pathConcat(directoryArray[i], full) + "\n";
+ }
+ alwaysAssertM(false, "Could not find '" + full + "' in:\n" + locations);
+ }
+
+ // Not found
+ return "";
+}
+
+
+void System::setAppDataDir(const std::string& path) {
+ instance().m_appDataDir = path;
+}
+
+
+std::string demoFindData(bool errorIfNotFound) {
+ static const char* g3dPath = getenv("G3DDATA");
+ if (g3dPath) {
+ return g3dPath;
+# ifdef G3D_WIN32
+ } else if (fileExists("../data")) {
+ // G3D install on Windows
+ return "../data";
+ } else if (fileExists("../data-files")) {
+ // G3D source on Windows
+ return "../data-files";
+# else
+ } else if (fileExists("../../../../data")) {
+ // G3D install on Unix
+ return "../../../../data";
+ } else if (fileExists("../../../../data-files")) {
+ // G3D source on Unix
+ return "../../../../data-files";
+# endif
+ } else {
+ return "";
+ }
+}
+
+
+const std::string& System::build() {
+ const static std::string b =
+# ifdef _DEBUG
+ "Debug";
+# else
+ "Release";
+# endif
+
+ return b;
+}
+
+
+static G3DEndian checkEndian() {
+ int32 a = 1;
+ if (*(uint8*)&a == 1) {
+ return G3D_LITTLE_ENDIAN;
+ } else {
+ return G3D_BIG_ENDIAN;
+ }
+}
+
+
+static bool checkForCPUID() {
+ // all known supported architectures have cpuid
+ // add cases for incompatible architectures if they are added
+ // e.g., if we ever support __powerpc__ being defined again
+
+ return true;
+}
+
+
+void System::getStandardProcessorExtensions() {
+#if ! defined(G3D_OSX) || defined(G3D_OSX_INTEL)
+ if (! m_hasCPUID) {
+ return;
+ }
+
+ uint32 eaxreg = 0, ebxreg = 0, ecxreg = 0, features = 0;
+
+ cpuid(CPUID_PROCESSOR_FEATURES, eaxreg, ebxreg, ecxreg, features);
+
+# define checkBit(var, bit) ((var & (1 << bit)) ? true : false)
+
+ m_hasRDTSC = checkBit(features, 4);
+ m_hasMMX = checkBit(features, 23);
+ m_hasSSE = checkBit(features, 25);
+ m_hasSSE2 = checkBit(features, 26);
+ // Bit 28 is HTT; not checked by G3D
+
+ m_hasSSE3 = checkBit(ecxreg, 0);
+
+ if (m_highestCPUIDFunction >= CPUID_EXTENDED_FEATURES) {
+ cpuid(CPUID_EXTENDED_FEATURES, eaxreg, ebxreg, ecxreg, features);
+ m_hasAMDMMX = checkBit(features, 22); // Only on AMD
+ m_has3DNOW = checkBit(features, 31); // Only on AMD
+ m_has3DNOW2 = checkBit(features, 30); // Only on AMD
+ } else {
+ m_hasAMDMMX = false;
+ m_has3DNOW = false;
+ m_has3DNOW2 = false;
+ }
+
+# undef checkBit
+#endif
+}
+
+#if defined(G3D_WIN32) && !defined(G3D_64BIT)
+ #pragma message("Port System::memcpy SIMD to all platforms")
+/** Michael Herf's fast memcpy */
+void memcpyMMX(void* dst, const void* src, int nbytes) {
+ int remainingBytes = nbytes;
+
+ if (nbytes > 64) {
+ _asm {
+ mov esi, src
+ mov edi, dst
+ mov ecx, nbytes
+ shr ecx, 6 // 64 bytes per iteration
+
+ loop1:
+ movq mm1, 0[ESI] // Read in source data
+ movq mm2, 8[ESI]
+ movq mm3, 16[ESI]
+ movq mm4, 24[ESI]
+ movq mm5, 32[ESI]
+ movq mm6, 40[ESI]
+ movq mm7, 48[ESI]
+ movq mm0, 56[ESI]
+
+ movntq 0[EDI], mm1 // Non-temporal stores
+ movntq 8[EDI], mm2
+ movntq 16[EDI], mm3
+ movntq 24[EDI], mm4
+ movntq 32[EDI], mm5
+ movntq 40[EDI], mm6
+ movntq 48[EDI], mm7
+ movntq 56[EDI], mm0
+
+ add esi, 64
+ add edi, 64
+ dec ecx
+ jnz loop1
+
+ emms
+ }
+ remainingBytes -= ((nbytes >> 6) << 6);
+ }
+
+ if (remainingBytes > 0) {
+ // Memcpy the rest
+ memcpy((uint8*)dst + (nbytes - remainingBytes),
+ (const uint8*)src + (nbytes - remainingBytes), remainingBytes);
+ }
+}
+#endif
void System::memcpy(void* dst, const void* src, size_t numBytes) {
- ::memcpy(dst, src, numBytes);
+#if defined(G3D_WIN32) && !defined(G3D_64BIT)
+ memcpyMMX(dst, src, numBytes);
+#else
+ ::memcpy(dst, src, numBytes);
+#endif
+}
+
+
+/** Michael Herf's fastest memset. n32 must be filled with the same
+ character repeated. */
+#if defined(G3D_WIN32) && !defined(G3D_64BIT)
+ #pragma message("Port System::memfill SIMD to all platforms")
+
+// On x86 processors, use MMX
+void memfill(void *dst, int n32, unsigned long i) {
+
+ int originalSize = i;
+ int bytesRemaining = i;
+
+ if (i > 16) {
+
+ bytesRemaining = i % 16;
+ i -= bytesRemaining;
+ __asm {
+ movq mm0, n32
+ punpckldq mm0, mm0
+ mov edi, dst
+
+ loopwrite:
+
+ movntq 0[edi], mm0
+ movntq 8[edi], mm0
+
+ add edi, 16
+ sub i, 16
+ jg loopwrite
+
+ emms
+ }
+ }
+
+ if (bytesRemaining > 0) {
+ ::memset((uint8*)dst + (originalSize - bytesRemaining), n32, bytesRemaining);
+ }
}
+#endif
+
void System::memset(void* dst, uint8 value, size_t numBytes) {
- ::memset(dst, value, numBytes);
+#if defined(G3D_WIN32) && !defined(G3D_64BIT)
+ uint32 v = value;
+ v = v + (v << 8) + (v << 16) + (v << 24);
+ G3D::memfill(dst, v, numBytes);
+#else
+ ::memset(dst, value, numBytes);
+#endif
+}
+
+
+/** Removes the 'd' that icompile / Morgan's VC convention appends. */
+static std::string computeAppName(const std::string& start) {
+ if (start.size() < 2) {
+ return start;
+ }
+
+ if (start[start.size() - 1] == 'd') {
+ // Maybe remove the 'd'; see if ../ or ../../ has the same name
+ char tmp[1024];
+ getcwd(tmp, sizeof(tmp));
+ std::string drive, base, ext;
+ Array<std::string> path;
+ parseFilename(tmp, drive, path, base, ext);
+
+ std::string shortName = start.substr(0, start.size() - 1);
+
+ if ((path.size() > 1) && (toLower(path.last()) == toLower(shortName))) {
+ return shortName;
+ }
+
+ if ((path.size() > 2) && (toLower(path[path.size() - 2]) == toLower(shortName))) {
+ return shortName;
+ }
+ }
+
+ return start;
+}
+
+
+std::string& System::appName() {
+ static std::string n = computeAppName(filenameBase(currentProgramFilename()));
+ return n;
+}
+
+
+std::string System::currentProgramFilename() {
+ char filename[2048];
+
+# ifdef G3D_WIN32
+ {
+ GetModuleFileNameA(NULL, filename, sizeof(filename));
+ }
+# elif defined(G3D_OSX)
+ {
+ // Run the 'ps' program to extract the program name
+ // from the process ID.
+ int pid;
+ FILE* fd;
+ char cmd[80];
+ pid = getpid();
+ sprintf(cmd, "ps -p %d -o comm=\"\"", pid);
+
+ fd = popen(cmd, "r");
+ int s = fread(filename, 1, sizeof(filename), fd);
+ // filename will contain a newline. Overwrite it:
+ filename[s - 1] = '\0';
+ }
+# else
+ {
+ int ret = readlink("/proc/self/exe", filename, sizeof(filename));
+
+ // In case of an error, leave the handling up to the caller
+ if (ret == -1) {
+ return "";
+ }
+
+ debugAssert((int)sizeof(filename) > ret);
+
+ // Ensure proper NULL termination
+ filename[ret] = 0;
+ }
+ #endif
+
+ return filename;
+}
+
+
+void System::sleep(RealTime t) {
+
+ // Overhead of calling this function, measured from a previous run.
+ static const RealTime OVERHEAD = 0.00006f;
+
+ RealTime now = time();
+ RealTime wakeupTime = now + t - OVERHEAD;
+
+ RealTime remainingTime = wakeupTime - now;
+ RealTime sleepTime = 0;
+
+ // On Windows, a "time slice" is measured in quanta of 3-5 ms (http://support.microsoft.com/kb/259025)
+ // Sleep(0) yields the remainder of the time slice, which could be a long time.
+ // A 1 ms minimum time experimentally kept the "Empty GApp" at nearly no CPU load at 100 fps,
+ // yet nailed the frame timing perfectly.
+ static RealTime minRealSleepTime = 3 * units::milliseconds();
+
+ while (remainingTime > 0) {
+
+ if (remainingTime > minRealSleepTime * 2.5) {
+ // Safe to use Sleep with a time... sleep for half the remaining time
+ sleepTime = max(remainingTime * 0.5, 0.0005);
+ } else if (remainingTime > minRealSleepTime) {
+ // Safe to use Sleep with a zero time;
+ // causes the program to yield only
+ // the current time slice, and then return.
+ sleepTime = 0;
+ } else {
+ // Not safe to use Sleep; busy wait
+ sleepTime = -1;
+ }
+
+ if (sleepTime >= 0) {
+ #ifdef G3D_WIN32
+ // Translate to milliseconds
+ Sleep((int)(sleepTime * 1e3));
+ #else
+ // Translate to microseconds
+ usleep((int)(sleepTime * 1e6));
+ #endif
+ }
+
+ now = time();
+ remainingTime = wakeupTime - now;
+ }
+}
+
+
+void System::consoleClearScreen() {
+# ifdef G3D_WIN32
+ system("cls");
+# else
+ system("clear");
+# endif
+}
+
+
+bool System::consoleKeyPressed() {
+ #ifdef G3D_WIN32
+
+ return _kbhit() != 0;
+
+ #else
+
+ static const int STDIN = 0;
+ static bool initialized = false;
+
+ if (! initialized) {
+ // Use termios to turn off line buffering
+ termios term;
+ tcgetattr(STDIN, &term);
+ term.c_lflag &= ~ICANON;
+ tcsetattr(STDIN, TCSANOW, &term);
+ setbuf(stdin, NULL);
+ initialized = true;
+ }
+
+ #ifdef G3D_LINUX
+
+ int bytesWaiting;
+ ioctl(STDIN, FIONREAD, &bytesWaiting);
+ return bytesWaiting;
+
+ #else
+
+ timeval timeout;
+ fd_set rdset;
+
+ FD_ZERO(&rdset);
+ FD_SET(STDIN, &rdset);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ return select(STDIN + 1, &rdset, NULL, NULL, &timeout);
+ #endif
+ #endif
+}
+
+
+int System::consoleReadKey() {
+# ifdef G3D_WIN32
+ return _getch();
+# else
+ char c;
+ read(0, &c, 1);
+ return c;
+# endif
+}
+
+
+void System::initTime() {
+ #ifdef G3D_WIN32
+ if (QueryPerformanceFrequency(&m_counterFrequency)) {
+ QueryPerformanceCounter(&m_start);
+ }
+
+ struct _timeb t;
+ _ftime(&t);
+
+ m_realWorldGetTickTime0 = (RealTime)t.time - t.timezone * G3D::MINUTE + (t.dstflag ? G3D::HOUR : 0);
+
+ #else
+ gettimeofday(&m_start, NULL);
+ // "sse" = "seconds since epoch". The time
+ // function returns the seconds since the epoch
+ // GMT (perhaps more correctly called UTC).
+ time_t gmt = ::time(NULL);
+
+ // No call to free or delete is needed, but subsequent
+ // calls to asctime, ctime, mktime, etc. might overwrite
+ // local_time_vals.
+ tm* localTimeVals = localtime(&gmt);
+
+ time_t local = gmt;
+
+ if (localTimeVals) {
+ // tm_gmtoff is already corrected for daylight savings.
+ local = local + localTimeVals->tm_gmtoff;
+ }
+
+ m_realWorldGetTickTime0 = local;
+ #endif
+}
+
+
+RealTime System::time() {
+# ifdef G3D_WIN32
+ LARGE_INTEGER now;
+ QueryPerformanceCounter(&now);
+
+ return ((RealTime)(now.QuadPart - instance().m_start.QuadPart) /
+ instance().m_counterFrequency.QuadPart) + instance().m_realWorldGetTickTime0;
+# else
+ // Linux resolution defaults to 100Hz.
+ // There is no need to do a separate RDTSC call as gettimeofday
+ // actually uses RDTSC when on systems that support it, otherwise
+ // it uses the system clock.
+ struct timeval now;
+ gettimeofday(&now, NULL);
+
+ return (now.tv_sec - instance().m_start.tv_sec) +
+ (now.tv_usec - instance().m_start.tv_usec) / 1e6
+ + instance().m_realWorldGetTickTime0;
+# endif
}
////////////////////////////////////////////////////////////////
+
+#define REALPTR_TO_USERPTR(x) ((uint8*)(x) + sizeof (void *))
+#define USERPTR_TO_REALPTR(x) ((uint8*)(x) - sizeof (void *))
+#define REALBLOCK_SIZE(x) ((x) + sizeof (void *))
+
class BufferPool {
public:
@@ -119,16 +928,18 @@ public:
A large block is preallocated for tiny buffers; they are used with
tremendous frequency. Other buffers are allocated as demanded.
+ Tiny buffers are 128 bytes long because that seems to align well with
+ cache sizes on many machines.
*/
enum {tinyBufferSize = 128, smallBufferSize = 1024, medBufferSize = 4096};
- /**
+ /**
Most buffers we're allowed to store.
- 64000 * 128 = 8 MB (preallocated)
- 1024 * 1024 = 1 MB (allocated on demand)
- 1024 * 4096 = 4 MB (allocated on demand)
+ 250000 * 128 = 32 MB (preallocated)
+ 10000 * 1024 = 10 MB (allocated on demand)
+ 1024 * 4096 = 4 MB (allocated on demand)
*/
- enum {maxTinyBuffers = 64000, maxSmallBuffers = 1024, maxMedBuffers = 1024};
+ enum {maxTinyBuffers = 250000, maxSmallBuffers = 10000, maxMedBuffers = 1024};
private:
@@ -157,6 +968,17 @@ private:
/** Pointer to the data in the tiny pool */
void* tinyHeap;
+ Spinlock m_lock;
+
+ void lock() {
+ m_lock.lock();
+ }
+
+ void unlock() {
+ m_lock.unlock();
+ }
+
+#if 0 //-----------------------------------------------old mutex
# ifdef G3D_WIN32
CRITICAL_SECTION mutex;
# else
@@ -179,22 +1001,35 @@ private:
pthread_mutex_unlock(&mutex);
# endif
}
+#endif //-------------------------------------------old mutex
- /**
- Malloc out of the tiny heap.
+ /**
+ Malloc out of the tiny heap. Returns NULL if allocation failed.
*/
inline void* tinyMalloc(size_t bytes) {
// Note that we ignore the actual byte size
// and create a constant size block.
(void)bytes;
- debugAssert(tinyBufferSize >= bytes);
+ assert(tinyBufferSize >= bytes);
void* ptr = NULL;
if (tinyPoolSize > 0) {
--tinyPoolSize;
- // Return the last one
+
+ // Return the old last pointer from the freelist
ptr = tinyPool[tinyPoolSize];
+
+# ifdef G3D_DEBUG
+ if (tinyPoolSize > 0) {
+ assert(tinyPool[tinyPoolSize - 1] != ptr);
+ // "System::malloc heap corruption detected: "
+ // "the last two pointers on the freelist are identical (during tinyMalloc).");
+ }
+# endif
+
+ // NULL out the entry to help detect corruption
+ tinyPool[tinyPoolSize] = NULL;
}
return ptr;
@@ -202,12 +1037,26 @@ private:
/** Returns true if this is a pointer into the tiny heap. */
bool inTinyHeap(void* ptr) {
- return (ptr >= tinyHeap) &&
- (ptr < (uint8*)tinyHeap + maxTinyBuffers * tinyBufferSize);
+ return
+ (ptr >= tinyHeap) &&
+ (ptr < (uint8*)tinyHeap + maxTinyBuffers * tinyBufferSize);
}
void tinyFree(void* ptr) {
- debugAssert(tinyPoolSize < maxTinyBuffers);
+ assert(ptr);
+ assert(tinyPoolSize < maxTinyBuffers);
+ // "Tried to free a tiny pool buffer when the tiny pool freelist is full.");
+
+# ifdef G3D_DEBUG
+ if (tinyPoolSize > 0) {
+ void* prevOnHeap = tinyPool[tinyPoolSize - 1];
+ assert(prevOnHeap != ptr);
+// "System::malloc heap corruption detected: "
+// "the last two pointers on the freelist are identical (during tinyFree).");
+ }
+# endif
+
+ assert(tinyPool[tinyPoolSize] == NULL);
// Put the pointer back into the free list
tinyPool[tinyPoolSize] = ptr;
@@ -217,16 +1066,17 @@ private:
void flushPool(MemBlock* pool, int& poolSize) {
for (int i = 0; i < poolSize; ++i) {
- ::free(pool->ptr);
- pool->ptr = NULL;
- pool->bytes = 0;
+ ::free(pool[i].ptr);
+ pool[i].ptr = NULL;
+ pool[i].bytes = 0;
}
poolSize = 0;
}
- /** Allocate out of a specific pool-> Return NULL if no suitable
- memory was found.
+ /** Allocate out of a specific pool-> Return NULL if no suitable
+ memory was found.
+
*/
void* malloc(MemBlock* pool, int& poolSize, size_t bytes) {
@@ -260,13 +1110,13 @@ public:
int mallocsFromSmallPool;
int mallocsFromMedPool;
- /** Amount of memory currently allocated (according to the application).
+ /** Amount of memory currently allocated (according to the application).
This does not count the memory still remaining in the buffer pool,
but does count extra memory required for rounding off to the size
of a buffer.
Primarily useful for detecting leaks.*/
// TODO: make me an atomic int!
- int bytesAllocated;
+ volatile int bytesAllocated;
BufferPool() {
totalMallocs = 0;
@@ -284,6 +1134,7 @@ public:
medPoolSize = 0;
+
// Initialize the tiny heap as a bunch of pointers into one
// pre-allocated buffer.
tinyHeap = ::malloc(maxTinyBuffers * tinyBufferSize);
@@ -292,22 +1143,28 @@ public:
}
tinyPoolSize = maxTinyBuffers;
+#if 0 ///---------------------------------- old mutex
# ifdef G3D_WIN32
InitializeCriticalSection(&mutex);
# else
pthread_mutex_init(&mutex, NULL);
# endif
+#endif ///---------------------------------- old mutex
}
+
~BufferPool() {
::free(tinyHeap);
+#if 0 //-------------------------------- old mutex
# ifdef G3D_WIN32
DeleteCriticalSection(&mutex);
# else
// No destruction on pthreads
# endif
+#endif //--------------------------------old mutex
}
+
void* realloc(void* ptr, size_t bytes) {
if (ptr == NULL) {
return malloc(bytes);
@@ -319,7 +1176,7 @@ public:
return ptr;
} else {
// Free the old pointer and malloc
-
+
void* newPtr = malloc(bytes);
System::memcpy(newPtr, ptr, tinyBufferSize);
tinyFree(ptr);
@@ -330,7 +1187,7 @@ public:
// In one of our heaps.
// See how big the block really was
- size_t realSize = ((uint32*)ptr)[-1];
+ size_t realSize = *(uint32*)USERPTR_TO_REALPTR(ptr);
if (bytes <= realSize) {
// The old block was big enough.
return ptr;
@@ -344,6 +1201,7 @@ public:
}
}
+
void* malloc(size_t bytes) {
lock();
++totalMallocs;
@@ -358,12 +1216,12 @@ public:
return ptr;
}
- }
-
+ }
+
// Failure to allocate a tiny buffer is allowed to flow
// through to a small buffer
if (bytes <= smallBufferSize) {
-
+
void* ptr = malloc(smallPool, smallPoolSize, bytes);
if (ptr) {
@@ -372,7 +1230,7 @@ public:
return ptr;
}
- } else if (bytes <= medBufferSize) {
+ } else if (bytes <= medBufferSize) {
// Note that a small allocation failure does *not* fall
// through into a medium allocation because that would
// waste the medium buffer's resources.
@@ -382,54 +1240,63 @@ public:
if (ptr) {
++mallocsFromMedPool;
unlock();
+ debugAssertM(ptr != NULL, "BufferPool::malloc returned NULL");
return ptr;
}
}
- bytesAllocated += 4 + (int) bytes;
+ bytesAllocated += REALBLOCK_SIZE(bytes);
unlock();
// Heap allocate
// Allocate 4 extra bytes for our size header (unfortunate,
// since malloc already added its own header).
- void* ptr = ::malloc(bytes + 4);
+ void* ptr = ::malloc(REALBLOCK_SIZE(bytes));
if (ptr == NULL) {
// Flush memory pools to try and recover space
flushPool(smallPool, smallPoolSize);
flushPool(medPool, medPoolSize);
- ptr = ::malloc(bytes + 4);
+ ptr = ::malloc(REALBLOCK_SIZE(bytes));
}
if (ptr == NULL) {
- if ((System::outOfMemoryCallback != NULL) &&
- (System::outOfMemoryCallback(bytes + 4, true) == true)) {
+ if ((System::outOfMemoryCallback() != NULL) &&
+ (System::outOfMemoryCallback()(REALBLOCK_SIZE(bytes), true) == true)) {
// Re-attempt the malloc
- ptr = ::malloc(bytes + 4);
+ ptr = ::malloc(REALBLOCK_SIZE(bytes));
}
}
if (ptr == NULL) {
- if (System::outOfMemoryCallback != NULL) {
+ if (System::outOfMemoryCallback() != NULL) {
// Notify the application
- System::outOfMemoryCallback(bytes + 4, false);
+ System::outOfMemoryCallback()(REALBLOCK_SIZE(bytes), false);
}
+# ifdef G3D_DEBUG
+ debugPrintf("::malloc(%d) returned NULL\n", (int)REALBLOCK_SIZE(bytes));
+# endif
+ debugAssertM(ptr != NULL,
+ "::malloc returned NULL. Either the "
+ "operating system is out of memory or the "
+ "heap is corrupt.");
return NULL;
}
- *(uint32*)ptr = (uint32)bytes;
+ *(uint32*)ptr = bytes;
- return (uint8*)ptr + 4;
+ return REALPTR_TO_USERPTR(ptr);
}
+
void free(void* ptr) {
if (ptr == NULL) {
// Free does nothing on null pointers
return;
}
- debugAssert(isValidPointer(ptr));
+ assert(isValidPointer(ptr));
if (inTinyHeap(ptr)) {
lock();
@@ -438,7 +1305,7 @@ public:
return;
}
- uint32 bytes = ((uint32*)ptr)[-1];
+ uint32 bytes = *(uint32*)USERPTR_TO_REALPTR(ptr);
lock();
if (bytes <= smallBufferSize) {
@@ -456,17 +1323,17 @@ public:
return;
}
}
- bytesAllocated -= bytes + 4;
+ bytesAllocated -= REALBLOCK_SIZE(bytes);
unlock();
// Free; the buffer pools are full or this is too big to store.
- ::free((uint8*)ptr - 4);
+ ::free(USERPTR_TO_REALPTR(ptr));
}
std::string performance() const {
if (totalMallocs > 0) {
int pooled = mallocsFromTinyPool +
- mallocsFromSmallPool +
+ mallocsFromSmallPool +
mallocsFromMedPool;
int total = totalMallocs;
@@ -493,11 +1360,11 @@ public:
};
// Dynamically allocated because we need to ensure that
-// the buffer pool is still around when the last global variable
+// the buffer pool is still around when the last global variable
// is deallocated.
static BufferPool* bufferpool = NULL;
-std::string System::mallocPerformance() {
+std::string System::mallocPerformance() {
#ifndef NO_BUFFERPOOL
return bufferpool->performance();
#else
@@ -505,7 +1372,7 @@ std::string System::mallocPerformance() {
#endif
}
-std::string System::mallocStatus() {
+std::string System::mallocStatus() {
#ifndef NO_BUFFERPOOL
return bufferpool->status();
#else
@@ -513,6 +1380,7 @@ std::string System::mallocStatus() {
#endif
}
+
void System::resetMallocPerformanceCounters() {
#ifndef NO_BUFFERPOOL
bufferpool->totalMallocs = 0;
@@ -522,6 +1390,7 @@ void System::resetMallocPerformanceCounters() {
#endif
}
+
#ifndef NO_BUFFERPOOL
inline void initMem() {
// Putting the test here ensures that the system is always
@@ -534,6 +1403,7 @@ inline void initMem() {
}
#endif
+
void* System::malloc(size_t bytes) {
#ifndef NO_BUFFERPOOL
initMem();
@@ -546,6 +1416,8 @@ void* System::malloc(size_t bytes) {
void* System::calloc(size_t n, size_t x) {
#ifndef NO_BUFFERPOOL
void* b = System::malloc(n * x);
+ debugAssertM(b != NULL, "System::malloc returned NULL");
+ debugAssertM(isValidHeapPointer(b), "System::malloc returned an invalid pointer");
System::memset(b, 0, n * x);
return b;
#else
@@ -553,6 +1425,7 @@ void* System::calloc(size_t n, size_t x) {
#endif
}
+
void* System::realloc(void* block, size_t bytes) {
#ifndef NO_BUFFERPOOL
initMem();
@@ -562,6 +1435,7 @@ void* System::realloc(void* block, size_t bytes) {
#endif
}
+
void System::free(void* p) {
#ifndef NO_BUFFERPOOL
bufferpool->free(p);
@@ -570,80 +1444,303 @@ void System::free(void* p) {
#endif
}
+
void* System::alignedMalloc(size_t bytes, size_t alignment) {
+
alwaysAssertM(isPow2(alignment), "alignment must be a power of 2");
// We must align to at least a word boundary.
- alignment = iMax((int)alignment, sizeof(void *));
+ alignment = iMax(alignment, sizeof(void *));
// Pad the allocation size with the alignment size and the
// size of the redirect pointer.
- size_t totalBytes = bytes + alignment + sizeof(intptr_t);
+ size_t totalBytes = bytes + alignment + sizeof(void*);
- void* truePtr = System::malloc(totalBytes);
+ size_t truePtr = (size_t)System::malloc(totalBytes);
- if (!truePtr) {
+ if (truePtr == 0) {
// malloc returned NULL
return NULL;
}
- debugAssert(isValidHeapPointer(truePtr));
+ debugAssert(isValidHeapPointer((void*)truePtr));
#ifdef G3D_WIN32
// The blocks we return will not be valid Win32 debug heap
- // pointers because they are offset
- // debugAssert(_CrtIsValidPointer(truePtr, totalBytes, TRUE) );
+ // pointers because they are offset
+ // debugAssert(_CrtIsValidPointer((void*)truePtr, totalBytes, TRUE) );
#endif
// The return pointer will be the next aligned location (we must at least
// leave space for the redirect pointer, however).
- char* alignedPtr = ((char*)truePtr)+ sizeof(intptr_t);
+ size_t alignedPtr = truePtr + sizeof(void*);
-#if 0
// 2^n - 1 has the form 1111... in binary.
uint32 bitMask = (alignment - 1);
// Advance forward until we reach an aligned location.
- while ((((intptr_t)alignedPtr) & bitMask) != 0) {
+ while ((alignedPtr & bitMask) != 0) {
alignedPtr += sizeof(void*);
}
-#else
- alignedPtr += alignment - (((intptr_t)alignedPtr) & (alignment - 1));
- // assert((alignedPtr - truePtr) + bytes <= totalBytes);
-#endif
- debugAssert((alignedPtr - truePtr) + bytes <= totalBytes);
+ debugAssert(alignedPtr - truePtr + bytes <= totalBytes);
// Immediately before the aligned location, write the true array location
// so that we can free it correctly.
- intptr_t* redirectPtr = (intptr_t*)(alignedPtr - sizeof(intptr_t));
- redirectPtr[0] = (intptr_t)truePtr;
+ size_t* redirectPtr = (size_t *)(alignedPtr - sizeof(void *));
+ redirectPtr[0] = truePtr;
- debugAssert(isValidHeapPointer(truePtr));
+ debugAssert(isValidHeapPointer((void*)truePtr));
#ifdef G3D_WIN32
- debugAssert( _CrtIsValidPointer(alignedPtr, bytes, TRUE) );
+ debugAssert( _CrtIsValidPointer((void*)alignedPtr, bytes, TRUE) );
#endif
- return (void*)alignedPtr;
+ return (void *)alignedPtr;
}
+
void System::alignedFree(void* _ptr) {
if (_ptr == NULL) {
return;
}
- char* alignedPtr = (char*)_ptr;
+ size_t alignedPtr = (size_t)_ptr;
// Back up one word from the pointer the user passed in.
// We now have a pointer to a pointer to the true start
// of the memory block.
- intptr_t* redirectPtr = (intptr_t*)(alignedPtr - sizeof(intptr_t));
+ size_t* redirectPtr = (size_t*)(alignedPtr - sizeof(void *));
// Dereference that pointer so that ptr = true start
- void* truePtr = (void*)(redirectPtr[0]);
+ void* truePtr = (void*)redirectPtr[0];
- debugAssert(isValidHeapPointer(truePtr));
+ debugAssert(isValidHeapPointer((void*)truePtr));
System::free(truePtr);
}
-} // namespace
+void System::setEnv(const std::string& name, const std::string& value) {
+ std::string cmd = name + "=" + value;
+# ifdef G3D_WIN32
+ _putenv(cmd.c_str());
+# else
+ // Many linux implementations of putenv expect char*
+ putenv(const_cast<char*>(cmd.c_str()));
+# endif
+}
+
+
+const char* System::getEnv(const std::string& name) {
+ return getenv(name.c_str());
+}
+
+
+static void var(TextOutput& t, const std::string& name, const std::string& val) {
+ t.writeSymbols(name,"=");
+ t.writeString(val);
+ t.writeNewline();
+}
+
+
+static void var(TextOutput& t, const std::string& name, const bool val) {
+ t.writeSymbols(name, "=", val ? "Yes" : "No");
+ t.writeNewline();
+}
+
+
+static void var(TextOutput& t, const std::string& name, const int val) {
+ t.writeSymbols(name,"=");
+ t.writeNumber(val);
+ t.writeNewline();
+}
+
+
+void System::describeSystem(
+ std::string& s) {
+
+ TextOutput t;
+ describeSystem(t);
+ t.commitString(s);
+}
+
+void System::describeSystem(
+ TextOutput& t) {
+
+ t.writeSymbols("App", "{");
+ t.writeNewline();
+ t.pushIndent();
+ {
+ var(t, "Name", System::currentProgramFilename());
+ char cwd[1024];
+ getcwd(cwd, 1024);
+ var(t, "cwd", std::string(cwd));
+ }
+ t.popIndent();
+ t.writeSymbols("}");
+ t.writeNewline();
+ t.writeNewline();
+
+ t.writeSymbols("OS", "{");
+ t.writeNewline();
+ t.pushIndent();
+ {
+ var(t, "Name", System::operatingSystem());
+ }
+ t.popIndent();
+ t.writeSymbols("}");
+ t.writeNewline();
+ t.writeNewline();
+
+ t.writeSymbols("CPU", "{");
+ t.writeNewline();
+ t.pushIndent();
+ {
+ var(t, "Vendor", System::cpuVendor());
+ var(t, "Architecture", System::cpuArchitecture());
+ var(t, "hasCPUID", System::hasCPUID());
+ var(t, "hasMMX", System::hasMMX());
+ var(t, "hasSSE", System::hasSSE());
+ var(t, "hasSSE2", System::hasSSE2());
+ var(t, "hasSSE3", System::hasSSE3());
+ var(t, "has3DNow", System::has3DNow());
+ var(t, "hasRDTSC", System::hasRDTSC());
+ var(t, "numCores", System::numCores());
+ }
+ t.popIndent();
+ t.writeSymbols("}");
+ t.writeNewline();
+ t.writeNewline();
+
+ t.writeSymbols("G3D", "{");
+ t.writeNewline();
+ t.pushIndent();
+ {
+ var(t, "Link version", G3D_VER);
+ var(t, "Compile version", System::version());
+ }
+ t.popIndent();
+ t.writeSymbols("}");
+ t.writeNewline();
+ t.writeNewline();
+}
+
+
+void System::setClipboardText(const std::string& s) {
+# ifdef G3D_WIN32
+ if (OpenClipboard(NULL)) {
+ HGLOBAL hMem = GlobalAlloc(GHND | GMEM_DDESHARE, s.size() + 1);
+ if (hMem) {
+ char *pMem = (char*)GlobalLock(hMem);
+ strcpy(pMem, s.c_str());
+ GlobalUnlock(hMem);
+
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT, hMem);
+ }
+
+ CloseClipboard();
+ GlobalFree(hMem);
+ }
+# endif
+}
+
+
+std::string System::getClipboardText() {
+ std::string s;
+
+# ifdef G3D_WIN32
+ if (OpenClipboard(NULL)) {
+ HANDLE h = GetClipboardData(CF_TEXT);
+
+ if (h) {
+ char* temp = (char*)GlobalLock(h);
+ if (temp) {
+ s = temp;
+ }
+ temp = NULL;
+ GlobalUnlock(h);
+ }
+ CloseClipboard();
+ }
+# endif
+ return s;
+}
+
+
+std::string System::currentDateString() {
+ time_t t1;
+ ::time(&t1);
+ tm* t = localtime(&t1);
+ return format("%d-%02d-%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
+}
+
+#ifdef _MSC_VER
+
+// VC on Intel
+void System::cpuid(CPUIDFunction func, uint32& areg, uint32& breg, uint32& creg, uint32& dreg) {
+#if !defined(G3D_64BIT)
+ // Can't copy from assembler direct to a function argument (which is on the stack) in VC.
+ uint32 a,b,c,d;
+
+ // Intel assembler syntax
+ __asm {
+ mov eax, func // eax <- func
+ mov ecx, 0
+ cpuid
+ mov a, eax
+ mov b, ebx
+ mov c, ecx
+ mov d, edx
+ }
+ areg = a;
+ breg = b;
+ creg = c;
+ dreg = d;
+#else
+ int CPUInfo[4];
+ __cpuid(CPUInfo, func);
+ memcpy(&areg, &CPUInfo[0], 4);
+ memcpy(&breg, &CPUInfo[1], 4);
+ memcpy(&creg, &CPUInfo[2], 4);
+ memcpy(&dreg, &CPUInfo[3], 4);
+#endif
+}
+
+#elif defined(G3D_OSX) && ! defined(G3D_OSX_INTEL)
+
+// non-intel OS X; no CPUID
+void System::cpuid(CPUIDFunction func, uint32& eax, uint32& ebx, uint32& ecx, uint32& edx) {
+ eax = 0;
+ ebx = 0;
+ ecx = 0;
+ edx = 0;
+}
+
+#else
+
+// See http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well
+// for a discussion of why the second version saves ebx; it allows 32-bit code to compile with the -fPIC option.
+// On 64-bit x86, PIC code has a dedicated rip register for PIC so there is no ebx conflict.
+void System::cpuid(CPUIDFunction func, uint32& eax, uint32& ebx, uint32& ecx, uint32& edx) {
+#if ! defined(__PIC__) || defined(__x86_64__)
+ // AT&T assembler syntax
+ asm volatile(
+ "movl $0, %%ecx \n\n" /* Wipe ecx */
+ "cpuid \n\t"
+ : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+ : "a"(func));
+#else
+ // AT&T assembler syntax
+ asm volatile(
+ "pushl %%ebx \n\t" /* save ebx */
+ "movl $0, %%ecx \n\n" /* Wipe ecx */
+ "cpuid \n\t"
+ "movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */
+ "popl %%ebx \n\t" /* restore the old ebx */
+ : "=a"(eax), "=r"(ebx), "=c"(ecx), "=d"(edx)
+ : "a"(func));
+#endif
+}
+
+#endif
+
+} // namespace
diff --git a/dep/src/g3dlite/TextInput.cpp b/dep/src/g3dlite/TextInput.cpp
new file mode 100644
index 00000000000..7276d8c66b2
--- /dev/null
+++ b/dep/src/g3dlite/TextInput.cpp
@@ -0,0 +1,1136 @@
+/**
+ @file TextInput.cpp
+
+ @author Morgan McGuire, graphics3d.com
+
+ @cite Based on a lexer written by Aaron Orenstein.
+
+ @created 2001-11-27
+ @edited 2008-07-14
+ */
+
+#include "G3D/fileutils.h"
+#include "G3D/TextInput.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/stringutils.h"
+
+#ifdef _MSC_VER
+# pragma warning (push)
+// conversion from 'int' to 'char', possible loss of data (TODO: fix underlying problems)
+# pragma warning (disable: 4244)
+#endif
+
+namespace G3D {
+
+Token TextInput::readSignificant() {
+ Token t;
+ do {
+ t = read();
+ } while ((t.type() == Token::COMMENT) || (t.type() == Token::NEWLINE));
+ return t;
+}
+
+
+double Token::number() const {
+ if (_type == NUMBER) {
+ std::string s = toLower(_string);
+ if (s == "-1.#ind00") {
+ return nan();
+ }
+
+ if (s == "1.#inf00") {
+ return inf();
+ }
+
+ if (s == "-1.#inf00") {
+ return -inf();
+ }
+
+ double n;
+ if ((_string.length() > 2) &&
+ (_string[0] == '0') &&
+ (_string[1] == 'x')) {
+ // Hex
+ uint32 i;
+ sscanf(_string.c_str(), "%x", &i);
+ n = i;
+ } else {
+ sscanf(_string.c_str(), "%lg", &n);
+ }
+ return n;
+ } else {
+ return 0.0;
+ }
+}
+
+
+TextInput::Settings::Settings () :
+ cppBlockComments(true),
+ cppLineComments(true),
+ otherLineComments(true),
+ escapeSequencesInStrings(true),
+ otherCommentCharacter('\0'),
+ otherCommentCharacter2('\0'),
+ generateCommentTokens(false),
+ generateNewlineTokens(false),
+ signedNumbers(true),
+ singleQuotedStrings(true),
+ singleQuoteCharacter('\''),
+ sourceFileName(),
+ startingLineNumberOffset(0),
+ msvcSpecials(true),
+ proofSymbols(false),
+ caseSensitive(true)
+{
+ trueSymbols.insert("true");
+ falseSymbols.insert("false");
+}
+
+
+Token TextInput::peek() {
+ if (stack.size() == 0) {
+ Token t = nextToken();
+ push(t);
+ }
+
+ return stack.front();
+}
+
+
+int TextInput::peekLineNumber() {
+ return peek().line();
+}
+
+
+int TextInput::peekCharacterNumber() {
+ return peek().character();
+}
+
+
+Token TextInput::read() {
+ if (stack.size() > 0) {
+ Token t = stack.front();
+ stack.pop_front();
+ return t;
+ } else {
+ return nextToken();
+ }
+}
+
+static void toUpper(Set<std::string>& set) {
+ Array<std::string> symbols;
+ set.getMembers(symbols);
+ set.clear();
+ for (int i = 0; i < symbols.size(); ++i) {
+ set.insert(toUpper(symbols[i]));
+ }
+}
+
+void TextInput::init() {
+ currentCharOffset = 0;
+ charNumber = 1;
+ lineNumber = 1 + options.startingLineNumberOffset;
+
+ if (! options.caseSensitive) {
+ // Convert true and false symbols to all uppercase for fast comparisons
+ toUpper(options.trueSymbols);
+ toUpper(options.falseSymbols);
+ }
+}
+
+
+void TextInput::push(const Token& t) {
+ stack.push_front(t);
+}
+
+
+bool TextInput::hasMore() {
+ return (peek()._type != Token::END);
+}
+
+
+int TextInput::eatInputChar() {
+ // Don't go off the end
+ if (currentCharOffset >= buffer.length()) {
+ return EOF;
+ }
+
+ unsigned char c = buffer[currentCharOffset];
+ ++currentCharOffset;
+
+ // update lineNumber and charNumber to reflect the location of the *next*
+ // character which will be read.
+
+ // increment line number for \r, \n and \r\n which matches Token::NEWLINE parsing
+ if (c == '\r') {
+ ++lineNumber;
+ charNumber = 1;
+
+ // check for \r\n
+ if (currentCharOffset < buffer.length()) {
+ unsigned char c2 = buffer[currentCharOffset];
+ if (c2 == '\n') {
+ c = c2;
+ ++currentCharOffset;
+ }
+ }
+ } else if (c == '\n') {
+ ++lineNumber;
+ charNumber = 1;
+ } else {
+ ++charNumber;
+ }
+
+ return c;
+}
+
+int TextInput::peekInputChar(int distance) {
+ // Don't go off the end
+ if ((currentCharOffset + distance) >= buffer.length()) {
+ return EOF;
+ }
+
+ unsigned char c = buffer[currentCharOffset + distance];
+ return c;
+}
+
+
+Token TextInput::nextToken() {
+ Token t;
+
+ t._line = lineNumber;
+ t._character = charNumber;
+ t._type = Token::END;
+ t._extendedType = Token::END_TYPE;
+
+ int c = peekInputChar();
+ if (c == EOF) {
+ return t;
+ }
+
+ // loop through white space, newlines and comments
+ // found before other tokens
+ bool whitespaceDone = false;
+ while (! whitespaceDone) {
+ whitespaceDone = true;
+
+ // generate newlines tokens for '\n' and '\r' and '\r\n'
+ if (options.generateNewlineTokens && isNewline(c)) {
+ t._type = Token::NEWLINE;
+ t._extendedType = Token::NEWLINE_TYPE;
+ t._string = c;
+
+ int c2 = peekInputChar(1);
+ if (c == '\r' && c2 == '\n') {
+ t._string += c2;
+ }
+
+ eatInputChar();
+ return t;
+ } else {
+ // Consume whitespace
+ while (isWhiteSpace(c)) {
+ c = eatAndPeekInputChar();
+ }
+ }
+
+ // update line and character number to include discarded whitespace
+ t._line = lineNumber;
+ t._character = charNumber;
+
+ int c2 = peekInputChar(1);
+
+ // parse comments and generate tokens if enabled
+ std::string commentString;
+
+ // check for line comments first
+ bool isLineComment = false;
+ if (options.cppLineComments && (c == '/' && c2 == '/')) {
+ // set start of line comment and eat markers
+ isLineComment = true;
+ eatInputChar();
+ eatInputChar();
+ } else if ( options.otherCommentCharacter &&
+ (options.otherCommentCharacter != '\0' && c == options.otherCommentCharacter) ) {
+ // set start of line comment and eat markers
+ isLineComment = true;
+ eatInputChar();
+ } else if ( options.otherCommentCharacter &&
+ (options.otherCommentCharacter2 != '\0' && c == options.otherCommentCharacter2) ) {
+ // set start of line comment and eat markers
+ isLineComment = true;
+ eatInputChar();
+ }
+
+ if (isLineComment) {
+
+ // consume line comment to newline or EOF
+ c = peekInputChar();
+ while (! isNewline(c) && c != EOF) {
+ // build comment string for token
+ commentString += c;
+
+ c = eatAndPeekInputChar();
+ }
+
+ if (options.generateCommentTokens) {
+ t._type = Token::COMMENT;
+ t._extendedType = Token::LINE_COMMENT_TYPE;
+ t._string = commentString;
+ return t;
+ } else {
+ // There is whitespace after the comment (in particular, the
+ // newline that terminates the comment). There might also be
+ // whitespace at the start of the next line.
+ whitespaceDone = false;
+ }
+
+ } else if (options.cppBlockComments && (c == '/' && c2 == '*')) {
+ // consume block comment to end-marker or EOF
+
+ // consume both start-comment chars, can't let the trailing one
+ // help close the comment.
+ eatInputChar();
+ eatInputChar();
+
+ c = peekInputChar();
+ c2 = peekInputChar(1);
+ while (! ((c == '*') && (c2 == '/')) && (c != EOF)) {
+ commentString += c;
+
+ eatInputChar();
+ c = c2;
+ c2 = peekInputChar(1);
+ }
+ eatInputChar(); // eat closing '*'
+ eatInputChar(); // eat closing '/'
+
+ c = peekInputChar();
+
+ if (options.generateCommentTokens) {
+ t._type = Token::COMMENT;
+ t._extendedType = Token::BLOCK_COMMENT_TYPE;
+ t._string = commentString;
+ return t;
+ } else {
+ // There is whitespace after the comment (in particular, the
+ // newline that terminates the comment). There might also be
+ // whitespace at the start of the next line.
+ whitespaceDone = false;
+ }
+ }
+
+ } // while (! whitespaceDone)
+
+ t._line = lineNumber;
+ t._character = charNumber;
+
+ // handle EOF
+ if (c == EOF) {
+ return t;
+ }
+
+ // Extended ASCII parses as itself, except for EOF
+ if (c > 127 && c < 255) {
+ t._type = Token::SYMBOL;
+ t._extendedType = Token::SYMBOL_TYPE;
+ t._string = c;
+ c = eatAndPeekInputChar();
+ }
+
+
+ // Perform appropriate setup for a symbol (including setting up the token
+ // string to start with c), eat the input character, and overwrite
+ // 'c' with the peeked next input character.
+#define SETUP_SYMBOL(c) \
+ { \
+ t._type = Token::SYMBOL; \
+ t._extendedType = Token::SYMBOL_TYPE; \
+ t._string = c; \
+ c = eatAndPeekInputChar(); \
+ }
+
+ switch (c) {
+
+ case '@': // Simple symbols -> just themselves.
+ case '(':
+ case ')':
+ case ',':
+ case ';':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case '#':
+ case '$':
+ case '?':
+ case '%':
+ SETUP_SYMBOL(c);
+ return t;
+
+ case '-': // negative number, -, --, -=, or ->
+ SETUP_SYMBOL(c);
+
+ switch (c) {
+ case '>': // ->
+ case '-': // --
+ case '=': // -=
+ t._string += c;
+ eatInputChar();
+ return t;
+ }
+
+ if (options.signedNumbers
+ && (isDigit(c) || (c == '.' && isDigit(peekInputChar(1))))) {
+
+ // Negative number. 'c' is still the first digit, and is
+ // the next input char.
+
+ goto numLabel;
+ }
+
+ // plain -
+ return t;
+
+ case '+': // positive number, +, ++, or +=
+ SETUP_SYMBOL(c);
+
+ switch (c) {
+ case '+': // ++
+ case '=': // +=
+ t._string += c;
+ eatInputChar();
+ return t;
+ }
+
+ if (options.signedNumbers
+ && (isDigit(c) || (c == '.' && isDigit(peekInputChar(1))))) {
+
+ // Positive number. 'c' is still the first digit, and is
+ // the next input char.
+
+ goto numLabel;
+ }
+
+ return t;
+
+ case ':': // : or :: or ::> or ::= or := or :>
+ SETUP_SYMBOL(c);
+
+ if (c == ':') {
+ t._string += c;
+ eatInputChar();
+
+ if (options.proofSymbols) {
+ c = peekInputChar(0);
+
+ if ((c == '>') || (c == '=')) {
+ t._string += c;
+ eatInputChar();
+ }
+ }
+ }
+ else if (options.proofSymbols && (c == '=' || c == '>')) {
+ t._string += c;
+ eatInputChar();
+ }
+ return t;
+
+ case '=': // = or == or =>
+ SETUP_SYMBOL(c);
+
+ if (c == '=') {
+ t._string += c;
+ eatInputChar();
+ return t;
+ } else if (options.proofSymbols && (c == '>')) {
+ t._string += c;
+ eatInputChar();
+ return t;
+ }
+ return t;
+
+ case '*': // * or *=
+ case '/': // / or /=
+ case '!': // ! or !=
+ case '~': // ~ or ~=
+ case '^': // ^ or ^=
+ SETUP_SYMBOL(c);
+
+ if (c == '=') {
+ t._string += c;
+ eatInputChar();
+ return t;
+ }
+ return t;
+
+ case '>': // >, >>,or >=
+ case '<': // <<, <<, or <= or <- or <:
+ case '|': // ||, ||, or |= or |-
+ case '&': // &, &&, or &=
+ {
+ int orig_c = c;
+ SETUP_SYMBOL(c);
+
+ if ((c == '=') || (orig_c == c)) {
+ t._string += c;
+ eatInputChar();
+ return t;
+ } else if (options.proofSymbols) {
+ if ((orig_c == '<') && (c == '-')) {
+ t._string += c;
+ eatInputChar();
+ } else if ((orig_c == '|') && (c == '-')) {
+ t._string += c;
+ eatInputChar();
+ } else if ((orig_c == '<') && (c == ':')) {
+ t._string += c;
+
+ c = eatAndPeekInputChar();
+
+ if (c == ':') {
+ t._string += c;
+ eatInputChar();
+ }
+ }
+ }
+ }
+ return t;
+
+ case '\\': // backslash or escaped comment char.
+ SETUP_SYMBOL(c);
+
+ if ((options.otherCommentCharacter != '\0'
+ && c == options.otherCommentCharacter)
+ || (options.otherCommentCharacter2 != '\0'
+ && c == options.otherCommentCharacter2)) {
+
+ // escaped comment character. Return the raw comment
+ // char (no backslash).
+
+ t._string = c;
+ eatInputChar();
+ return t;
+ }
+ return t;
+
+ case '.': // number, ., .., or ...
+ if (isDigit(peekInputChar(1))) {
+ // We're parsing a float that began without a leading zero
+ goto numLabel;
+ }
+
+ SETUP_SYMBOL(c);
+
+ if (c == '.') { // .. or ...
+ t._string += c;
+ c = eatAndPeekInputChar();
+
+ if (c == '.') { // ...
+ t._string += c;
+ eatInputChar();
+ }
+ return t;
+ }
+
+ return t;
+
+ } // switch (c)
+
+#undef SETUP_SYMBOL
+
+numLabel:
+ if (isDigit(c) || (c == '.')) {
+
+ // A number. Note-- single dots have been
+ // parsed already, so a . indicates a number
+ // less than 1 in floating point form.
+
+ // [0-9]*(\.[0-9][f]) or [0-9]+ or 0x[0-9,A-F]+
+
+ if (t._string != "-") {
+ // If we picked up a leading "-" sign above, keep it,
+ // otherwise drop the string parsed thus far
+ t._string = "";
+ }
+ t._type = Token::NUMBER;
+ if (c == '.') {
+ t._extendedType = Token::FLOATING_POINT_TYPE;
+ } else {
+ t._extendedType = Token::INTEGER_TYPE;
+ }
+
+ if ((c == '0') && (peekInputChar(1) == 'x')) {
+ // Hex number
+ t._string += "0x";
+
+ // skip the 0x
+ eatInputChar();
+ eatInputChar();
+
+ c = peekInputChar();
+ while (isDigit(c) || ((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f'))) {
+ t._string += c;
+ c = eatAndPeekInputChar();
+ }
+
+ } else {
+ // Non-hex number
+
+ // Read the part before the decimal.
+ while (isDigit(c)) {
+ t._string += c;
+ c = eatAndPeekInputChar();
+ }
+
+ // True if we are reading a floating-point special type
+ bool isSpecial = false;
+
+ // Read the decimal, if one exists
+ if (c == '.') {
+ t._extendedType = Token::FLOATING_POINT_TYPE;
+
+ // The '.' character was a decimal point, not the start of a
+ // method or range operator
+ t._string += c;
+ c = eatAndPeekInputChar();
+
+ // Floating point specials (msvc format only)
+ if (options.msvcSpecials && (c == '#')) {
+ isSpecial = true;
+ // We are reading a floating point special value
+ // of the form -1.#IND00, -1.#INF00, or 1.#INF00
+ c = eatAndPeekInputChar();
+ char test = c;
+ if (! options.caseSensitive) {
+ test = toupper(c);
+ }
+ if (test != 'I') {
+ throw BadMSVCSpecial
+ (
+ "Incorrect floating-point special (inf or nan) "
+ "format.",
+ t.line(), charNumber);
+ }
+ c = eatAndPeekInputChar();
+ test = c;
+ if (! options.caseSensitive) {
+ test = toupper(c);
+ }
+ if (test != 'N') {
+ throw BadMSVCSpecial
+ (
+ "Incorrect floating-point special (inf or nan) "
+ "format.",
+ t.line(), charNumber);
+ }
+ t._string += "#IN";
+ c = eatAndPeekInputChar();
+ test = c;
+ if (! options.caseSensitive) {
+ test = toupper(c);
+ }
+ if ((test != 'F') && (test != 'D')) {
+ throw BadMSVCSpecial
+ (
+ "Incorrect floating-point special (inf or nan) "
+ "format.",
+ t.line(), charNumber);
+ }
+ t._string += c;
+ for (int j = 0; j < 2; ++j) {
+ c = eatAndPeekInputChar();
+ if (c != '0') {
+ throw BadMSVCSpecial
+ (
+ "Incorrect floating-point special (inf or"
+ "nan) format.",
+ t.line(), charNumber);
+ }
+ t._string += (char)c;
+ }
+
+ } else {
+
+ // Read the part after the decimal
+ while (isDigit((char)c)) {
+ t._string += (char)c;
+ c = eatAndPeekInputChar();
+ }
+ }
+ }
+
+ if (! isSpecial && ((c == 'e') || (c == 'E'))) {
+ // Read exponent
+ t._extendedType = Token::FLOATING_POINT_TYPE;
+ t._string += c;
+
+ c = eatAndPeekInputChar();
+ if ((c == '-') || (c == '+')) {
+ t._string += c;
+ c = eatAndPeekInputChar();
+ }
+
+ while (isDigit(c)) {
+ t._string += c;
+ c = eatAndPeekInputChar();
+ }
+ }
+
+ if (! isSpecial && (t._extendedType == Token::FLOATING_POINT_TYPE) && (c == 'f')) {
+ // Trailing f on a float
+ t._string += c;
+ c = eatAndPeekInputChar();
+ }
+ }
+ return t;
+
+ } else if (isLetter(c) || (c == '_')) {
+ // Identifier or keyword
+ // [A-Za-z_][A-Za-z_0-9]*
+
+ t._type = Token::SYMBOL;
+ t._extendedType = Token::SYMBOL_TYPE;
+ t._string = "";
+ do {
+ t._string += c;
+ c = eatAndPeekInputChar();
+ } while (isLetter(c) || isDigit(c) || (c == '_'));
+
+ // See if this symbol is actually a boolean
+ if ((options.trueSymbols.size() > 0) || (options.falseSymbols.size() > 0)) {
+ std::string str = t._string;
+ if (! options.caseSensitive) {
+ str = toUpper(str);
+ }
+ if (options.trueSymbols.contains(str)) {
+ t._type = Token::BOOLEAN;
+ t._extendedType = Token::BOOLEAN_TYPE;
+ t._bool = true;
+ } else if (options.falseSymbols.contains(str)) {
+ t._type = Token::BOOLEAN;
+ t._extendedType = Token::BOOLEAN_TYPE;
+ t._bool = false;
+ }
+ }
+
+ return t;
+
+ } else if (c == '\"') {
+
+ // Discard the double-quote.
+ eatInputChar();
+
+ // Double quoted string
+ parseQuotedString('\"', t);
+ return t;
+
+ } else if (c == options.singleQuoteCharacter) {
+
+ // Discard the single-quote.
+ eatInputChar();
+
+ if (options.singleQuotedStrings) {
+ // Single quoted string
+ parseQuotedString(options.singleQuoteCharacter, t);
+ } else {
+ t._string = c;
+ t._type = Token::SYMBOL;
+ t._extendedType = Token::SYMBOL_TYPE;
+ }
+ return t;
+
+ } // end of special case tokens
+
+ if (c == EOF) {
+ t._type = Token::END;
+ t._extendedType = Token::END_TYPE;
+ t._string = "";
+ return t;
+ }
+
+ // Some unknown token
+ debugAssertM(false,
+ format("Unrecognized token type beginning with character '%c' (ASCII %d)",
+ c, c));
+ return t;
+}
+
+
+void TextInput::parseQuotedString(unsigned char delimiter, Token& t) {
+
+ t._type = Token::STRING;
+
+ if (delimiter == options.singleQuoteCharacter) {
+ t._extendedType = Token::SINGLE_QUOTED_TYPE;
+ } else {
+ t._extendedType = Token::DOUBLE_QUOTED_TYPE;
+ }
+
+ while (true) {
+ // We're definitely going to consume the next input char, so we get
+ // it right now. This makes the condition handling below a bit easier.
+ int c = eatInputChar();
+
+ if (c == EOF) {
+ // END inside a quoted string. (We finish the string.)
+ break;
+ }
+
+ if (options.escapeSequencesInStrings && (c == '\\')) {
+ // An escaped character. We're definitely going to consume it,
+ // so we get it (and consume it) now.
+
+ c = eatInputChar();
+
+ switch (c) {
+ case 'r':
+ t._string += '\r';
+ break;
+ case 'n':
+ t._string += '\n';
+ break;
+ case 't':
+ t._string += '\t';
+ break;
+ case '0':
+ t._string += '\0';
+ break;
+
+ case '\\':
+ case '\"':
+ t._string += (char)c;
+ break;
+
+ default:
+ if (c == options.singleQuoteCharacter) {
+ t._string += (char)c;
+ break;
+ }
+
+ if (((c == options.otherCommentCharacter) &&
+ (options.otherCommentCharacter != '\0')) ||
+ ((c == options.otherCommentCharacter2) &&
+ (options.otherCommentCharacter2 != '\0'))) {
+ t._string += c;
+ }
+ // otherwise, some illegal escape sequence; skip it.
+ break;
+
+ } // switch
+
+ } else if (c == delimiter) {
+ // End of the string. Already consumed the character.
+ break;
+ } else {
+ // All other chars, go on to the string. Already consumed the
+ // character.
+ t._string += (char)c;
+ }
+
+ }
+}
+
+bool TextInput::readBoolean() {
+ Token t(read());
+
+ if (t._type == Token::BOOLEAN) {
+ return t.boolean();
+ }
+
+ // Push initial token back, and throw an error. We intentionally
+ // indicate that the wrong type is the type of the initial token.
+ // Logically, the number started there.
+ push(t);
+ throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
+ Token::BOOLEAN, t._type);
+}
+
+double TextInput::readNumber() {
+ Token t(read());
+
+ if (t._type == Token::NUMBER) {
+ return t.number();
+ }
+
+ // Even if signedNumbers is disabled, readNumber attempts to
+ // read a signed number, so we handle that case here.
+ if (! options.signedNumbers
+ && (t._type == Token::SYMBOL)
+ && ((t._string == "-")
+ || (t._string == "+"))) {
+
+ Token t2(read());
+
+ if ((t2._type == Token::NUMBER)
+ && (t2._character == t._character + 1)) {
+
+ if (t._string == "-") {
+ return -t2.number();
+ } else {
+ return t2.number();
+ }
+ }
+
+ // push back the second token.
+ push(t2);
+ }
+
+ // Push initial token back, and throw an error. We intentionally
+ // indicate that the wrong type is the type of the initial token.
+ // Logically, the number started there.
+ push(t);
+ throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
+ Token::NUMBER, t._type);
+}
+
+
+Token TextInput::readStringToken() {
+ Token t(read());
+
+ if (t._type == Token::STRING) { // fast path
+ return t;
+ }
+
+ push(t);
+ throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
+ Token::STRING, t._type);
+}
+
+std::string TextInput::readString() {
+ return readStringToken()._string;
+}
+
+void TextInput::readString(const std::string& s) {
+ Token t(readStringToken());
+
+ if (t._string == s) { // fast path
+ return;
+ }
+
+ push(t);
+ throw WrongString(options.sourceFileName, t.line(), t.character(),
+ s, t._string);
+}
+
+Token TextInput::readCommentToken() {
+ Token t(read());
+
+ if (t._type == Token::COMMENT) { // fast path
+ return t;
+ }
+
+ push(t);
+ throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
+ Token::COMMENT, t._type);
+}
+
+std::string TextInput::readComment() {
+ return readCommentToken()._string;
+}
+
+void TextInput::readComment(const std::string& s) {
+ Token t(readCommentToken());
+
+ if (t._string == s) { // fast path
+ return;
+ }
+
+ push(t);
+ throw WrongString(options.sourceFileName, t.line(), t.character(),
+ s, t._string);
+}
+
+Token TextInput::readNewlineToken() {
+ Token t(read());
+
+ if (t._type == Token::NEWLINE) { // fast path
+ return t;
+ }
+
+ push(t);
+ throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
+ Token::NEWLINE, t._type);
+}
+
+std::string TextInput::readNewline() {
+ return readNewlineToken()._string;
+}
+
+void TextInput::readNewline(const std::string& s) {
+ Token t(readNewlineToken());
+
+ if (t._string == s) { // fast path
+ return;
+ }
+
+ push(t);
+ throw WrongString(options.sourceFileName, t.line(), t.character(),
+ s, t._string);
+}
+
+Token TextInput::readSymbolToken() {
+ Token t(read());
+
+ if (t._type == Token::SYMBOL) { // fast path
+ return t;
+ }
+
+ push(t);
+ throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
+ Token::SYMBOL, t._type);
+}
+
+
+std::string TextInput::readSymbol() {
+ return readSymbolToken()._string;
+}
+
+void TextInput::readSymbol(const std::string& symbol) {
+ Token t(readSymbolToken());
+
+ if (t._string == symbol) { // fast path
+ return;
+ }
+
+ push(t);
+ throw WrongSymbol(options.sourceFileName, t.line(), t.character(),
+ symbol, t._string);
+}
+
+
+TextInput::TextInput(const std::string& filename, const Settings& opt) : options(opt) {
+ init();
+ std::string input = readWholeFile(filename);
+
+ if (options.sourceFileName.empty()) {
+ options.sourceFileName = filename;
+ }
+ int n = input.size();
+ buffer.resize(n);
+ System::memcpy(buffer.getCArray(), input.c_str(), n);
+}
+
+
+TextInput::TextInput(FS fs, const std::string& str, const Settings& opt) : options(opt) {
+ (void)fs;
+ init();
+ if (options.sourceFileName.empty()) {
+ if (str.length() < 14) {
+ options.sourceFileName = std::string("\"") + str + "\"";
+ } else {
+ options.sourceFileName = std::string("\"") + str.substr(0, 10) + "...\"";
+ }
+ }
+ buffer.resize(str.length()); // we don't bother copying trailing NUL.
+ System::memcpy(buffer.getCArray(), str.c_str(), buffer.size());
+}
+
+
+const std::string& TextInput::filename() const {
+ return options.sourceFileName;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+
+TextInput::TokenException::TokenException(
+ const std::string& src,
+ int ln,
+ int ch) : ParseError(src, ln, ch, format("%s(%d) : ", src.c_str(), ln)),
+ sourceFile(src) {
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+
+static const char* tokenTypeToString(Token::Type t) {
+ switch (t) {
+ case Token::SYMBOL:
+ return "Token::SYMBOL";
+ case Token::STRING:
+ return "Token::STRING";
+ case Token::NUMBER:
+ return "Token::NUMBER";
+ case Token::END:
+ return "Token::END";
+ default:
+ debugAssertM(false, "Fell through switch");
+ return "?";
+ }
+}
+
+TextInput::WrongTokenType::WrongTokenType(
+ const std::string& src,
+ int ln,
+ int ch,
+ Token::Type e,
+ Token::Type a) :
+ TokenException(src, ln, ch), expected(e), actual(a) {
+
+ message += format("Expected token of type %s, found type %s.",
+ tokenTypeToString(e), tokenTypeToString(a));
+}
+
+
+TextInput::BadMSVCSpecial::BadMSVCSpecial(
+ const std::string& src,
+ int ln,
+ int ch) :
+ TokenException(src, ln, ch) {
+}
+
+
+TextInput::WrongSymbol::WrongSymbol(
+ const std::string& src,
+ int ln,
+ int ch,
+ const std::string& e,
+ const std::string& a) :
+ TokenException(src, ln, ch), expected(e), actual(a) {
+
+ message += format("Expected symbol '%s', found symbol '%s'.",
+ e.c_str(), a.c_str());
+}
+
+
+TextInput::WrongString::WrongString(
+ const std::string& src,
+ int ln,
+ int ch,
+ const std::string& e,
+ const std::string& a) :
+ TokenException(src, ln, ch), expected(e), actual(a) {
+
+ message += format("Expected string '%s', found string '%s'.",
+ e.c_str(), a.c_str());
+}
+
+
+void deserialize(bool& b, TextInput& ti) {
+ b = ti.readSymbol() == "true";
+}
+
+
+void deserialize(int& b, TextInput& ti) {
+ b = iRound(ti.readNumber());
+}
+
+
+void deserialize(uint8& b, TextInput& ti) {
+ b = (uint8)iRound(ti.readNumber());
+}
+
+
+void deserialize(double& b, TextInput& ti) {
+ b = ti.readNumber();
+}
+
+
+void deserialize(float& b, TextInput& ti) {
+ b = (float)ti.readNumber();
+}
+
+} // namespace
+
+#ifdef _MSC_VER
+# pragma warning (pop)
+#endif
diff --git a/dep/src/g3dlite/TextOutput.cpp b/dep/src/g3dlite/TextOutput.cpp
new file mode 100644
index 00000000000..11347252eba
--- /dev/null
+++ b/dep/src/g3dlite/TextOutput.cpp
@@ -0,0 +1,452 @@
+/**
+ @file TextOutput.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2004-06-21
+ @edited 2006-08-14
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/TextOutput.h"
+#include "G3D/Log.h"
+#include "G3D/fileutils.h"
+
+namespace G3D {
+
+TextOutput::TextOutput(const TextOutput::Settings& opt) :
+ startingNewLine(true),
+ currentColumn(0),
+ inDQuote(false),
+ filename(""),
+ indentLevel(0)
+{
+ setOptions(opt);
+}
+
+
+TextOutput::TextOutput(const std::string& fil, const TextOutput::Settings& opt) :
+ startingNewLine(true),
+ currentColumn(0),
+ inDQuote(false),
+ filename(fil),
+ indentLevel(0)
+{
+
+ setOptions(opt);
+}
+
+
+void TextOutput::setIndentLevel(int i) {
+ indentLevel = i;
+
+ // If there were more pops than pushes, don't let that take us below 0 indent.
+ // Don't ever indent more than the number of columns.
+ indentSpaces =
+ iClamp(option.spacesPerIndent * indentLevel,
+ 0,
+ option.numColumns - 1);
+}
+
+
+void TextOutput::setOptions(const Settings& _opt) {
+ option = _opt;
+
+ debugAssert(option.numColumns > 1);
+
+ setIndentLevel(indentLevel);
+
+ newline = (option.newlineStyle == Settings::NEWLINE_WINDOWS) ? "\r\n" : "\n";
+}
+
+
+void TextOutput::pushIndent() {
+ setIndentLevel(indentLevel + 1);
+}
+
+
+void TextOutput::popIndent() {
+ setIndentLevel(indentLevel - 1);
+}
+
+
+static std::string escape(const std::string& string) {
+ std::string result = "";
+
+ for (std::string::size_type i = 0; i < string.length(); ++i) {
+ char c = string.at(i);
+ switch (c) {
+ case '\0':
+ result += "\\0";
+ break;
+
+ case '\r':
+ result += "\\r";
+ break;
+
+ case '\n':
+ result += "\\n";
+ break;
+
+ case '\t':
+ result += "\\t";
+ break;
+
+ case '\\':
+ result += "\\\\";
+ break;
+
+ default:
+ result += c;
+ }
+ }
+
+ return result;
+}
+
+void TextOutput::writeString(const std::string& string) {
+ // Convert special characters to escape sequences
+ this->printf("\"%s\"", escape(string).c_str());
+}
+
+
+void TextOutput::writeBoolean(bool b) {
+ this->printf("%s ", b ? option.trueSymbol.c_str() : option.falseSymbol.c_str());
+}
+
+void TextOutput::writeNumber(double n) {
+ this->printf("%f ", n);
+}
+
+
+void TextOutput::writeNumber(int n) {
+ this->printf("%d ", n);
+}
+
+
+void TextOutput::writeSymbol(const std::string& string) {
+ if (string.size() > 0) {
+ // TODO: check for legal symbols?
+ this->printf("%s ", string.c_str());
+ }
+}
+
+void TextOutput::writeSymbols(
+ const std::string& a,
+ const std::string& b,
+ const std::string& c,
+ const std::string& d,
+ const std::string& e,
+ const std::string& f) {
+
+ writeSymbol(a);
+ writeSymbol(b);
+ writeSymbol(c);
+ writeSymbol(d);
+ writeSymbol(e);
+ writeSymbol(f);
+}
+
+
+void TextOutput::printf(const std::string formatString, ...) {
+ va_list argList;
+ va_start(argList, formatString);
+ this->vprintf(formatString.c_str(), argList);
+ va_end(argList);
+}
+
+
+void TextOutput::printf(const char* formatString, ...) {
+ va_list argList;
+ va_start(argList, formatString);
+ this->vprintf(formatString, argList);
+ va_end(argList);
+}
+
+
+void TextOutput::convertNewlines(const std::string& in, std::string& out) {
+ // TODO: can be significantly optimized in cases where
+ // single characters are copied in order by walking through
+ // the array and copying substrings as needed.
+
+ if (option.convertNewlines) {
+ out = "";
+ for (uint32 i = 0; i < in.size(); ++i) {
+ if (in[i] == '\n') {
+ // Unix newline
+ out += newline;
+ } else if ((in[i] == '\r') && (i + 1 < in.size()) && (in[i + 1] == '\n')) {
+ // Windows newline
+ out += newline;
+ ++i;
+ } else {
+ out += in[i];
+ }
+ }
+ } else {
+ out = in;
+ }
+}
+
+
+void TextOutput::writeNewline() {
+ for (uint32 i = 0; i < newline.size(); ++i) {
+ indentAppend(newline[i]);
+ }
+}
+
+
+void TextOutput::writeNewlines(int numLines) {
+ for (int i = 0; i < numLines; ++i) {
+ writeNewline();
+ }
+}
+
+
+void TextOutput::wordWrapIndentAppend(const std::string& str) {
+ // TODO: keep track of the last space character we saw so we don't
+ // have to always search.
+
+ if ((option.wordWrap == Settings::WRAP_NONE) ||
+ (currentColumn + (int)str.size() <= option.numColumns)) {
+ // No word-wrapping is needed
+
+ // Add one character at a time.
+ // TODO: optimize for strings without newlines to add multiple
+ // characters.
+ for (uint32 i = 0; i < str.size(); ++i) {
+ indentAppend(str[i]);
+ }
+ return;
+ }
+
+ // Number of columns to wrap against
+ int cols = option.numColumns - indentSpaces;
+
+ // Copy forward until we exceed the column size,
+ // and then back up and try to insert newlines as needed.
+ for (uint32 i = 0; i < str.size(); ++i) {
+
+ indentAppend(str[i]);
+ if ((str[i] == '\r') && (i + 1 < str.size()) && (str[i + 1] == '\n')) {
+ // \r\n, we need to hit the \n to enter word wrapping.
+ ++i;
+ indentAppend(str[i]);
+ }
+
+ if (currentColumn >= cols) {
+ debugAssertM(str[i] != '\n' && str[i] != '\r',
+ "Should never enter word-wrapping on a newline character");
+
+ // True when we're allowed to treat a space as a space.
+ bool unquotedSpace = option.allowWordWrapInsideDoubleQuotes || ! inDQuote;
+
+ // Cases:
+ //
+ // 1. Currently in a series of spaces that ends with a newline
+ // strip all spaces and let the newline
+ // flow through.
+ //
+ // 2. Currently in a series of spaces that does not end with a newline
+ // strip all spaces and replace them with single newline
+ //
+ // 3. Not in a series of spaces
+ // search backwards for a space, then execute case 2.
+
+ // Index of most recent space
+ uint32 lastSpace = data.size() - 1;
+
+ // How far back we had to look for a space
+ uint32 k = 0;
+ uint32 maxLookBackward = currentColumn - indentSpaces;
+
+ // Search backwards (from current character), looking for a space.
+ while ((k < maxLookBackward) &&
+ (lastSpace > 0) &&
+ (! ((data[lastSpace] == ' ') && unquotedSpace))) {
+ --lastSpace;
+ ++k;
+
+ if ((data[lastSpace] == '\"') && !option.allowWordWrapInsideDoubleQuotes) {
+ unquotedSpace = ! unquotedSpace;
+ }
+ }
+
+ if (k == maxLookBackward) {
+ // We couldn't find a series of spaces
+
+ if (option.wordWrap == Settings::WRAP_ALWAYS) {
+ // Strip the last character we wrote, force a newline,
+ // and replace the last character;
+ data.pop();
+ writeNewline();
+ indentAppend(str[i]);
+ } else {
+ // Must be Settings::WRAP_WITHOUT_BREAKING
+ //
+ // Don't write the newline; we'll come back to
+ // the word wrap code after writing another character
+ }
+ } else {
+ // We found a series of spaces. If they continue
+ // to the new string, strip spaces off both. Otherwise
+ // strip spaces from data only and insert a newline.
+
+ // Find the start of the spaces. firstSpace is the index of the
+ // first non-space, looking backwards from lastSpace.
+ uint32 firstSpace = lastSpace;
+ while ((k < maxLookBackward) &&
+ (firstSpace > 0) &&
+ (data[firstSpace] == ' ')) {
+ --firstSpace;
+ ++k;
+ }
+
+ if (k == maxLookBackward) {
+ ++firstSpace;
+ }
+
+ if (lastSpace == (uint32)data.size() - 1) {
+ // Spaces continued up to the new string
+ data.resize(firstSpace + 1);
+ writeNewline();
+
+ // Delete the spaces from the new string
+ while ((i < str.size() - 1) && (str[i + 1] == ' ')) {
+ ++i;
+ }
+ } else {
+ // Spaces were somewhere in the middle of the old string.
+ // replace them with a newline.
+
+ // Copy over the characters that should be saved
+ Array<char> temp;
+ for (uint32 j = lastSpace + 1; j < (uint32)data.size(); ++j) {
+ char c = data[j];
+
+ if (c == '\"') {
+ // Undo changes to quoting (they will be re-done
+ // when we paste these characters back on).
+ inDQuote = !inDQuote;
+ }
+ temp.append(c);
+ }
+
+ // Remove those characters and replace with a newline.
+ data.resize(firstSpace + 1);
+ writeNewline();
+
+ // Write them back
+ for (uint32 j = 0; j < (uint32)temp.size(); ++j) {
+ indentAppend(temp[j]);
+ }
+
+ // We are now free to continue adding from the
+ // new string, which may or may not begin with spaces.
+
+ } // if spaces included new string
+ } // if hit indent
+ } // if line exceeded
+ } // iterate over str
+}
+
+
+void TextOutput::indentAppend(char c) {
+
+ if (startingNewLine) {
+ for (int j = 0; j < indentSpaces; ++j) {
+ data.push(' ');
+ }
+ startingNewLine = false;
+ currentColumn = indentSpaces;
+ }
+
+ data.push(c);
+
+ // Don't increment the column count on return character
+ // newline is taken care of below.
+ if (c != '\r') {
+ ++currentColumn;
+ }
+
+ if (c == '\"') {
+ inDQuote = ! inDQuote;
+ }
+
+ startingNewLine = (c == '\n');
+ if (startingNewLine) {
+ currentColumn = 0;
+ }
+}
+
+
+void TextOutput::vprintf(const char* formatString, va_list argPtr) {
+ std::string str = vformat(formatString, argPtr);
+
+ std::string clean;
+ convertNewlines(str, clean);
+ wordWrapIndentAppend(clean);
+}
+
+
+void TextOutput::commit(bool flush) {
+ std::string p = filenamePath(filename);
+ if (! fileExists(p, false)) {
+ createDirectory(p);
+ }
+
+ FILE* f = fopen(filename.c_str(), "wb");
+ debugAssertM(f, "Could not open \"" + filename + "\"");
+ fwrite(data.getCArray(), 1, data.size(), f);
+ if (flush) {
+ fflush(f);
+ }
+ fclose(f);
+}
+
+
+void TextOutput::commitString(std::string& out) {
+ // Null terminate
+ data.push('\0');
+ out = data.getCArray();
+ data.pop();
+}
+
+
+std::string TextOutput::commitString() {
+ std::string str;
+ commitString(str);
+ return str;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+
+void serialize(const float& b, TextOutput& to) {
+ to.writeNumber(b);
+}
+
+
+void serialize(const bool& b, TextOutput& to) {
+ to.writeSymbol(b ? "true" : "false");
+}
+
+
+void serialize(const int& b, TextOutput& to) {
+ to.writeNumber(b);
+}
+
+
+void serialize(const uint8& b, TextOutput& to) {
+ to.writeNumber(b);
+}
+
+
+void serialize(const double& b, TextOutput& to) {
+ to.writeNumber(b);
+}
+
+
+}
diff --git a/dep/src/g3dlite/ThreadSet.cpp b/dep/src/g3dlite/ThreadSet.cpp
new file mode 100644
index 00000000000..ee3895fe9de
--- /dev/null
+++ b/dep/src/g3dlite/ThreadSet.cpp
@@ -0,0 +1,166 @@
+#include "G3D/ThreadSet.h"
+
+namespace G3D {
+
+int ThreadSet::size() const {
+ ThreadSet* me = const_cast<ThreadSet*>(this);
+ me->m_lock.lock();
+ int s = m_thread.size();
+ me->m_lock.unlock();
+ return s;
+}
+
+
+int ThreadSet::numStarted() const {
+ ThreadSet* me = const_cast<ThreadSet*>(this);
+ me->m_lock.lock();
+ int count = 0;
+ for (int i = 0; i < m_thread.size(); ++i) {
+ if (m_thread[i]->started()) {
+ ++count;
+ }
+ }
+ me->m_lock.unlock();
+ return count;
+}
+
+
+void ThreadSet::start(GThread::SpawnBehavior lastBehavior) const {
+ ThreadSet* me = const_cast<ThreadSet*>(this);
+
+ Array<GThreadRef> unstarted;
+ me->m_lock.lock();
+ // Find the unstarted threads
+ for (int i = 0; i < m_thread.size(); ++i) {
+ if (! m_thread[i]->started()) {
+ unstarted.append(m_thread[i]);
+ }
+ }
+
+ int last = unstarted.size();
+ if (lastBehavior == GThread::USE_CURRENT_THREAD) {
+ // Save the last unstarted for the current thread
+ --last;
+ }
+
+ for (int i = 0; i < last; ++i) {
+ unstarted[i]->start(GThread::USE_NEW_THREAD);
+ }
+
+ me->m_lock.unlock();
+
+ // Start the last one on my thread
+ if ((unstarted.size() > 0) && (lastBehavior == GThread::USE_CURRENT_THREAD)) {
+ unstarted.last()->start(GThread::USE_CURRENT_THREAD);
+ }
+}
+
+
+void ThreadSet::terminate() const {
+ ThreadSet* me = const_cast<ThreadSet*>(this);
+ me->m_lock.lock();
+ for (int i = 0; i < m_thread.size(); ++i) {
+ if (m_thread[i]->started()) {
+ m_thread[i]->terminate();
+ }
+ }
+ me->m_lock.unlock();
+}
+
+
+void ThreadSet::waitForCompletion() const {
+ ThreadSet* me = const_cast<ThreadSet*>(this);
+ me->m_lock.lock();
+ for (int i = 0; i < m_thread.size(); ++i) {
+ if (m_thread[i]->started()) {
+ m_thread[i]->waitForCompletion();
+ }
+ }
+ me->m_lock.unlock();
+}
+
+
+int ThreadSet::removeCompleted() {
+ m_lock.lock();
+ for (int i = 0; i < m_thread.size(); ++i) {
+ if (m_thread[i]->completed()) {
+ m_thread.fastRemove(i);
+ --i;
+ }
+ }
+
+ int s = m_thread.size();
+ m_lock.unlock();
+ return s;
+}
+
+
+void ThreadSet::clear() {
+ m_lock.lock();
+ m_thread.clear();
+ m_lock.unlock();
+}
+
+
+int ThreadSet::insert(const ThreadRef& t) {
+ m_lock.lock();
+ bool found = false;
+ for (int i = 0; i < m_thread.size() && ! found; ++i) {
+ found = (m_thread[i] == t);
+ }
+ if (! found) {
+ m_thread.append(t);
+ }
+ int s = m_thread.size();
+ m_lock.unlock();
+ return s;
+}
+
+
+bool ThreadSet::remove(const ThreadRef& t) {
+ m_lock.lock();
+ bool found = false;
+ for (int i = 0; i < m_thread.size() && ! found; ++i) {
+ found = (m_thread[i] == t);
+ if (found) {
+ m_thread.fastRemove(i);
+ }
+ }
+ m_lock.unlock();
+ return found;
+}
+
+
+bool ThreadSet::contains(const ThreadRef& t) const {
+ ThreadSet* me = const_cast<ThreadSet*>(this);
+ me->m_lock.lock();
+ bool found = false;
+ for (int i = 0; i < m_thread.size() && ! found; ++i) {
+ found = (m_thread[i] == t);
+ }
+ me->m_lock.unlock();
+ return found;
+}
+
+
+ThreadSet::Iterator ThreadSet::begin() {
+ return m_thread.begin();
+}
+
+
+ThreadSet::Iterator ThreadSet::end() {
+ return m_thread.end();
+}
+
+
+ThreadSet::ConstIterator ThreadSet::begin() const {
+ return m_thread.begin();
+}
+
+
+ThreadSet::ConstIterator ThreadSet::end() const {
+ return m_thread.end();
+}
+
+
+} // namespace G3D
diff --git a/dep/src/g3dlite/Triangle.cpp b/dep/src/g3dlite/Triangle.cpp
index 2e221b12f1d..253438ad5fb 100644
--- a/dep/src/g3dlite/Triangle.cpp
+++ b/dep/src/g3dlite/Triangle.cpp
@@ -1,22 +1,27 @@
/**
@file Triangle.cpp
-
- @maintainer Morgan McGuire, graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2001-04-06
- @edited 2006-01-20
+ @edited 2008-12-28
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
#include "G3D/platform.h"
#include "G3D/Triangle.h"
#include "G3D/Plane.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/debugAssert.h"
#include "G3D/AABox.h"
+#include "G3D/Ray.h"
namespace G3D {
+
void Triangle::init(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
_plane = Plane(v0, v1, v2);
@@ -27,8 +32,8 @@ void Triangle::init(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
static int next[] = {1,2,0};
for (int i = 0; i < 3; ++i) {
- const Vector3 e = _vertex[next[i]] - _vertex[i];
- edgeMagnitude[i] = e.magnitude();
+ const Vector3& e = _vertex[next[i]] - _vertex[i];
+ edgeMagnitude[i] = e.magnitude();
if (edgeMagnitude[i] == 0) {
edgeDirection[i] = Vector3::zero();
@@ -37,37 +42,64 @@ void Triangle::init(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
}
}
- edge01 = _vertex[1] - _vertex[0];
- edge02 = _vertex[2] - _vertex[0];
+ _edge01 = _vertex[1] - _vertex[0];
+ _edge02 = _vertex[2] - _vertex[0];
_primaryAxis = _plane.normal().primaryAxis();
- _area = (float)edgeDirection[0].cross(edgeDirection[2]).magnitude() * (edgeMagnitude[0] * edgeMagnitude[2]);
-
+ _area = 0.5f * edgeDirection[0].cross(edgeDirection[2]).magnitude() * (edgeMagnitude[0] * edgeMagnitude[2]);
+ //0.5f * (_vertex[1] - _vertex[0]).cross(_vertex[2] - _vertex[0]).dot(_plane.normal());
}
+
Triangle::Triangle() {
init(Vector3::zero(), Vector3::zero(), Vector3::zero());
}
+
Triangle::Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
init(v0, v1, v2);
}
+
Triangle::~Triangle() {
}
-double Triangle::area() const {
+
+Triangle::Triangle(class BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Triangle::serialize(class BinaryOutput& b) {
+ _vertex[0].serialize(b);
+ _vertex[1].serialize(b);
+ _vertex[2].serialize(b);
+}
+
+
+void Triangle::deserialize(class BinaryInput& b) {
+ _vertex[0].deserialize(b);
+ _vertex[1].deserialize(b);
+ _vertex[2].deserialize(b);
+ init(_vertex[0], _vertex[1], _vertex[2]);
+}
+
+
+float Triangle::area() const {
return _area;
}
+
const Vector3& Triangle::normal() const {
return _plane.normal();
}
+
const Plane& Triangle::plane() const {
return _plane;
}
+
Vector3 Triangle::center() const {
return (_vertex[0] + _vertex[1] + _vertex[2]) / 3.0;
}
@@ -85,9 +117,10 @@ Vector3 Triangle::randomPoint() const {
s = 1.0f - s;
}
- return edge01 * s + edge02 * t + _vertex[0];
+ return _edge01 * s + _edge02 * t + _vertex[0];
}
+
void Triangle::getBounds(AABox& out) const {
Vector3 lo = _vertex[0];
Vector3 hi = lo;
@@ -100,5 +133,54 @@ void Triangle::getBounds(AABox& out) const {
out = AABox(lo, hi);
}
-} // G3D
+bool Triangle::intersect(const Ray& ray, float& distance, float baryCoord[3]) const {
+ static const float EPS = 1e-5f;
+
+ // See RTR2 ch. 13.7 for the algorithm.
+
+ const Vector3& e1 = edge01();
+ const Vector3& e2 = edge02();
+ const Vector3 p(ray.direction().cross(e2));
+ const float a = e1.dot(p);
+
+ if (abs(a) < EPS) {
+ // Determinant is ill-conditioned; abort early
+ return false;
+ }
+
+ const float f = 1.0f / a;
+ const Vector3 s(ray.origin() - vertex(0));
+ const float u = f * s.dot(p);
+
+ if ((u < 0.0f) || (u > 1.0f)) {
+ // We hit the plane of the m_geometry, but outside the m_geometry
+ return false;
+ }
+
+ const Vector3 q(s.cross(e1));
+ const float v = f * ray.direction().dot(q);
+
+ if ((v < 0.0f) || ((u + v) > 1.0f)) {
+ // We hit the plane of the triangle, but outside the triangle
+ return false;
+ }
+
+ const float t = f * e2.dot(q);
+
+ if ((t > 0.0f) && (t < distance)) {
+ // This is a new hit, closer than the previous one
+ distance = t;
+
+ baryCoord[0] = 1.0 - u - v;
+ baryCoord[1] = u;
+ baryCoord[2] = v;
+
+ return true;
+ } else {
+ // This hit is after the previous hit, so ignore it
+ return false;
+ }
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/UprightFrame.cpp b/dep/src/g3dlite/UprightFrame.cpp
new file mode 100644
index 00000000000..c80264bf4e8
--- /dev/null
+++ b/dep/src/g3dlite/UprightFrame.cpp
@@ -0,0 +1,132 @@
+/**
+ @file UprightFrame.cpp
+ Box class
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-05-02
+ @edited 2007-05-05
+*/
+
+#include "G3D/UprightFrame.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+UprightFrame::UprightFrame(const CoordinateFrame& cframe) {
+ Vector3 look = cframe.lookVector();
+
+ yaw = G3D::pi() + atan2(look.x, look.z);
+ pitch = asin(look.y);
+
+ translation = cframe.translation;
+}
+
+
+CoordinateFrame UprightFrame::toCoordinateFrame() const {
+ CoordinateFrame cframe;
+
+ Matrix3 P(Matrix3::fromAxisAngle(Vector3::unitX(), pitch));
+ Matrix3 Y(Matrix3::fromAxisAngle(Vector3::unitY(), yaw));
+
+ cframe.rotation = Y * P;
+ cframe.translation = translation;
+
+ return cframe;
+}
+
+
+UprightFrame UprightFrame::operator+(const UprightFrame& other) const {
+ return UprightFrame(translation + other.translation, pitch + other.pitch, yaw + other.yaw);
+}
+
+
+UprightFrame UprightFrame::operator*(const float k) const {
+ return UprightFrame(translation * k, pitch * k, yaw * k);
+}
+
+
+void UprightFrame::unwrapYaw(UprightFrame* a, int N) {
+ // Use the first point to establish the wrapping convention
+ for (int i = 1; i < N; ++i) {
+ const float prev = a[i - 1].yaw;
+ float& cur = a[i].yaw;
+
+ // No two angles should be more than pi (i.e., 180-degrees) apart.
+ if (abs(cur - prev) > G3D::pi()) {
+ // These angles must have wrapped at zero, causing them
+ // to be interpolated the long way.
+
+ // Find canonical [0, 2pi] versions of these numbers
+ float p = wrap(prev, twoPi());
+ float c = wrap(cur, twoPi());
+
+ // Find the difference -pi < diff < pi between the current and previous values
+ float diff = c - p;
+ if (diff < -G3D::pi()) {
+ diff += twoPi();
+ } else if (diff > G3D::pi()) {
+ diff -= twoPi();
+ }
+
+ // Offset the current from the previous by the difference
+ // between them.
+ cur = prev + diff;
+ }
+ }
+}
+
+
+void UprightFrame::serialize(class BinaryOutput& b) const {
+ translation.serialize(b);
+ b.writeFloat32(pitch);
+ b.writeFloat32(yaw);
+}
+
+
+void UprightFrame::deserialize(class BinaryInput& b) {
+ translation.deserialize(b);
+ pitch = b.readFloat32();
+ yaw = b.readFloat32();
+}
+
+
+void UprightSpline::serialize(class BinaryOutput& b) const {
+ b.writeBool8(cyclic);
+
+ b.writeInt32(control.size());
+ for (int i = 0; i < control.size(); ++i) {
+ control[i].serialize(b);
+ }
+ b.writeInt32(time.size());
+ for (int i = 0; i < time.size(); ++i) {
+ b.writeFloat32(time[i]);
+ }
+}
+
+
+void UprightSpline::deserialize(class BinaryInput& b) {
+ cyclic = b.readBool8();
+
+ control.resize(b.readInt32());
+ for (int i = 0; i < control.size(); ++i) {
+ control[i].deserialize(b);
+ }
+
+ if (b.hasMore()) {
+ time.resize(b.readInt32());
+ for (int i = 0; i < time.size(); ++i) {
+ time[i] = b.readFloat32();
+ }
+ debugAssert(time.size() == control.size());
+ } else {
+ // Import legacy path
+ time.resize(control.size());
+ for (int i = 0; i < time.size(); ++i) {
+ time[i] = i;
+ }
+ }
+}
+
+}
diff --git a/dep/src/g3dlite/Vector2.cpp b/dep/src/g3dlite/Vector2.cpp
new file mode 100644
index 00000000000..ec0737c3755
--- /dev/null
+++ b/dep/src/g3dlite/Vector2.cpp
@@ -0,0 +1,224 @@
+/**
+ @file Vector2.cpp
+
+ 2D vector class, used for texture coordinates primarily.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @cite Portions based on Dave Eberly'x Magic Software Library
+ at http://www.magic-software.com
+
+ @created 2001-06-02
+ @edited 2009-11-16
+ */
+
+#include "G3D/platform.h"
+#include <stdlib.h>
+#include "G3D/Vector2.h"
+#include "G3D/g3dmath.h"
+#include "G3D/format.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/TextInput.h"
+#include "G3D/TextOutput.h"
+#include "G3D/Any.h"
+
+namespace G3D {
+
+
+Vector2::Vector2(const Any& any) {
+ any.verifyName("Vector2");
+ any.verifyType(Any::TABLE, Any::ARRAY);
+ any.verifySize(2);
+
+ if (any.type() == Any::ARRAY) {
+ x = any[0];
+ y = any[1];
+ } else {
+ // Table
+ x = any["x"];
+ y = any["y"];
+ }
+}
+
+
+Vector2::operator Any() const {
+ Any any(Any::ARRAY, "Vector2");
+ any.append(x, y);
+ return any;
+}
+
+
+const Vector2& Vector2::one() {
+ static const Vector2 v(1, 1); return v;
+}
+
+
+const Vector2& Vector2::zero() {
+ static Vector2 v(0, 0);
+ return v;
+}
+
+const Vector2& Vector2::unitX() {
+ static Vector2 v(1, 0);
+ return v;
+}
+
+const Vector2& Vector2::unitY() {
+ static Vector2 v(0, 1);
+ return v;
+}
+
+const Vector2& Vector2::inf() {
+ static Vector2 v((float)G3D::finf(), (float)G3D::finf());
+ return v;
+}
+
+
+const Vector2& Vector2::nan() {
+ static Vector2 v((float)G3D::fnan(), (float)G3D::fnan());
+ return v;
+}
+
+
+const Vector2& Vector2::minFinite() {
+ static Vector2 v(-FLT_MAX, -FLT_MAX);
+ return v;
+}
+
+
+const Vector2& Vector2::maxFinite() {
+ static Vector2 v(FLT_MAX, FLT_MAX);
+ return v;
+}
+
+
+size_t Vector2::hashCode() const {
+ unsigned int xhash = (*(int*)(void*)(&x));
+ unsigned int yhash = (*(int*)(void*)(&y));
+
+ return xhash + (yhash * 37);
+}
+
+
+Vector2::Vector2(BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Vector2::deserialize(BinaryInput& b) {
+ x = b.readFloat32();
+ y = b.readFloat32();
+}
+
+
+void Vector2::serialize(BinaryOutput& b) const {
+ b.writeFloat32(x);
+ b.writeFloat32(y);
+}
+
+
+void Vector2::deserialize(TextInput& t) {
+ t.readSymbol("(");
+ x = (float)t.readNumber();
+ t.readSymbol(",");
+ y = (float)t.readNumber();
+ t.readSymbol(")");
+}
+
+
+void Vector2::serialize(TextOutput& t) const {
+ t.writeSymbol("(");
+ t.writeNumber(x);
+ t.writeSymbol(",");
+ t.writeNumber(y);
+ t.writeSymbol(")");
+}
+
+//----------------------------------------------------------------------------
+
+Vector2 Vector2::random(G3D::Random& r) {
+ Vector2 result;
+
+ do {
+ result = Vector2(r.uniform(-1, 1), r.uniform(-1, 1));
+
+ } while (result.squaredLength() >= 1.0f);
+
+ result.unitize();
+
+ return result;
+}
+
+
+Vector2 Vector2::operator/ (float k) const {
+ return *this * (1.0f / k);
+}
+
+Vector2& Vector2::operator/= (float k) {
+ this->x /= k;
+ this->y /= k;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+float Vector2::unitize (float fTolerance) {
+ float fLength = length();
+
+ if (fLength > fTolerance) {
+ float fInvLength = 1.0f / fLength;
+ x *= fInvLength;
+ y *= fInvLength;
+ } else {
+ fLength = 0.0;
+ }
+
+ return fLength;
+}
+
+//----------------------------------------------------------------------------
+
+std::string Vector2::toString() const {
+ return G3D::format("(%g, %g)", x, y);
+}
+
+// 2-char swizzles
+
+Vector2 Vector2::xx() const { return Vector2 (x, x); }
+Vector2 Vector2::yx() const { return Vector2 (y, x); }
+Vector2 Vector2::xy() const { return Vector2 (x, y); }
+Vector2 Vector2::yy() const { return Vector2 (y, y); }
+
+// 3-char swizzles
+
+Vector3 Vector2::xxx() const { return Vector3 (x, x, x); }
+Vector3 Vector2::yxx() const { return Vector3 (y, x, x); }
+Vector3 Vector2::xyx() const { return Vector3 (x, y, x); }
+Vector3 Vector2::yyx() const { return Vector3 (y, y, x); }
+Vector3 Vector2::xxy() const { return Vector3 (x, x, y); }
+Vector3 Vector2::yxy() const { return Vector3 (y, x, y); }
+Vector3 Vector2::xyy() const { return Vector3 (x, y, y); }
+Vector3 Vector2::yyy() const { return Vector3 (y, y, y); }
+
+// 4-char swizzles
+
+Vector4 Vector2::xxxx() const { return Vector4 (x, x, x, x); }
+Vector4 Vector2::yxxx() const { return Vector4 (y, x, x, x); }
+Vector4 Vector2::xyxx() const { return Vector4 (x, y, x, x); }
+Vector4 Vector2::yyxx() const { return Vector4 (y, y, x, x); }
+Vector4 Vector2::xxyx() const { return Vector4 (x, x, y, x); }
+Vector4 Vector2::yxyx() const { return Vector4 (y, x, y, x); }
+Vector4 Vector2::xyyx() const { return Vector4 (x, y, y, x); }
+Vector4 Vector2::yyyx() const { return Vector4 (y, y, y, x); }
+Vector4 Vector2::xxxy() const { return Vector4 (x, x, x, y); }
+Vector4 Vector2::yxxy() const { return Vector4 (y, x, x, y); }
+Vector4 Vector2::xyxy() const { return Vector4 (x, y, x, y); }
+Vector4 Vector2::yyxy() const { return Vector4 (y, y, x, y); }
+Vector4 Vector2::xxyy() const { return Vector4 (x, x, y, y); }
+Vector4 Vector2::yxyy() const { return Vector4 (y, x, y, y); }
+Vector4 Vector2::xyyy() const { return Vector4 (x, y, y, y); }
+Vector4 Vector2::yyyy() const { return Vector4 (y, y, y, y); }
+
+
+
+} // namespace
diff --git a/dep/src/g3dlite/Vector2int16.cpp b/dep/src/g3dlite/Vector2int16.cpp
new file mode 100644
index 00000000000..2a4035a4d09
--- /dev/null
+++ b/dep/src/g3dlite/Vector2int16.cpp
@@ -0,0 +1,47 @@
+/**
+ @file Vector2int16.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-08-09
+ @edited 2006-01-29
+ */
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Vector2int16.h"
+#include "G3D/Vector2.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
+namespace G3D {
+
+Vector2int16::Vector2int16(const class Vector2& v) {
+ x = (int16)iFloor(v.x + 0.5);
+ y = (int16)iFloor(v.y + 0.5);
+}
+
+
+Vector2int16::Vector2int16(class BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Vector2int16::serialize(class BinaryOutput& bo) const {
+ bo.writeInt16(x);
+ bo.writeInt16(y);
+}
+
+
+void Vector2int16::deserialize(class BinaryInput& bi) {
+ x = bi.readInt16();
+ y = bi.readInt16();
+}
+
+
+Vector2int16 Vector2int16::clamp(const Vector2int16& lo, const Vector2int16& hi) {
+ return Vector2int16(iClamp(x, lo.x, hi.x), iClamp(y, lo.y, hi.y));
+}
+
+
+}
diff --git a/dep/src/g3dlite/Vector3.cpp b/dep/src/g3dlite/Vector3.cpp
index b0ca1990a3f..a53fa8269b7 100644
--- a/dep/src/g3dlite/Vector3.cpp
+++ b/dep/src/g3dlite/Vector3.cpp
@@ -1,44 +1,84 @@
/**
@file Vector3.cpp
-
+
3D vector class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
-
+
@created 2001-06-02
- @edited 2006-01-30
+ @edited 2009-11-27
*/
#include <limits>
#include <stdlib.h>
#include "G3D/Vector3.h"
#include "G3D/g3dmath.h"
-#include "G3D/format.h"
#include "G3D/stringutils.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/TextInput.h"
+#include "G3D/TextOutput.h"
#include "G3D/Vector3int16.h"
#include "G3D/Matrix3.h"
#include "G3D/Vector2.h"
-
+#include "G3D/Color3.h"
+#include "G3D/Vector4int8.h"
+#include "G3D/Vector3int32.h"
+#include "G3D/Any.h"
+
namespace G3D {
-Vector3 Vector3::dummy;
+Vector3::Vector3(const Any& any) {
+ any.verifyName("Vector3");
+ any.verifyType(Any::TABLE, Any::ARRAY);
+ any.verifySize(3);
-// Deprecated.
-const Vector3 Vector3::ZERO(0, 0, 0);
-const Vector3 Vector3::ZERO3(0, 0, 0);
-const Vector3 Vector3::UNIT_X(1, 0, 0);
-const Vector3 Vector3::UNIT_Y(0, 1, 0);
-const Vector3 Vector3::UNIT_Z(0, 0, 1);
-const Vector3 Vector3::INF3((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf());
-const Vector3 Vector3::NAN3((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan());
+ if (any.type() == Any::ARRAY) {
+ x = any[0];
+ y = any[1];
+ z = any[2];
+ } else {
+ // Table
+ x = any["x"];
+ y = any["y"];
+ z = any["z"];
+ }
+}
+
+Vector3::operator Any() const {
+ Any any(Any::ARRAY, "Vector3");
+ any.append(x, y, z);
+ return any;
+}
+
+Vector3::Vector3(const class Color3& v) : x(v.r), y(v.g), z(v.b) {}
+
+Vector3::Vector3(const class Vector3int32& v) : x((float)v.x), y((float)v.y), z((float)v.z) {}
+
+Vector3::Vector3(const Vector4int8& v) : x(v.x / 127.0f), y(v.y / 127.0f), z(v.z / 127.0f) {}
Vector3::Vector3(const class Vector2& v, float _z) : x(v.x), y(v.y), z(_z) {
}
-Vector3::Axis Vector3::primaryAxis() const {
+Vector3& Vector3::ignore() {
+ static Vector3 v;
+ return v;
+}
+const Vector3& Vector3::zero() { static const Vector3 v(0, 0, 0); return v; }
+const Vector3& Vector3::one() { static const Vector3 v(1, 1, 1); return v; }
+const Vector3& Vector3::unitX() { static const Vector3 v(1, 0, 0); return v; }
+const Vector3& Vector3::unitY() { static const Vector3 v(0, 1, 0); return v; }
+const Vector3& Vector3::unitZ() { static const Vector3 v(0, 0, 1); return v; }
+const Vector3& Vector3::inf() { static const Vector3 v((float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf()); return v; }
+const Vector3& Vector3::nan() { static const Vector3 v((float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan()); return v; }
+const Vector3& Vector3::minFinite(){ static const Vector3 v(-FLT_MAX, -FLT_MAX, -FLT_MAX); return v; }
+const Vector3& Vector3::maxFinite(){ static const Vector3 v(FLT_MAX, FLT_MAX, FLT_MAX); return v; }
+
+Vector3::Axis Vector3::primaryAxis() const {
+
Axis a = X_AXIS;
double nx = abs(x);
@@ -62,7 +102,8 @@ Vector3::Axis Vector3::primaryAxis() const {
return a;
}
-unsigned int Vector3::hashCode() const {
+
+size_t Vector3::hashCode() const {
unsigned int xhash = (*(int*)(void*)(&x));
unsigned int yhash = (*(int*)(void*)(&y));
unsigned int zhash = (*(int*)(void*)(&z));
@@ -74,65 +115,73 @@ std::ostream& operator<<(std::ostream& os, const Vector3& v) {
return os << v.toString();
}
+
//----------------------------------------------------------------------------
double frand() {
return rand() / (double) RAND_MAX;
}
+Vector3::Vector3(TextInput& t) {
+ deserialize(t);
+}
+
+Vector3::Vector3(BinaryInput& b) {
+ deserialize(b);
+}
+
+
Vector3::Vector3(const class Vector3int16& v) {
x = v.x;
y = v.y;
z = v.z;
}
-Vector3 Vector3::random() {
- Vector3 result;
- do {
- result = Vector3(uniformRandom(-1.0, 1.0),
- uniformRandom(-1.0, 1.0),
- uniformRandom(-1.0, 1.0));
- } while (result.squaredMagnitude() >= 1.0f);
+void Vector3::deserialize(BinaryInput& b) {
+ x = b.readFloat32();
+ y = b.readFloat32();
+ z = b.readFloat32();
+}
- result.unitize();
- return result;
+void Vector3::deserialize(TextInput& t) {
+ t.readSymbol("(");
+ x = (float)t.readNumber();
+ t.readSymbol(",");
+ y = (float)t.readNumber();
+ t.readSymbol(",");
+ z = (float)t.readNumber();
+ t.readSymbol(")");
}
-//----------------------------------------------------------------------------
-Vector3 Vector3::operator/ (float fScalar) const {
- Vector3 kQuot;
-
- if ( fScalar != 0.0 ) {
- float fInvScalar = 1.0f / fScalar;
- kQuot.x = fInvScalar * x;
- kQuot.y = fInvScalar * y;
- kQuot.z = fInvScalar * z;
- return kQuot;
- } else {
- return Vector3::inf();
- }
+
+void Vector3::serialize(TextOutput& t) const {
+ t.writeSymbol("(");
+ t.writeNumber(x);
+ t.writeSymbol(",");
+ t.writeNumber(y);
+ t.writeSymbol(",");
+ t.writeNumber(z);
+ t.writeSymbol(")");
}
-//----------------------------------------------------------------------------
-Vector3& Vector3::operator/= (float fScalar) {
- if (fScalar != 0.0) {
- float fInvScalar = 1.0f / fScalar;
- x *= fInvScalar;
- y *= fInvScalar;
- z *= fInvScalar;
- } else {
- x = (float)G3D::inf();
- y = (float)G3D::inf();
- z = (float)G3D::inf();
- }
- return *this;
+void Vector3::serialize(BinaryOutput& b) const {
+ b.writeFloat32(x);
+ b.writeFloat32(y);
+ b.writeFloat32(z);
}
-//----------------------------------------------------------------------------
-float Vector3::unitize (float fTolerance) {
+
+Vector3 Vector3::random(Random& r) {
+ Vector3 result;
+ r.sphere(result.x, result.y, result.z);
+ return result;
+}
+
+
+float Vector3::unitize(float fTolerance) {
float fMagnitude = magnitude();
if (fMagnitude > fTolerance) {
@@ -147,10 +196,8 @@ float Vector3::unitize (float fTolerance) {
return fMagnitude;
}
-//----------------------------------------------------------------------------
Vector3 Vector3::reflectAbout(const Vector3& normal) const {
-
Vector3 out;
Vector3 N = normal.direction();
@@ -159,36 +206,49 @@ Vector3 Vector3::reflectAbout(const Vector3& normal) const {
return N * 2 * this->dot(N) - *this;
}
-//----------------------------------------------------------------------------
-#if 0
-Vector3 Vector3::cosRandom(const Vector3& normal) {
- double e1 = G3D::random(0, 1);
- double e2 = G3D::random(0, 1);
- // Angle from normal
- double theta = acos(sqrt(e1));
+Vector3 Vector3::cosHemiRandom(const Vector3& normal, Random& r) {
+ debugAssertM(G3D::fuzzyEq(normal.length(), 1.0f),
+ "cosHemiRandom requires its argument to have unit length");
- // Angle about normal
- double phi = 2 * G3D_PI * e2;
+ float x, y, z;
+ r.cosHemi(x, y, z);
// Make a coordinate system
- Vector3 U = normal.direction();
- Vector3 V = Vector3::unitX();
+ const Vector3& Z = normal;
- if (abs(U.dot(V)) > .9) {
- V = Vector3::unitY();
- }
+ Vector3 X, Y;
+ normal.getTangents(X, Y);
+
+ return
+ x * X +
+ y * Y +
+ z * Z;
+}
+
+
+Vector3 Vector3::cosPowHemiRandom(const Vector3& normal, const float k, Random& r) {
+ debugAssertM(G3D::fuzzyEq(normal.length(), 1.0f),
+ "cosPowHemiRandom requires its argument to have unit length");
- Vector3 W = U.cross(V).direction();
- V = W.cross(U);
+ float x, y, z;
+ r.cosPowHemi(k, x, y, z);
- // Convert to rectangular form
- return cos(theta) * U + sin(theta) * (cos(phi) * V + sin(phi) * W);
+ // Make a coordinate system
+ const Vector3& Z = normal;
+
+ Vector3 X, Y;
+ normal.getTangents(X, Y);
+
+ return
+ x * X +
+ y * Y +
+ z * Z;
}
-//----------------------------------------------------------------------------
-Vector3 Vector3::hemiRandom(const Vector3& normal) {
- Vector3 V = Vector3::random();
+
+Vector3 Vector3::hemiRandom(const Vector3& normal, Random& r) {
+ const Vector3& V = Vector3::random(r);
if (V.dot(normal) < 0) {
return -V;
@@ -196,7 +256,7 @@ Vector3 Vector3::hemiRandom(const Vector3& normal) {
return V;
}
}
-#endif
+
//----------------------------------------------------------------------------
Vector3 Vector3::reflectionDirection(const Vector3& normal) const {
@@ -256,12 +316,12 @@ void Vector3::orthonormalize (Vector3 akVector[3]) {
akVector[0].unitize();
// compute u1
- float fDot0 = akVector[0].dot(akVector[1]);
+ float fDot0 = akVector[0].dot(akVector[1]);
akVector[1] -= akVector[0] * fDot0;
akVector[1].unitize();
// compute u2
- float fDot1 = akVector[1].dot(akVector[2]);
+ float fDot1 = akVector[1].dot(akVector[2]);
fDot0 = akVector[0].dot(akVector[2]);
akVector[2] -= akVector[0] * fDot0 + akVector[1] * fDot1;
akVector[2].unitize();
@@ -294,6 +354,7 @@ std::string Vector3::toString() const {
return G3D::format("(%g, %g, %g)", x, y, z);
}
+
//----------------------------------------------------------------------------
Matrix3 Vector3::cross() const {
@@ -302,6 +363,15 @@ Matrix3 Vector3::cross() const {
-y, x, 0);
}
+
+void serialize(const Vector3::Axis& a, class BinaryOutput& bo) {
+ bo.writeUInt8((uint8)a);
+}
+
+void deserialize(Vector3::Axis& a, class BinaryInput& bi) {
+ a = (Vector3::Axis)bi.readUInt8();
+}
+
//----------------------------------------------------------------------------
// 2-char swizzles
@@ -431,5 +501,7 @@ Vector4 Vector3::zzzz() const { return Vector4 (z, z, z, z); }
-} // namespace
+
+
+} // namespace
diff --git a/dep/src/g3dlite/Vector3int16.cpp b/dep/src/g3dlite/Vector3int16.cpp
new file mode 100644
index 00000000000..44069b85d8c
--- /dev/null
+++ b/dep/src/g3dlite/Vector3int16.cpp
@@ -0,0 +1,49 @@
+/**
+ @file Vector3int16.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2003-04-07
+ @edited 2006-01-17
+ */
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Vector3int16.h"
+#include "G3D/Vector3.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/format.h"
+
+namespace G3D {
+
+Vector3int16::Vector3int16(const class Vector3& v) {
+ x = (int16)iFloor(v.x + 0.5);
+ y = (int16)iFloor(v.y + 0.5);
+ z = (int16)iFloor(v.z + 0.5);
+}
+
+
+Vector3int16::Vector3int16(class BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Vector3int16::serialize(class BinaryOutput& bo) const {
+ bo.writeInt16(x);
+ bo.writeInt16(y);
+ bo.writeInt16(z);
+}
+
+
+void Vector3int16::deserialize(class BinaryInput& bi) {
+ x = bi.readInt16();
+ y = bi.readInt16();
+ z = bi.readInt16();
+}
+
+std::string Vector3int16::toString() const {
+ return G3D::format("(%d, %d, %d)", x, y, z);
+}
+
+}
diff --git a/dep/src/g3dlite/Vector3int32.cpp b/dep/src/g3dlite/Vector3int32.cpp
new file mode 100644
index 00000000000..3bd8e9f2bc2
--- /dev/null
+++ b/dep/src/g3dlite/Vector3int32.cpp
@@ -0,0 +1,57 @@
+/**
+ @file Vector3int32.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2008-07-01
+ @edited 2008-07-01
+ */
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Vector3int32.h"
+#include "G3D/Vector3int16.h"
+#include "G3D/Vector3.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/format.h"
+
+namespace G3D {
+
+Vector3int32::Vector3int32(const class Vector3& v) {
+ x = (int32)iFloor(v.x + 0.5);
+ y = (int32)iFloor(v.y + 0.5);
+ z = (int32)iFloor(v.z + 0.5);
+}
+
+
+Vector3int32::Vector3int32(const class Vector3int16& v) {
+ x = v.x;
+ y = v.y;
+ z = v.z;
+}
+
+
+Vector3int32::Vector3int32(class BinaryInput& bi) {
+ deserialize(bi);
+}
+
+
+void Vector3int32::serialize(class BinaryOutput& bo) const {
+ bo.writeInt32(x);
+ bo.writeInt32(y);
+ bo.writeInt32(z);
+}
+
+
+void Vector3int32::deserialize(class BinaryInput& bi) {
+ x = bi.readInt32();
+ y = bi.readInt32();
+ z = bi.readInt32();
+}
+
+std::string Vector3int32::toString() const {
+ return G3D::format("(%d, %d, %d)", x, y, z);
+}
+
+}
diff --git a/dep/src/g3dlite/Vector4.cpp b/dep/src/g3dlite/Vector4.cpp
index b38e6f7cb57..f6abc1a6e0c 100644
--- a/dep/src/g3dlite/Vector4.cpp
+++ b/dep/src/g3dlite/Vector4.cpp
@@ -1,23 +1,74 @@
/**
@file Vector4.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@created 2001-07-09
- @edited 2003-09-29
+ @edited 2009-11-29
*/
#include <stdlib.h>
#include <limits>
#include "G3D/Vector4.h"
-//#include "G3D/Color4.h"
+#include "G3D/Color4.h"
#include "G3D/g3dmath.h"
-#include "G3D/format.h"
#include "G3D/stringutils.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/Vector4int8.h"
+#include "G3D/Matrix4.h"
+#include "G3D/Any.h"
namespace G3D {
-unsigned int Vector4::hashCode() const {
+Vector4::Vector4(const Any& any) {
+ any.verifyName("Vector4");
+ any.verifyType(Any::TABLE, Any::ARRAY);
+ any.verifySize(4);
+
+ if (any.type() == Any::ARRAY) {
+ x = any[0];
+ y = any[1];
+ z = any[2];
+ w = any[3];
+ } else {
+ // Table
+ x = any["x"];
+ y = any["y"];
+ z = any["z"];
+ w = any["w"];
+ }
+}
+
+Vector4::operator Any() const {
+ Any any(Any::ARRAY, "Vector4");
+ any.append(x, y, z, w);
+ return any;
+}
+
+
+Vector4::Vector4(const Vector4int8& v) : x(v.x / 127.0f), y(v.y / 127.0f), z(v.z / 127.0f), w(v.w / 127.0f) {
+}
+
+
+const Vector4& Vector4::inf() {
+ static const Vector4 v((float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf());
+ return v;
+}
+
+
+const Vector4& Vector4::zero() {
+ static const Vector4 v(0,0,0,0);
+ return v;
+}
+
+const Vector4& Vector4::nan() {
+ static Vector4 v((float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan());
+ return v;
+}
+
+
+size_t Vector4::hashCode() const {
unsigned int xhash = (*(int*)(void*)(&x));
unsigned int yhash = (*(int*)(void*)(&y));
unsigned int zhash = (*(int*)(void*)(&z));
@@ -26,14 +77,14 @@ unsigned int Vector4::hashCode() const {
return xhash + (yhash * 37) + (zhash * 101) + (whash * 241);
}
-#if 0
+
Vector4::Vector4(const class Color4& c) {
x = c.r;
y = c.g;
z = c.b;
w = c.a;
}
-#endif
+
Vector4::Vector4(const Vector2& v1, const Vector2& v2) {
x = v1.x;
@@ -42,6 +93,7 @@ Vector4::Vector4(const Vector2& v1, const Vector2& v2) {
w = v2.y;
}
+
Vector4::Vector4(const Vector2& v1, float fz, float fw) {
x = v1.x;
y = v1.y;
@@ -49,13 +101,45 @@ Vector4::Vector4(const Vector2& v1, float fz, float fw) {
w = fw;
}
+Vector4::Vector4(BinaryInput& b) {
+ deserialize(b);
+}
+
+
+void Vector4::deserialize(BinaryInput& b) {
+ x = b.readFloat32();
+ y = b.readFloat32();
+ z = b.readFloat32();
+ w = b.readFloat32();
+}
+
+
+void Vector4::serialize(BinaryOutput& b) const {
+ b.writeFloat32(x);
+ b.writeFloat32(y);
+ b.writeFloat32(z);
+ b.writeFloat32(w);
+}
+
//----------------------------------------------------------------------------
+Vector4 Vector4::operator*(const Matrix4& M) const {
+ Vector4 result;
+ for (int i = 0; i < 4; ++i) {
+ result[i] = 0.0f;
+ for (int j = 0; j < 4; ++j) {
+ result[i] += (*this)[j] * M[j][i];
+ }
+ }
+ return result;
+}
+
+
Vector4 Vector4::operator/ (float fScalar) const {
Vector4 kQuot;
if ( fScalar != 0.0 ) {
- float fInvScalar = 1.0f / fScalar;
+ float fInvScalar = 1.0f / fScalar;
kQuot.x = fInvScalar * x;
kQuot.y = fInvScalar * y;
kQuot.z = fInvScalar * z;
@@ -69,18 +153,19 @@ Vector4 Vector4::operator/ (float fScalar) const {
//----------------------------------------------------------------------------
Vector4& Vector4::operator/= (float fScalar) {
if (fScalar != 0.0f) {
- float fInvScalar = 1.0f / fScalar;
+ float fInvScalar = 1.0f / fScalar;
x *= fInvScalar;
y *= fInvScalar;
z *= fInvScalar;
w *= fInvScalar;
} else {
- *this = Vector4::inf();
+ *this = Vector4::inf();
}
return *this;
}
+
//----------------------------------------------------------------------------
std::string Vector4::toString() const {
@@ -431,5 +516,5 @@ Vector4 Vector4::ywww() const { return Vector4 (y, w, w, w); }
Vector4 Vector4::zwww() const { return Vector4 (z, w, w, w); }
Vector4 Vector4::wwww() const { return Vector4 (w, w, w, w); }
-}; // namespace
+}; // namespace
diff --git a/dep/src/g3dlite/Vector4int8.cpp b/dep/src/g3dlite/Vector4int8.cpp
new file mode 100644
index 00000000000..70bd143e01d
--- /dev/null
+++ b/dep/src/g3dlite/Vector4int8.cpp
@@ -0,0 +1,58 @@
+/**
+ @file Vector4int8.cpp
+
+ Homogeneous vector class.
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2007-02-09
+ @edited 2007-02-09
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Vector4int8.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector4.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include <string>
+
+namespace G3D {
+
+Vector4int8::Vector4int8(const Vector4& source) {
+ x = iClamp(iRound(source.x), -128, 127);
+ y = iClamp(iRound(source.y), -128, 127);
+ z = iClamp(iRound(source.z), -128, 127);
+ w = iClamp(iRound(source.w), -128, 127);
+}
+
+Vector4int8::Vector4int8(const Vector3& source, int8 w) : w(w) {
+ x = iClamp(iRound(source.x), -128, 127);
+ y = iClamp(iRound(source.y), -128, 127);
+ z = iClamp(iRound(source.z), -128, 127);
+}
+
+Vector4int8::Vector4int8(class BinaryInput& b) {
+ deserialize(b);
+}
+
+void Vector4int8::serialize(class BinaryOutput& b) const {
+ // Intentionally write individual bytes to avoid endian issues
+ b.writeInt8(x);
+ b.writeInt8(y);
+ b.writeInt8(z);
+ b.writeInt8(w);
+}
+
+void Vector4int8::deserialize(class BinaryInput& b) {
+ x = b.readInt8();
+ y = b.readInt8();
+ z = b.readInt8();
+ w = b.readInt8();
+}
+
+} // namespace G3D
+
diff --git a/dep/src/g3dlite/Welder.cpp b/dep/src/g3dlite/Welder.cpp
new file mode 100644
index 00000000000..b4f752f38bd
--- /dev/null
+++ b/dep/src/g3dlite/Welder.cpp
@@ -0,0 +1,416 @@
+/**
+ @file Welder.cpp
+
+ @author Morgan McGuire, Kyle Whitson, Corey Taylor
+
+ @created 2008-07-30
+ @edited 2009-11-29
+ */
+
+#include "G3D/platform.h"
+#include "G3D/Vector2.h"
+#include "G3D/Vector3.h"
+#include "G3D/Sphere.h"
+#include "G3D/PointHashGrid.h"
+#include "G3D/Welder.h"
+#include "G3D/Stopwatch.h" // for profiling
+#include "G3D/AreaMemoryManager.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D { namespace _internal{
+
+
+/** Used by WeldHelper2::smoothNormals. */
+class VN {
+public:
+ Vector3 vertex;
+ Vector3 normal;
+
+ VN() {}
+ VN(const Vector3& v, const Vector3& n) : vertex(v), normal(n) {}
+};
+
+/** Used by WeldHelper::getIndex to maintain a list of vertices by location. */
+class VNTi {
+public:
+ Vector3 vertex;
+ Vector3 normal;
+ Vector2 texCoord;
+ int index;
+
+ VNTi() : index(0) {}
+
+ VNTi(const Vector3& v, const Vector3& n, const Vector2& t, int i) :
+ vertex(v), normal(n), texCoord(t), index(i) {}
+};
+
+
+}} // G3D
+
+template <> struct HashTrait <G3D::_internal::VN> {
+ static size_t hashCode(const G3D::_internal::VN& k) { return static_cast<size_t>(k.vertex.hashCode()); }
+};
+template <> struct HashTrait <G3D::_internal::VNTi> {
+ static size_t hashCode(const G3D::_internal::VNTi& k) { return static_cast<size_t>(k.vertex.hashCode()); }
+};
+
+
+template<> struct EqualsTrait <G3D::_internal::VN> {
+ static bool equals(const G3D::_internal::VN& a, const G3D::_internal::VN& b) { return a.vertex == b.vertex; }
+};
+template<> struct EqualsTrait <G3D::_internal::VNTi> {
+ static bool equals(const G3D::_internal::VNTi& a, const G3D::_internal::VNTi& b) { return a.vertex == b.vertex; }
+};
+
+template<> struct PositionTrait<G3D::_internal::VN> {
+ static void getPosition(const G3D::_internal::VN& v, G3D::Vector3& p) { p = v.vertex; }
+};
+template<> struct PositionTrait<G3D::_internal::VNTi> {
+ static void getPosition(const G3D::_internal::VNTi& v, G3D::Vector3& p) { p = v.vertex; }
+};
+
+namespace G3D { namespace _internal {
+
+class WeldHelper {
+private:
+ /** Used by getIndex and updateTriLists */
+ PointHashGrid<VNTi> weldGrid;
+
+ Array<Vector3>* outputVertexArray;
+ Array<Vector3>* outputNormalArray;
+ Array<Vector2>* outputTexCoordArray;
+
+ float vertexWeldRadius;
+ /** Squared radius allowed for welding similar normals. */
+ float normalWeldRadius2;
+ float texCoordWeldRadius2;
+
+ float normalSmoothingAngle;
+
+ /**
+ Returns the index of the vertex in
+ outputVertexArray/outputNormalArray/outputTexCoordArray
+ that is within the global tolerances of v,n,t. If there
+ is no such vertex, adds it to the arrays and returns that index.
+
+ Called from updateTriLists().
+ */
+ int getIndex(const Vector3& v, const Vector3& n, const Vector2& t) {
+ PointHashGrid<VNTi>::SphereIterator it =
+ weldGrid.beginSphereIntersection(Sphere(v, vertexWeldRadius));
+
+ if (n.isZero()) {
+ // Don't bother trying to match the surface normal, since this vertex has no surface normal.
+ while (it.hasMore()) {
+ if ((t - it->texCoord).squaredLength() <= texCoordWeldRadius2) {
+ // This is the vertex
+ return it->index;
+ }
+ ++it;
+ }
+ } else {
+ while (it.hasMore()) {
+ if (((n - it->normal).squaredLength() <= normalWeldRadius2) &&
+ ((t - it->texCoord).squaredLength() <= texCoordWeldRadius2)) {
+ // This is the vertex
+ return it->index;
+ }
+ ++it;
+ }
+ }
+
+ // Note that a sliver triangle processed before its neighbors may reach here
+ // with a zero length normal.
+
+ // The vertex does not exist. Create it.
+ const int i = outputVertexArray->size();
+ outputVertexArray->append(v);
+ outputNormalArray->append(n);
+ outputTexCoordArray->append(t);
+
+ // Store in the grid so that it will be remembered.
+ weldGrid.insert(VNTi(v, n, t, i));
+
+ return i;
+ }
+
+
+ /**
+ Updates each indexArray to refer to vertices in the
+ outputVertexArray.
+
+ Called from process()
+ */
+ void updateTriLists(
+ Array<Array<int>*>& indexArrayArray,
+ const Array<Vector3>& vertexArray,
+ const Array<Vector3>& normalArray,
+ const Array<Vector2>& texCoordArray) {
+
+ // Compute a hash grid so that we can find neighbors quickly.
+ // It begins empty and is extended as the tri lists are iterated
+ // through.
+ weldGrid.clear();
+
+ // Process all triLists
+ int numTriLists = indexArrayArray.size();
+ int u = 0;
+ for (int t = 0; t < numTriLists; ++t) {
+ Array<int>& triList = *(indexArrayArray[t]);
+
+ // For all vertices in this list
+ for (int v = 0; v < triList.size(); ++v) {
+ // This vertex mapped to u in the flatVertexArray
+ triList[v] = getIndex(vertexArray[u], normalArray[u], texCoordArray[u]);
+
+ /*
+# ifdef G3D_DEBUG
+ {
+ int i = triList[v];
+ Vector3 N = normalArray[i];
+ debugAssertM(N.length() > 0.9f, "Produced non-unit normal");
+ }
+# endif
+ */
+ ++u;
+ }
+ }
+ }
+
+ /** Expands the indexed triangle lists into a triangle list.
+
+ Called from process() */
+ void unroll(
+ const Array<Array<int>*>& indexArrayArray,
+ const Array<Vector3>& vertexArray,
+ const Array<Vector2>& texCoordArray,
+ Array<Vector3>& unrolledVertexArray,
+ Array<Vector2>& unrolledTexCoordArray) {
+
+ int numTriLists = indexArrayArray.size();
+ for (int t = 0; t < numTriLists; ++t) {
+ const Array<int>& triList = *(indexArrayArray[t]);
+ for (int v = 0; v < triList.size(); ++v) {
+ int i = triList[v];
+ unrolledVertexArray.append(vertexArray[i]);
+ unrolledTexCoordArray.append(texCoordArray[i]);
+ }
+ }
+ }
+
+ /** For every three vertices, compute the face normal and store it three times.
+ Sliver triangles have a zero surface normal, which we will later take to
+ match *any* surface normal. */
+ void computeFaceNormals(
+ const Array<Vector3>& vertexArray,
+ Array<Vector3>& faceNormalArray) {
+
+ debugAssertM(vertexArray.size() % 3 == 0, "Input is not a triangle soup");
+ debugAssertM(faceNormalArray.size() == 0, "Output must start empty.");
+
+ for (int v = 0; v < vertexArray.size(); v += 3) {
+ const Vector3& e0 = vertexArray[v + 1] - vertexArray[v];
+ const Vector3& e1 = vertexArray[v + 2] - vertexArray[v];
+
+ // Note that the length may be zero in the case of sliver polygons, e.g.,
+ // those correcting a T-junction.
+ const Vector3& n = e0.cross(e1).directionOrZero();
+
+ // Append the normal once per vertex.
+ faceNormalArray.append(n, n, n);
+ }
+ }
+
+ /**
+ Computes @a smoothNormalArray, whose elements are those of normalArray averaged
+ with neighbors within the angular cutoff.
+ */
+ void smoothNormals(
+ const Array<Vector3>& vertexArray,
+ const Array<Vector3>& normalArray,
+ Array<Vector3>& smoothNormalArray) {
+
+ // Create an area memory manager for fast deallocation
+ MemoryManager::Ref mm = AreaMemoryManager::create(iRound(sizeof(VN) * normalArray.size() * 1.5));
+
+ if (normalSmoothingAngle <= 0) {
+ smoothNormalArray = normalArray;
+ return;
+ }
+
+ const float cosThresholdAngle = (float)cos(normalSmoothingAngle);
+
+ debugAssert(vertexArray.size() == normalArray.size());
+ smoothNormalArray.resize(normalArray.size());
+
+ // Compute a hash grid so that we can find neighbors quickly.
+ PointHashGrid<VN> grid(vertexWeldRadius, mm);
+ for (int v = 0; v < normalArray.size(); ++v) {
+ grid.insert(VN(vertexArray[v], normalArray[v]));
+ }
+
+ for (int v = 0; v < normalArray.size(); ++v) {
+ // Compute the sum of all nearby normals within the cutoff angle.
+ // Search within the vertexWeldRadius, since those are the vertices
+ // that will collapse to the same point.
+ PointHashGrid<VN>::SphereIterator it =
+ grid.beginSphereIntersection(Sphere(vertexArray[v], vertexWeldRadius));
+
+ Vector3 sum;
+
+ const Vector3& original = normalArray[v];
+ while (it.hasMore()) {
+ const Vector3& N = it->normal;
+ const float cosAngle = N.dot(original);
+
+ if (cosAngle > cosThresholdAngle) {
+ // This normal is close enough to consider
+ sum += N;
+ }
+ ++it;
+ }
+
+ const Vector3& average = sum.directionOrZero();
+
+ const bool indeterminate = average.isZero();
+ // Never "smooth" a normal so far that it points backwards
+ const bool backFacing = original.dot(average) < 0;
+
+ if (indeterminate || backFacing) {
+ // Revert to the face normal
+ smoothNormalArray[v] = original;
+ } else {
+ // Average available normals
+ smoothNormalArray[v] = average;
+ }
+ }
+ }
+
+public:
+
+
+ /**
+ Algorithm:
+
+ 1. Unroll the indexed triangle list into a triangle list, where
+ there are duplicated vertices.
+
+ 2. Compute face normals for all triangles, and expand those into
+ the triangle vertices.
+
+ 3. At each vertex, average all normals that are within normalSmoothingAngle.
+
+ 4. Generate output indexArrayArray. While doing so, merge all vertices where
+ the distance between position, texCoord, and normal is within the thresholds.
+ */
+ void process(
+ Array<Vector3>& vertexArray,
+ Array<Vector2>& texCoordArray,
+ Array<Vector3>& normalArray,
+ Array<Array<int>*>& indexArrayArray,
+ float normAngle,
+ float texRadius,
+ float normRadius) {
+
+ normalSmoothingAngle = normAngle;
+ normalWeldRadius2 = square(normRadius);
+ texCoordWeldRadius2 = square(texRadius);
+
+ const bool hasTexCoords = (texCoordArray.size() > 0);
+
+ if (hasTexCoords) {
+ debugAssertM(vertexArray.size() == texCoordArray.size(),
+ "Input arrays are not parallel.");
+ }
+
+ Array<Vector3> unrolledVertexArray;
+ Array<Vector3> unrolledFaceNormalArray;
+ Array<Vector3> unrolledSmoothNormalArray;
+ Array<Vector2> unrolledTexCoordArray;
+
+ if (! hasTexCoords) {
+ // Generate all zero texture coordinates
+ texCoordArray.resize(vertexArray.size());
+ }
+
+ // Generate a flat (unrolled) triangle list with texture coordinates.
+ unroll(indexArrayArray, vertexArray, texCoordArray,
+ unrolledVertexArray, unrolledTexCoordArray);
+
+ // Put the output back into the input slots.
+ outputVertexArray = &vertexArray;
+ outputNormalArray = &normalArray;
+ outputTexCoordArray = &texCoordArray;
+ outputVertexArray->fastClear();
+ outputNormalArray->fastClear();
+ outputTexCoordArray->fastClear();
+
+ // For every three vertices, generate their face normal and store it at
+ // each vertex. The output array has the same length as the input.
+ computeFaceNormals(unrolledVertexArray, unrolledFaceNormalArray);
+
+ // Compute smooth normals at vertices.
+ if (unrolledFaceNormalArray.size() > 0) {
+ smoothNormals(unrolledVertexArray, unrolledFaceNormalArray, unrolledSmoothNormalArray);
+ unrolledFaceNormalArray.clear();
+ }
+
+ // Regenerate the triangle lists
+ updateTriLists(indexArrayArray, unrolledVertexArray, unrolledSmoothNormalArray, unrolledTexCoordArray);
+
+ if (! hasTexCoords) {
+ // Throw away the generated texCoords
+ texCoordArray.resize(0);
+ }
+ }
+
+ WeldHelper(float vertRadius) :
+ weldGrid(vertRadius),
+ vertexWeldRadius(vertRadius) {}
+
+};
+} // Internal
+
+void Welder::weld(
+ Array<Vector3>& vertexArray,
+ Array<Vector2>& texCoordArray,
+ Array<Vector3>& normalArray,
+ Array<Array<int>*>& indexArrayArray,
+ const Welder::Settings& settings) {
+
+ _internal::WeldHelper(settings.vertexWeldRadius).process(
+ vertexArray, texCoordArray, normalArray, indexArrayArray,
+ settings.normalSmoothingAngle, settings.textureWeldRadius, settings.normalWeldRadius);
+}
+
+
+Welder::Settings::Settings(const Any& any) {
+ *this = Settings();
+ any.verifyName("Welder::Settings");
+ for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
+ const std::string& key = toLower(it->key);
+ if (key == "normalsmoothingangle") {
+ normalSmoothingAngle = it->value;
+ } else if (key == "vertexweldradius") {
+ vertexWeldRadius = it->value;
+ } else if (key == "textureweldradius") {
+ textureWeldRadius = it->value;
+ } else if (key == "normalweldradius") {
+ normalWeldRadius = it->value;
+ } else {
+ any.verify(false, "Illegal key: " + it->key);
+ }
+ }
+}
+
+Welder::Settings::operator Any() const {
+ Any a(Any::TABLE, "Welder::Settings");
+ a.set("normalSmoothingAngle", normalSmoothingAngle);
+ a.set("vertexWeldRadius", vertexWeldRadius);
+ a.set("textureWeldRadius", textureWeldRadius);
+ a.set("normalWeldRadius", normalWeldRadius);
+ return a;
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/WinMain.cpp b/dep/src/g3dlite/WinMain.cpp
new file mode 100644
index 00000000000..3cee71084e4
--- /dev/null
+++ b/dep/src/g3dlite/WinMain.cpp
@@ -0,0 +1,159 @@
+/*
+ Dervied from SDL_main.c, which was placed in the public domain by Sam Lantinga 4/13/98
+
+ The WinMain function -- calls your program's main() function
+*/
+
+#include "G3D/platform.h"
+
+#ifdef G3D_WIN32
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cctype>
+
+#ifdef main
+# ifndef _WIN32_WCE_EMULATION
+# undef main
+# endif /* _WIN32_WCE_EMULATION */
+#endif /* main */
+
+#if defined(_WIN32_WCE) && _WIN32_WCE < 300
+/* seems to be undefined in Win CE although in online help */
+#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t'))
+#endif /* _WIN32_WCE < 300 */
+
+// Turn off the G3D for loop scoping for C++
+#ifdef for
+# undef for
+#endif
+
+extern int main(int argc, const char** argv);
+
+/* Parse a command line buffer into arguments */
+static int ParseCommandLine(char *cmdline, char **argv) {
+ char *bufp;
+ int argc;
+
+ argc = 0;
+ for (bufp = cmdline; *bufp;) {
+ /* Skip leading whitespace */
+ while (isspace(*bufp)) {
+ ++bufp;
+ }
+ /* Skip over argument */
+ if (*bufp == '"') {
+ ++bufp;
+ if (*bufp) {
+ if (argv) {
+ argv[argc] = bufp;
+ }
+ ++argc;
+ }
+ /* Skip over word */
+ while (*bufp && (*bufp != '"')) {
+ ++bufp;
+ }
+ } else {
+ if (*bufp) {
+ if (argv) {
+ argv[argc] = bufp;
+ }
+ ++argc;
+ }
+ /* Skip over word */
+ while (*bufp && !isspace(*bufp)) {
+ ++bufp;
+ }
+ }
+ if (*bufp) {
+ if (argv) {
+ *bufp = '\0';
+ }
+ ++bufp;
+ }
+ }
+ if (argv) {
+ argv[argc] = NULL;
+ }
+ return (argc);
+}
+
+/* Show an error message */
+static void ShowError(const char *title, const char *message) {
+/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */
+#ifdef USE_MESSAGEBOX
+ MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK);
+#else
+ fprintf(stderr, "%s: %s\n", title, message);
+#endif
+}
+
+/* Pop up an out of memory message, returns to Windows */
+static BOOL OutOfMemory(void) {
+ ShowError("Fatal Error", "Out of memory - aborting");
+ return FALSE;
+}
+
+
+int WINAPI G3D_WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {
+ char **argv;
+ int argc;
+ int status;
+ char *cmdline;
+# ifdef _WIN32_WCE
+ wchar_t *bufp;
+ int nLen;
+# else
+ char *bufp;
+ size_t nLen;
+# endif
+ (void)sw;
+ (void)szCmdLine;
+ (void)hInst;
+ (void)hPrev;
+
+#ifdef _WIN32_WCE
+#error WinCE not supported
+ /*
+ nLen = wcslen(szCmdLine) + 128 + 1;
+ bufp = SDL_stack_alloc(wchar_t, nLen * 2);
+ wcscpy(bufp, TEXT("\""));
+ GetModuleFileName(NULL, bufp + 1, 128 - 3);
+ wcscpy(bufp + wcslen(bufp), TEXT("\" "));
+ wcsncpy(bufp + wcslen(bufp), szCmdLine, nLen - wcslen(bufp));
+ nLen = wcslen(bufp) + 1;
+ cmdline = SDL_stack_alloc(char, nLen);
+ if (cmdline == NULL) {
+ return OutOfMemory();
+ }
+ WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL);
+ */
+#else
+ /* Grab the command line */
+ bufp = GetCommandLineA();
+ nLen = strlen(bufp) + 1;
+ cmdline = (char*)malloc(sizeof(char) * nLen);
+ if (cmdline == NULL) {
+ return OutOfMemory();
+ }
+ strncpy(cmdline, bufp, nLen);
+#endif
+
+ /* Parse it into argv and argc */
+ argc = ParseCommandLine(cmdline, NULL);
+ argv = (char**)malloc(sizeof(char*) * (argc + 1));
+ if (argv == NULL) {
+ return OutOfMemory();
+ }
+ ParseCommandLine(cmdline, argv);
+
+ /* Run the main program */
+ status = main(argc, (const char**)argv);
+ free(argv);
+ free(cmdline);
+
+ return status;
+}
+
+#endif // if Win32
diff --git a/dep/src/g3dlite/constants.cpp b/dep/src/g3dlite/constants.cpp
new file mode 100644
index 00000000000..52cad3cd90b
--- /dev/null
+++ b/dep/src/g3dlite/constants.cpp
@@ -0,0 +1,82 @@
+/**
+ @file constants.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2009-05-20
+ @edited 2010-01-29
+*/
+#include "G3D/constants.h"
+#include "G3D/Any.h"
+#include "G3D/stringutils.h"
+
+namespace G3D {
+
+const std::string MirrorQuality::str[] = {"NONE", "STATIC_ENV", "DYNAMIC_PLANAR", "DYNAMIC_ENV", "BEST"};
+const MirrorQuality::Value MirrorQuality::enm[] = {MirrorQuality::NONE, MirrorQuality::STATIC_ENV,
+ MirrorQuality::DYNAMIC_PLANAR, MirrorQuality::DYNAMIC_ENV, MirrorQuality::BEST};
+
+MirrorQuality::MirrorQuality(const class Any& any) {
+ *this = any;
+}
+
+
+MirrorQuality& MirrorQuality::operator=(const Any& any) {
+ const std::string& s = toUpper(any.string());
+
+ for (int i = 0; ! str[i].empty(); ++i) {
+ if (s == str[i]) {
+ value = enm[i];
+ return *this;
+ }
+ }
+
+ any.verify(false, "Unrecognized MirrorQuality constant");
+ return *this;
+}
+
+
+MirrorQuality::operator Any() const {
+ return toString();
+}
+
+
+const std::string& MirrorQuality::toString() const {
+ return str[value];
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const std::string RefractionQuality::str[] = {"NONE", "STATIC_ENV", "DYNAMIC_FLAT", "DYNAMIC_FLAT_MULTILAYER", "DYNAMIC_ENV", "BEST"};
+const RefractionQuality::Value RefractionQuality::enm[] = {RefractionQuality::NONE, RefractionQuality::STATIC_ENV,
+ RefractionQuality::DYNAMIC_FLAT, RefractionQuality::DYNAMIC_FLAT_MULTILAYER, RefractionQuality::DYNAMIC_ENV, RefractionQuality::BEST};
+
+RefractionQuality::RefractionQuality(const class Any& any) {
+ *this = any;
+}
+
+
+RefractionQuality& RefractionQuality::operator=(const Any& any) {
+ const std::string& s = toUpper(any.string());
+
+ for (int i = 0; ! str[i].empty(); ++i) {
+ if (s == str[i]) {
+ value = enm[i];
+ return *this;
+ }
+ }
+
+ any.verify(false, "Unrecognized RefractionQuality constant");
+ return *this;
+}
+
+
+RefractionQuality::operator Any() const {
+ return toString();
+}
+
+
+const std::string& RefractionQuality::toString() const {
+ return str[value];
+}
+
+} // G3D
diff --git a/dep/src/g3dlite/debugAssert.cpp b/dep/src/g3dlite/debugAssert.cpp
new file mode 100644
index 00000000000..a87161b261f
--- /dev/null
+++ b/dep/src/g3dlite/debugAssert.cpp
@@ -0,0 +1,389 @@
+/**
+ @file debugAssert.cpp
+
+ Windows implementation of assertion routines.
+
+ @maintainer Morgan McGuire, graphics3d.com
+
+ @created 2001-08-26
+ @edited 2009-06-02
+ */
+
+#include "G3D/debugAssert.h"
+#include "G3D/platform.h"
+#ifdef G3D_WIN32
+ #include <tchar.h>
+#endif
+#include "G3D/format.h"
+#include "G3D/prompt.h"
+#include <string>
+#include "G3D/debugPrintf.h"
+#include "G3D/Log.h"
+
+#include <cstdlib>
+
+#ifdef _MSC_VER
+ // disable: "C++ exception handler used"
+# pragma warning (push)
+# pragma warning (disable : 4530)
+#endif
+
+using namespace std;
+
+namespace G3D { namespace _internal {
+
+ConsolePrintHook _consolePrintHook;
+AssertionHook _debugHook = _handleDebugAssert_;
+AssertionHook _failureHook = _handleErrorCheck_;
+
+#ifdef G3D_LINUX
+#if SOMEONE_MADE_THIS_USEFUL
+ Display* x11Display = NULL;
+ Window x11Window = 0;
+#endif
+#endif
+
+
+#ifdef G3D_WIN32
+static void postToClipboard(const char *text) {
+ if (OpenClipboard(NULL)) {
+ HGLOBAL hMem = GlobalAlloc(GHND | GMEM_DDESHARE, strlen(text) + 1);
+ if (hMem) {
+ char *pMem = (char*)GlobalLock(hMem);
+ strcpy(pMem, text);
+ GlobalUnlock(hMem);
+
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT, hMem);
+ }
+
+ CloseClipboard();
+ GlobalFree(hMem);
+ }
+}
+#endif
+
+/**
+ outTitle should be set before the call
+ */
+static void createErrorMessage(
+ const char* expression,
+ const std::string& message,
+ const char* filename,
+ int lineNumber,
+ std::string& outTitle,
+ std::string& outMessage) {
+
+ std::string le = "";
+ const char* newline = "\n";
+
+ #ifdef G3D_WIN32
+ newline = "\r\n";
+
+ // The last error value. (Which is preserved across the call).
+ DWORD lastErr = GetLastError();
+
+ // The decoded message from FormatMessage
+ LPTSTR formatMsg = NULL;
+
+ if (NULL == formatMsg) {
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ lastErr,
+ 0,
+ (LPTSTR)&formatMsg,
+ 0,
+ NULL);
+ }
+
+ // Make sure the message got translated into something.
+ LPTSTR realLastErr;
+ if (NULL != formatMsg) {
+ realLastErr = formatMsg;
+ } else {
+ realLastErr = _T("Last error code does not exist.");
+ }
+
+ if (lastErr != 0) {
+ le = G3D::format("Last Error (0x%08X): %s\r\n\r\n", lastErr, (LPCSTR)realLastErr);
+ }
+
+ // Get rid of the allocated memory from FormatMessage.
+ if (NULL != formatMsg) {
+ LocalFree((LPVOID)formatMsg);
+ }
+
+ char modulePath[MAX_PATH];
+ GetModuleFileNameA(NULL, modulePath, MAX_PATH);
+
+ const char* moduleName = strrchr(modulePath, '\\');
+ outTitle = outTitle + string(" - ") + string(moduleName ? (moduleName + 1) : modulePath);
+
+ #endif
+
+ // Build the message.
+ outMessage =
+ G3D::format("%s%s%sExpression: %s%s%s:%d%s%s%s",
+ message.c_str(), newline, newline, expression, newline,
+ filename, lineNumber, newline, newline, le.c_str());
+}
+
+
+bool _handleDebugAssert_(
+ const char* expression,
+ const std::string& message,
+ const char* filename,
+ int lineNumber,
+ bool useGuiPrompt) {
+
+ std::string dialogTitle = "Assertion Failure";
+ std::string dialogText = "";
+ createErrorMessage(expression, message, filename, lineNumber, dialogTitle, dialogText);
+
+ #ifdef G3D_WIN32
+ DWORD lastErr = GetLastError();
+ postToClipboard(dialogText.c_str());
+ debugPrintf("\n%s\n", dialogText.c_str());
+ #endif
+
+ const int cBreak = 0;
+ const int cIgnore = 1;
+ const int cAbort = 2;
+
+ static const char* choices[] = {"Debug", "Ignore", "Exit"};
+
+ // Log the error
+ Log::common()->print(std::string("\n**************************\n\n") + dialogTitle + "\n" + dialogText);
+
+ int result = G3D::prompt(dialogTitle.c_str(), dialogText.c_str(), (const char**)choices, 3, useGuiPrompt);
+
+# ifdef G3D_WIN32
+ // Put the incoming last error back.
+ SetLastError(lastErr);
+# endif
+
+ switch (result) {
+ // -1 shouldn't actually occur because it means
+ // that we're in release mode.
+ case -1:
+ case cBreak:
+ return true;
+ break;
+
+ case cIgnore:
+ return false;
+ break;
+
+ case cAbort:
+ exit(-1);
+ break;
+ }
+
+ // Should never get here
+ return false;
+}
+
+
+bool _handleErrorCheck_(
+ const char* expression,
+ const std::string& message,
+ const char* filename,
+ int lineNumber,
+ bool useGuiPrompt) {
+
+ std::string dialogTitle = "Critical Error";
+ std::string dialogText = "";
+
+ createErrorMessage(expression, message, filename, lineNumber, dialogTitle, dialogText);
+
+ // Log the error
+ Log::common()->print(std::string("\n**************************\n\n") + dialogTitle + "\n" + dialogText);
+ #ifdef G3D_WIN32
+ DWORD lastErr = GetLastError();
+ (void)lastErr;
+ postToClipboard(dialogText.c_str());
+ debugPrintf("\n%s\n", dialogText.c_str());
+ #endif
+
+ static const char* choices[] = {"Ok"};
+
+ const std::string& m =
+ std::string("An internal error has occured in this program and it will now close. "
+ "The specific error is below. More information has been saved in \"") +
+ Log::getCommonLogFilename() + "\".\n" + dialogText;
+
+ int result = G3D::prompt("Error", m.c_str(), (const char**)choices, 1, useGuiPrompt);
+ (void)result;
+
+ return true;
+}
+
+
+#ifdef G3D_WIN32
+static HCURSOR oldCursor;
+static RECT oldCursorRect;
+static POINT oldCursorPos;
+static int oldShowCursorCount;
+#endif
+
+void _releaseInputGrab_() {
+ #ifdef G3D_WIN32
+
+ GetCursorPos(&oldCursorPos);
+
+ // Stop hiding the cursor if the application hid it.
+ oldShowCursorCount = ShowCursor(true) - 1;
+
+ if (oldShowCursorCount < -1) {
+ for (int c = oldShowCursorCount; c < -1; ++c) {
+ ShowCursor(true);
+ }
+ }
+
+ // Set the default cursor in case the application
+ // set the cursor to NULL.
+ oldCursor = GetCursor();
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ // Allow the cursor full access to the screen
+ GetClipCursor(&oldCursorRect);
+ ClipCursor(NULL);
+
+ #elif defined(G3D_LINUX)
+#if SOMEONE_MADE_THIS_USEFUL
+ if (x11Display != NULL) {
+ XUngrabPointer(x11Display, CurrentTime);
+ XUngrabKeyboard(x11Display, CurrentTime);
+ if (x11Window != 0) {
+ //XUndefineCursor(x11Display, x11Window);
+ // TODO: Note that we leak this cursor; it should be
+ // freed in the restore code.
+ Cursor c = XCreateFontCursor(x11Display, 68);
+ XDefineCursor(x11Display, x11Window, c);
+ }
+ XSync(x11Display, false);
+ XAllowEvents(x11Display, AsyncPointer, CurrentTime);
+ XFlush(x11Display);
+ }
+#endif
+ #elif defined(G3D_OSX)
+ // TODO: OS X
+ #endif
+}
+
+
+void _restoreInputGrab_() {
+ #ifdef G3D_WIN32
+
+ // Restore the old clipping region
+ ClipCursor(&oldCursorRect);
+
+ SetCursorPos(oldCursorPos.x, oldCursorPos.y);
+
+ // Restore the old cursor
+ SetCursor(oldCursor);
+
+ // Restore old visibility count
+ if (oldShowCursorCount < 0) {
+ for (int c = 0; c > oldShowCursorCount; --c) {
+ ShowCursor(false);
+ }
+ }
+
+ #elif defined(G3D_LINUX)
+ // TODO: Linux
+ #elif defined(G3D_OSX)
+ // TODO: OS X
+ #endif
+}
+
+
+}; // internal namespace
+
+void setAssertionHook(AssertionHook hook) {
+ G3D::_internal::_debugHook = hook;
+}
+
+AssertionHook assertionHook() {
+ return G3D::_internal::_debugHook;
+}
+
+void setFailureHook(AssertionHook hook) {
+ G3D::_internal::_failureHook = hook;
+}
+
+AssertionHook failureHook() {
+ return G3D::_internal::_failureHook;
+}
+
+
+void setConsolePrintHook(ConsolePrintHook h) {
+ G3D::_internal::_consolePrintHook = h;
+}
+
+ConsolePrintHook consolePrintHook() {
+ return G3D::_internal::_consolePrintHook;
+}
+
+
+std::string __cdecl debugPrint(const std::string& s) {
+# ifdef G3D_WIN32
+ const int MAX_STRING_LEN = 1024;
+
+ // Windows can't handle really long strings sent to
+ // the console, so we break the string.
+ if (s.size() < MAX_STRING_LEN) {
+ OutputDebugStringA(s.c_str());
+ } else {
+ for (unsigned int i = 0; i < s.size(); i += MAX_STRING_LEN) {
+ std::string sub = s.substr(i, MAX_STRING_LEN);
+ OutputDebugStringA(sub.c_str());
+ }
+ }
+# else
+ fprintf(stderr, "%s", s.c_str());
+ fflush(stderr);
+# endif
+
+ return s;
+}
+
+std::string __cdecl debugPrintf(const char* fmt ...) {
+ va_list argList;
+ va_start(argList, fmt);
+ std::string s = G3D::vformat(fmt, argList);
+ va_end(argList);
+
+ return debugPrint(s);
+// return debugPrint(consolePrint(s));
+}
+
+std::string consolePrint(const std::string& s) {
+ FILE* L = Log::common()->getFile();
+ fprintf(L, "%s", s.c_str());
+
+ if (consolePrintHook()) {
+ consolePrintHook()(s);
+ }
+
+ fflush(L);
+ return s;
+}
+
+
+std::string __cdecl consolePrintf(const char* fmt ...) {
+ va_list argList;
+ va_start(argList, fmt);
+ std::string s = G3D::vformat(fmt, argList);
+ va_end(argList);
+
+ return consolePrint(s);
+}
+
+} // namespace
+
+#ifdef _MSC_VER
+# pragma warning (pop)
+#endif
diff --git a/dep/src/g3dlite/fileutils.cpp b/dep/src/g3dlite/fileutils.cpp
new file mode 100644
index 00000000000..3f5eb579ba9
--- /dev/null
+++ b/dep/src/g3dlite/fileutils.cpp
@@ -0,0 +1,1165 @@
+/**
+ @file fileutils.cpp
+
+ @author Morgan McGuire, graphics3d.com
+
+ @author 2002-06-06
+ @edited 2010-02-05
+ */
+
+#include <cstring>
+#include <cstdio>
+#include "G3D/platform.h"
+#include "G3D/fileutils.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+#include "G3D/g3dmath.h"
+#include "G3D/stringutils.h"
+#include "G3D/Set.h"
+#include "G3D/g3dfnmatch.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#if _HAVE_ZIP
+ #include "zip.h"
+#endif
+
+#ifdef G3D_WIN32
+ // Needed for _getcwd
+ #include <direct.h>
+ #include <io.h>
+#else
+ #include <dirent.h>
+ #include <fnmatch.h>
+ #include <unistd.h>
+ #define _getcwd getcwd
+ #define _stat stat
+#endif
+
+
+namespace G3D {
+
+namespace _internal {
+ Set<std::string> currentFilesUsed;
+}
+
+std::string pathConcat(const std::string& dirname, const std::string& file) {
+ // Ensure that the directory ends in a slash
+ if ((dirname.size() != 0) &&
+ (dirname[dirname.size() - 1] != '/') &&
+ (dirname[dirname.size() - 1] != '\\') &&
+ (dirname[dirname.size() - 1] != ':')) {
+ return dirname + '/' + file;
+ } else {
+ return dirname + file;
+ }
+}
+
+std::string resolveFilename(const std::string& filename) {
+ if (filename.size() >= 1) {
+ if ((filename[0] == '/') || (filename[0] == '\\')) {
+ // Already resolved
+ return filename;
+ } else {
+
+ #ifdef G3D_WIN32
+ if ((filename.size() >= 2) && (filename[1] == ':')) {
+ // There is a drive spec on the front.
+ if ((filename.size() >= 3) && ((filename[2] == '\\') ||
+ (filename[2] == '/'))) {
+ // Already fully qualified
+ return filename;
+ } else {
+ // The drive spec is relative to the
+ // working directory on that drive.
+ debugAssertM(false, "Files of the form d:path are"
+ " not supported (use a fully qualified"
+ " name).");
+ return filename;
+ }
+ }
+ #endif
+ }
+ }
+
+ char buffer[1024];
+
+ // Prepend the working directory.
+ _getcwd(buffer, 1024);
+
+ return format("%s/%s", buffer, filename.c_str());
+}
+
+bool zipfileExists(const std::string& filename) {
+ std::string outZipfile;
+ std::string outInternalFile;
+ return zipfileExists(filename, outZipfile, outInternalFile);
+}
+
+std::string readWholeFile(
+ const std::string& filename) {
+
+ _internal::currentFilesUsed.insert(filename);
+
+ std::string s;
+
+ debugAssert(filename != "");
+ if (fileExists(filename, false)) {
+
+ int64 length = fileLength(filename);
+
+ char* buffer = (char*)System::alignedMalloc(length + 1, 16);
+ debugAssert(buffer);
+ FILE* f = fopen(filename.c_str(), "rb");
+ debugAssert(f);
+ int ret = fread(buffer, 1, length, f);
+ debugAssert(ret == length);(void)ret;
+ fclose(f);
+
+ buffer[length] = '\0';
+ s = std::string(buffer);
+
+ System::alignedFree(buffer);
+
+ } else if (zipfileExists(filename)) {
+
+ void* zipBuffer;
+ size_t length;
+ zipRead(filename, zipBuffer, length);
+
+ char* buffer = (char*)System::alignedMalloc(length + 1, 16);
+ System::memcpy(buffer,zipBuffer, length + 1);
+ zipClose(zipBuffer);
+
+ buffer[length] = '\0';
+ s = std::string(buffer);
+ System::alignedFree(buffer);
+ } else {
+ debugAssertM(false, filename + " not found");
+ }
+
+ return s;
+}
+
+
+void zipRead(const std::string& file,
+ void*& data,
+ size_t& length) {
+ std::string zip, desiredFile;
+#if _HAVE_ZIP
+ if (zipfileExists(file, zip, desiredFile)) {
+ struct zip *z = zip_open( zip.c_str(), ZIP_CHECKCONS, NULL );
+ {
+ struct zip_stat info;
+ zip_stat_init( &info ); // TODO: Docs unclear if zip_stat_init is required.
+ zip_stat( z, desiredFile.c_str(), ZIP_FL_NOCASE, &info );
+ length = info.size;
+ // sets machines up to use MMX, if they want
+ data = System::alignedMalloc(length, 16);
+ struct zip_file *zf = zip_fopen( z, desiredFile.c_str(), ZIP_FL_NOCASE );
+ {
+ int test = zip_fread( zf, data, length );
+ debugAssertM((size_t)test == length,
+ desiredFile + " was corrupt because it unzipped to the wrong size.");
+ (void)test;
+ }
+ zip_fclose( zf );
+ }
+ zip_close( z );
+ } else {
+ data = NULL;
+ }
+#else
+ data = NULL;
+#endif
+}
+
+
+void zipClose(void* data) {
+ System::alignedFree(data);
+}
+
+
+int64 fileLength(const std::string& filename) {
+ struct _stat st;
+ int result = _stat(filename.c_str(), &st);
+
+ if (result == -1) {
+#if _HAVE_ZIP
+ std::string zip, contents;
+ if(zipfileExists(filename, zip, contents)){
+ int64 requiredMem;
+
+ struct zip *z = zip_open( zip.c_str(), ZIP_CHECKCONS, NULL );
+ debugAssertM(z != NULL, zip + ": zip open failed.");
+ {
+ struct zip_stat info;
+ zip_stat_init( &info ); // TODO: Docs unclear if zip_stat_init is required.
+ int success = zip_stat( z, contents.c_str(), ZIP_FL_NOCASE, &info );
+ debugAssertM(success == 0, zip + ": " + contents + ": zip stat failed.");
+ requiredMem = info.size;
+ }
+ zip_close( z );
+ return requiredMem;
+ } else {
+ return -1;
+ }
+#else
+ return -1;
+#endif
+ }
+
+ return st.st_size;
+}
+
+/** Used by robustTmpfile. Returns nonzero if fread, fwrite, and fseek all
+succeed on the file.
+ @author Morgan McGuire, http://graphics.cs.williams.edu */
+static int isFileGood(FILE* f) {
+
+ int x, n, result;
+
+ /* Must be a valid file handle */
+ if (f == NULL) {
+ return 0;
+ }
+
+ /* Try to write */
+ x = 1234;
+ n = fwrite(&x, sizeof(int), 1, f);
+
+ if (n != 1) {
+ return 0;
+ }
+
+ /* Seek back to the beginning */
+ result = fseek(f, 0, SEEK_SET);
+ if (result != 0) {
+ return 0;
+ }
+
+ /* Read */
+ n = fread(&x, sizeof(int), 1, f);
+ if (n != 1) {
+ return 0;
+ }
+
+ /* Seek back to the beginning again */
+ fseek(f, 0, SEEK_SET);
+
+ return 1;
+}
+
+FILE* createTempFile() {
+ FILE* t = NULL;
+
+//# ifdef G3D_WIN32
+ t = tmpfile();
+//# else
+// // On Unix, tmpfile generates a warning for any code that links against it.
+// const char* tempfilename = "/tmp/g3dtemp.XXXXXXXX";
+// mktemp(tempfilename);
+// t = fopen(tempfilename, "w");
+//# endif
+
+# ifdef _WIN32
+ char* n = NULL;
+# endif
+ char name[256];
+
+ if (isFileGood(t)) {
+ return t;
+ }
+
+# ifdef G3D_WIN32
+ /* tmpfile failed; try the tmpnam routine */
+ t = fopen(tmpnam(NULL), "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+
+ n = _tempnam("c:/tmp/", "t");
+ /* Try to create something in C:\tmp */
+ t = fopen(n, "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+
+ /* Try c:\temp */
+ n = _tempnam("c:/temp/", "t");
+ t = fopen(n, "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+
+ /* try the current directory */
+ n = _tempnam("./", "t");
+ t = fopen(n, "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+
+ sprintf(name, "%s/tmp%d", "c:/temp", rand());
+ t = fopen(name, "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+
+ /* Try some hardcoded paths */
+ sprintf(name, "%s/tmp%d", "c:/tmp", rand());
+ t = fopen(name, "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+# else
+ sprintf(name, "%s/tmp%d", "/tmp", rand());
+ t = fopen(name, "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+#endif
+
+ sprintf(name, "tmp%d", rand());
+ t = fopen(name, "w+");
+ if (isFileGood(t)) {
+ return t;
+ }
+
+ fprintf(stderr, "Unable to create a temporary file; robustTmpfile returning NULL\n");
+
+ return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void writeWholeFile(
+ const std::string& filename,
+ const std::string& str,
+ bool flush) {
+
+ // Make sure the directory exists.
+ std::string root, base, ext, path;
+ Array<std::string> pathArray;
+ parseFilename(filename, root, pathArray, base, ext);
+
+ path = root + stringJoin(pathArray, '/');
+ if (! fileExists(path, false)) {
+ createDirectory(path);
+ }
+
+ FILE* file = fopen(filename.c_str(), "wb");
+
+ debugAssert(file);
+
+ fwrite(str.c_str(), str.size(), 1, file);
+
+ if (flush) {
+ fflush(file);
+ }
+ fclose(file);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ Creates the directory (which may optionally end in a /)
+ and any parents needed to reach it.
+ */
+void createDirectory(
+ const std::string& dir) {
+
+ if (dir == "") {
+ return;
+ }
+
+ std::string d;
+
+ // Add a trailing / if there isn't one.
+ switch (dir[dir.size() - 1]) {
+ case '/':
+ case '\\':
+ d = dir;
+ break;
+
+ default:
+ d = dir + "/";
+ }
+
+ // If it already exists, do nothing
+ if (fileExists(d.substr(0, d.size() - 1)), false) {
+ return;
+ }
+
+ // Parse the name apart
+ std::string root, base, ext;
+ Array<std::string> path;
+
+ std::string lead;
+ parseFilename(d, root, path, base, ext);
+ debugAssert(base == "");
+ debugAssert(ext == "");
+
+ // Begin with an extra period so "c:\" becomes "c:\.\" after
+ // appending a path and "c:" becomes "c:.\", not root: "c:\"
+ std::string p = root + ".";
+
+ // Create any intermediate that doesn't exist
+ for (int i = 0; i < path.size(); ++i) {
+ p += "/" + path[i];
+ if (! fileExists(p, false)) {
+ // Windows only requires one argument to mkdir,
+ // where as unix also requires the permissions.
+# ifndef G3D_WIN32
+ mkdir(p.c_str(), 0777);
+# else
+ _mkdir(p.c_str());
+# endif
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class FileSystemCache {
+private:
+
+ Table<std::string, Array<std::string> > m_files;
+
+public:
+
+ bool fileExists(const std::string& filename) {
+ const std::string& path = resolveFilename(filenamePath(filename));
+ const std::string& name = filenameBaseExt(filename);
+
+ bool neverBeforeSeen = false;
+ Array<std::string>& fileList = m_files.getCreate(path, neverBeforeSeen);
+ if (neverBeforeSeen) {
+ if (! G3D::fileExists(path, true, false)) {
+ // The path itself doesn't exist... back out our insertion (which makes fileList& invalid)
+ m_files.remove(path);
+ return false;
+ }
+
+ std::string spec = pathConcat(path, "*");
+
+ // Will automatically recurse into zipfiles
+ getFiles(spec, fileList);
+ getDirs(spec, fileList);
+
+# ifdef G3D_WIN32
+ {
+ // Case insensitive
+ for (int i = 0; i < fileList.size(); ++i) {
+ fileList[i] = toLower(fileList[i]);
+ }
+ }
+# endif
+ }
+
+ if (filenameContainsWildcards(name)) {
+ // See if anything matches
+ for (int i = 0; i < fileList.size(); ++i) {
+ if (g3dfnmatch(name.c_str(), fileList[i].c_str(), 0) == 0) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ // On windows, this is a lower-lower comparison, so it is case insensitive
+ return fileList.contains(name);
+ }
+ }
+
+ void clear() {
+ m_files.clear();
+ }
+
+ static FileSystemCache& instance() {
+ static FileSystemCache i;
+ return i;
+ }
+};
+
+
+void clearFileSystemCache() {
+ FileSystemCache::instance().clear();
+}
+
+bool fileExists
+(const std::string& _filename,
+ bool lookInZipfiles,
+ bool trustCache) {
+
+ if (_filename.empty()) {
+ return false;
+ }
+
+ // Remove trailing slash from directories
+ const std::string& filename = (endsWith(_filename, "/") || endsWith(_filename, "\\")) ? _filename.substr(0, _filename.length() - 1) : _filename;
+
+ if (trustCache && lookInZipfiles) {
+# ifdef G3D_WIN32
+ // Case insensitive
+ return FileSystemCache::instance().fileExists(toLower(filename));
+# else
+ return FileSystemCache::instance().fileExists(filename);
+# endif
+ }
+
+ // Useful for debugging
+ //char curdir[1024]; _getcwd(curdir, 1024);
+
+ struct _stat st;
+ int ret = _stat(filename.c_str(), &st);
+
+ // _stat returns zero on success
+ bool exists = (ret == 0);
+
+ if (! exists && lookInZipfiles) {
+ // Does not exist standalone, but might exist in a zipfile
+
+ // These output arguments will be ignored
+ std::string zipDir, internalPath;
+ return zipfileExists(filename, zipDir, internalPath);
+ } else {
+ return exists;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if _HAVE_ZIP
+/* Helper methods for zipfileExists()*/
+// Given a string (the drive) and an array (the path), computes the directory
+static void _zip_resolveDirectory(std::string& completeDir, const std::string& drive, const Array<std::string>& path, const int length){
+ completeDir = drive;
+ int tempLength;
+ // if the given length is longer than the array, we correct it
+ if(length > path.length()){
+ tempLength = path.length();
+ } else{
+ tempLength = length;
+ }
+
+ for(int t = 0; t < tempLength; ++t){
+ if(t > 0){
+ completeDir += "/";
+ }
+ completeDir += path[t];
+ }
+}
+
+
+// assumes that zipDir references a .zip file
+static bool _zip_zipContains(const std::string& zipDir, const std::string& desiredFile){
+ struct zip *z = zip_open( zipDir.c_str(), ZIP_CHECKCONS, NULL );
+ //the last parameter, an int, determines case sensitivity:
+ //1 is sensitive, 2 is not, 0 is default
+ int test = zip_name_locate( z, desiredFile.c_str(), ZIP_FL_NOCASE );
+ zip_close( z );
+ if(test == -1){
+ return false;
+ }
+ return true;
+}
+#endif
+
+// If no zipfile exists, outZipfile and outInternalFile are unchanged
+bool zipfileExists(const std::string& filename, std::string& outZipfile,
+ std::string& outInternalFile){
+#if _HAVE_ZIP
+ Array<std::string> path;
+ std::string drive, base, ext, zipfile, infile;
+ parseFilename(filename, drive, path, base, ext);
+
+ // Put the filename back together
+ if ((base != "") && (ext != "")) {
+ infile = base + "." + ext;
+ } else {
+ infile = base + ext;
+ }
+
+ // Remove "." from path
+ for (int i = 0; i < path.length(); ++i) {
+ if (path[i] == ".") {
+ path.remove(i);
+ --i;
+ }
+ }
+
+ // Remove ".." from path
+ for (int i = 1; i < path.length(); ++i) {
+ if ((path[i] == "..") && (i > 0) && (path[i - 1] != "..")) {
+ // Remove both i and i - 1
+ path.remove(i - 1, 2);
+ i -= 2;
+ }
+ }
+
+ // Walk the path backwards, accumulating pieces onto the infile until
+ // we find a zipfile that contains it
+ for (int t = 0; t < path.length(); ++t){
+ _zip_resolveDirectory(zipfile, drive, path, path.length() - t);
+ if (t > 0) {
+ infile = path[path.length() - t] + "/" + infile;
+ }
+
+ if (endsWith(zipfile, "..")) {
+ return false;
+ }
+
+ if (fileExists(zipfile, false)) {
+ // test if it actually is a zipfile
+ // if not, return false, a bad
+ // directory structure has been given,
+ // not a .zip
+ if (isZipfile(zipfile)){
+
+ if (_zip_zipContains(zipfile, infile)){
+ outZipfile = zipfile;
+ outInternalFile = infile;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // the directory structure was valid but did not point to a .zip
+ return false;
+ }
+ }
+
+ }
+#endif
+ // not a valid directory structure ever,
+ // obviously no .zip was found within the path
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+std::string generateFilenameBase(const std::string& prefix, const std::string& suffix) {
+ Array<std::string> exist;
+
+ // Note "template" is a reserved word in C++
+ std::string templat = prefix + System::currentDateString() + "_";
+ getFiles(templat + "*", exist);
+
+ // Remove extensions
+ for (int i = 0; i < exist.size(); ++i) {
+ exist[i] = filenameBase(exist[i]);
+ }
+
+ int num = 0;
+ std::string result;
+ templat += "%03d" + suffix;
+ do {
+ result = format(templat.c_str(), num);
+ ++num;
+ } while (exist.contains(result));
+
+ return result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void copyFile(
+ const std::string& source,
+ const std::string& dest) {
+
+ #ifdef G3D_WIN32
+ CopyFileA(source.c_str(), dest.c_str(), FALSE);
+ #else
+ // TODO: don't use BinaryInput and BinaryOutput
+ // Read it all in, then dump it out
+ BinaryInput in(source, G3D_LITTLE_ENDIAN);
+ BinaryOutput out(dest, G3D_LITTLE_ENDIAN);
+ out.writeBytes(in.getCArray(), in.size());
+ out.commit(false);
+ #endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void parseFilename(
+ const std::string& filename,
+ std::string& root,
+ Array<std::string>& path,
+ std::string& base,
+ std::string& ext) {
+
+ std::string f = filename;
+
+ root = "";
+ path.clear();
+ base = "";
+ ext = "";
+
+ if (f == "") {
+ // Empty filename
+ return;
+ }
+
+ // See if there is a root/drive spec.
+ if ((f.size() >= 2) && (f[1] == ':')) {
+
+ if ((f.size() > 2) && isSlash(f[2])) {
+
+ // e.g. c:\foo
+ root = f.substr(0, 3);
+ f = f.substr(3, f.size() - 3);
+
+ } else {
+
+ // e.g. c:foo
+ root = f.substr(2);
+ f = f.substr(2, f.size() - 2);
+
+ }
+
+ } else if ((f.size() >= 2) & isSlash(f[0]) && isSlash(f[1])) {
+
+ // e.g. //foo
+ root = f.substr(0, 2);
+ f = f.substr(2, f.size() - 2);
+
+ } else if (isSlash(f[0])) {
+
+ root = f.substr(0, 1);
+ f = f.substr(1, f.size() - 1);
+
+ }
+
+ // Pull the extension off
+ {
+ // Find the period
+ size_t i = f.rfind('.');
+
+ if (i != std::string::npos) {
+ // Make sure it is after the last slash!
+ size_t j = iMax(f.rfind('/'), f.rfind('\\'));
+ if ((j == std::string::npos) || (i > j)) {
+ ext = f.substr(i + 1, f.size() - i - 1);
+ f = f.substr(0, i);
+ }
+ }
+ }
+
+ // Pull the basename off
+ {
+ // Find the last slash
+ size_t i = iMax(f.rfind('/'), f.rfind('\\'));
+
+ if (i == std::string::npos) {
+
+ // There is no slash; the basename is the whole thing
+ base = f;
+ f = "";
+
+ } else if ((i != std::string::npos) && (i < f.size() - 1)) {
+
+ base = f.substr(i + 1, f.size() - i - 1);
+ f = f.substr(0, i);
+
+ }
+ }
+
+ // Parse what remains into path.
+ size_t prev, cur = 0;
+
+ while (cur < f.size()) {
+ prev = cur;
+
+ // Allow either slash
+ size_t i = f.find('/', prev + 1);
+ size_t j = f.find('\\', prev + 1);
+ if (i == std::string::npos) {
+ i = f.size();
+ }
+
+ if (j == std::string::npos) {
+ j = f.size();
+ }
+
+ cur = iMin(i, j);
+
+ if (cur == std::string::npos) {
+ cur = f.size();
+ }
+
+ path.append(f.substr(prev, cur - prev));
+ ++cur;
+ }
+}
+
+
+/**
+ Helper for getFileList and getDirectoryList.
+
+ @param wantFiles If false, returns the directories, otherwise
+ returns the files.
+ @param includePath If true, the names include paths
+ */
+static void getFileOrDirListNormal
+(const std::string& filespec,
+ Array<std::string>& files,
+ bool wantFiles,
+ bool includePath) {
+
+ bool test = wantFiles ? true : false;
+
+ std::string path = "";
+
+ // Find the place where the path ends and the file-spec begins
+ size_t i = filespec.rfind('/');
+ size_t j = filespec.rfind('\\');
+
+ // Drive letters on Windows can separate a path
+ size_t k = filespec.rfind(':');
+
+ if (((j != std::string::npos) && (j > i)) ||
+ (i == std::string::npos)) {
+ i = j;
+ }
+
+ if (((k != std::string::npos) && (k > i)) ||
+ (i == std::string::npos)) {
+ i = k;
+ }
+
+ // If there is a path, pull it off
+ if (i != std::string::npos) {
+ path = filespec.substr(0, i + 1);
+ }
+
+ std::string prefix = path;
+
+ if (path.size() > 0) {
+ // Strip the trailing character
+ path = path.substr(0, path.size() - 1);
+ }
+
+# ifdef G3D_WIN32
+ {
+ struct _finddata_t fileinfo;
+
+ long handle = _findfirst(filespec.c_str(), &fileinfo);
+ int result = handle;
+
+ while (result != -1) {
+ if ((((fileinfo.attrib & _A_SUBDIR) == 0) == test) &&
+ strcmp(fileinfo.name, ".") &&
+ strcmp(fileinfo.name, "..")) {
+
+ if (includePath) {
+ files.append(prefix + fileinfo.name);
+ } else {
+ files.append(fileinfo.name);
+ }
+ }
+
+ result = _findnext(handle, &fileinfo);
+ }
+ }
+# else
+ {
+ if (path == "") {
+ // Empty paths don't work on Unix
+ path = ".";
+ }
+
+ // Unix implementation
+ DIR* dir = opendir(path.c_str());
+
+ if (dir != NULL) {
+ struct dirent* entry = readdir(dir);
+
+ while (entry != NULL) {
+
+ // Exclude '.' and '..'
+ if ((strcmp(entry->d_name, ".") != 0) &&
+ (strcmp(entry->d_name, "..") != 0)) {
+
+ // Form a name with a path
+ std::string filename = prefix + entry->d_name;
+ // See if this is a file or a directory
+ struct _stat st;
+ bool exists = _stat(filename.c_str(), &st) != -1;
+
+ if (exists &&
+
+ // Make sure it has the correct type
+ (((st.st_mode & S_IFDIR) == 0) == test) &&
+
+ // Make sure it matches the wildcard
+ (fnmatch(filespec.c_str(),
+ filename.c_str(),
+ FNM_PATHNAME) == 0)) {
+
+ if (includePath) {
+ files.append(filename);
+ } else {
+ files.append(entry->d_name);
+ }
+ }
+ }
+
+ entry = readdir(dir);
+ }
+ closedir(dir);
+ }
+ }
+# endif
+}
+
+#if _HAVE_ZIP
+/**
+ @param path The zipfile name (no trailing slash)
+ @param prefix Directory inside the zipfile. No leading slash, must have trailing slash if non-empty.
+ @param file Name inside the zipfile that we are testing to see if it matches prefix + "*"
+ */
+static void _zip_addEntry(const std::string& path,
+ const std::string& prefix,
+ const std::string& file,
+ Set<std::string>& files,
+ bool wantFiles,
+ bool includePath) {
+
+ // Make certain we are within the desired parent folder (prefix)
+ if (beginsWith(file, prefix)) {
+ // validityTest was prefix/file
+
+ // Extract everything to the right of the prefix
+ std::string s = file.substr(prefix.length());
+
+ if (s == "") {
+ // This was the name of the prefix
+ return;
+ }
+
+ // See if there are any slashes
+ size_t slashPos = s.find('/');
+
+ bool add = false;
+
+ if (slashPos == std::string::npos) {
+ // No slashes, so s must be a file
+ add = wantFiles;
+ } else if (! wantFiles) {
+ // Not all zipfiles list directories as explicit entries.
+ // Because of this, if we're looking for directories and see
+ // any path longer than prefix, we must add the subdirectory.
+ // The Set will fix duplicates for us.
+ s = s.substr(0, slashPos);
+ add = true;
+ }
+
+ if (add) {
+ if (includePath) {
+ files.insert(path + "/" + prefix + s);
+ } else {
+ files.insert(s);
+ }
+ }
+ }
+}
+#endif
+
+static void getFileOrDirListZip(const std::string& path,
+ const std::string& prefix,
+ Array<std::string>& files,
+ bool wantFiles,
+ bool includePath){
+#if _HAVE_ZIP
+ struct zip *z = zip_open( path.c_str(), ZIP_CHECKCONS, NULL );
+
+ Set<std::string> fileSet;
+
+ int count = zip_get_num_files( z );
+ for( int i = 0; i < count; ++i ) {
+ struct zip_stat info;
+ zip_stat_init( &info ); // TODO: Docs unclear if zip_stat_init is required.
+ zip_stat_index( z, i, ZIP_FL_NOCASE, &info );
+ _zip_addEntry(path, prefix, info.name, fileSet, wantFiles, includePath);
+ }
+
+ zip_close( z );
+
+ fileSet.getMembers(files);
+#endif
+}
+
+
+static void determineFileOrDirList(
+ const std::string& filespec,
+ Array<std::string>& files,
+ bool wantFiles,
+ bool includePath) {
+
+ // if it is a .zip, prefix will specify the folder within
+ // whose contents we want to see
+ std::string prefix = "";
+ std::string path = filenamePath(filespec);
+
+ if ((path.size() > 0) && isSlash(path[path.size() - 1])) {
+ // Strip the trailing slash
+ path = path.substr(0, path.length() -1);
+ }
+
+ if ((path == "") || fileExists(path, false)) {
+ if ((path != "") && isZipfile(path)) {
+ // .zip should only work if * is specified as the Base + Ext
+ // Here, we have been asked for the root's contents
+ debugAssertM(filenameBaseExt(filespec) == "*", "Can only call getFiles/getDirs on zipfiles using '*' wildcard");
+ getFileOrDirListZip(path, prefix, files, wantFiles, includePath);
+ } else {
+ // It is a normal directory
+ getFileOrDirListNormal(filespec, files, wantFiles, includePath);
+ }
+ } else if (zipfileExists(filenamePath(filespec), path, prefix)) {
+ // .zip should only work if * is specified as the Base + Ext
+ // Here, we have been asked for the contents of a folder within the .zip
+ debugAssertM(filenameBaseExt(filespec) == "*", "Can only call getFiles/getDirs on zipfiles using '*' wildcard");
+ getFileOrDirListZip(path, prefix, files, wantFiles, includePath);
+ }
+}
+
+
+void getFiles(const std::string& filespec,
+ Array<std::string>& files,
+ bool includePath) {
+
+ determineFileOrDirList(filespec, files, true, includePath);
+}
+
+
+void getDirs(
+ const std::string& filespec,
+ Array<std::string>& files,
+ bool includePath) {
+
+ determineFileOrDirList(filespec, files, false, includePath);
+}
+
+
+std::string filenameBaseExt(const std::string& filename) {
+ int i = filename.rfind("/");
+ int j = filename.rfind("\\");
+
+ if ((j > i) && (j >= 0)) {
+ i = j;
+ }
+
+# ifdef G3D_WIN32
+ j = filename.rfind(":");
+ if ((i == -1) && (j >= 0)) {
+ i = j;
+ }
+# endif
+
+ if (i == -1) {
+ return filename;
+ } else {
+ return filename.substr(i + 1, filename.length() - i);
+ }
+}
+
+
+std::string filenameBase(const std::string& s) {
+ std::string drive;
+ std::string base;
+ std::string ext;
+ Array<std::string> path;
+
+ parseFilename(s, drive, path, base, ext);
+ return base;
+}
+
+
+std::string filenameExt(const std::string& filename) {
+ int i = filename.rfind(".");
+ if (i >= 0) {
+ return filename.substr(i + 1, filename.length() - i);
+ } else {
+ return "";
+ }
+}
+
+
+std::string filenamePath(const std::string& filename) {
+ int i = filename.rfind("/");
+ int j = filename.rfind("\\");
+
+ if ((j > i) && (j >= 0)) {
+ i = j;
+ }
+
+# ifdef G3D_WIN32
+ j = filename.rfind(":");
+ if ((i == -1) && (j >= 0)) {
+ i = j;
+ }
+# endif
+
+ if (i == -1) {
+ return "";
+ } else {
+ return filename.substr(0, i+1);
+ }
+}
+
+
+bool isZipfile(const std::string& filename) {
+
+ FILE* f = fopen(filename.c_str(), "r");
+ if (f == NULL) {
+ return false;
+ }
+ uint8 header[4];
+ fread(header, 4, 1, f);
+
+ const uint8 zipHeader[4] = {0x50, 0x4b, 0x03, 0x04};
+ for (int i = 0; i < 4; ++i) {
+ if (header[i] != zipHeader[i]) {
+ fclose(f);
+ return false;
+ }
+ }
+
+ fclose(f);
+ return true;
+}
+
+
+bool isDirectory(const std::string& filename) {
+ struct _stat st;
+ bool exists = _stat(filename.c_str(), &st) != -1;
+ return exists && ((st.st_mode & S_IFDIR) != 0);
+}
+
+
+bool filenameContainsWildcards(const std::string& filename) {
+ return (filename.find('*') != std::string::npos) || (filename.find('?') != std::string::npos);
+}
+
+
+bool fileIsNewer(const std::string& src, const std::string& dst) {
+ struct _stat sts;
+ bool sexists = _stat(src.c_str(), &sts) != -1;
+
+ struct _stat dts;
+ bool dexists = _stat(dst.c_str(), &dts) != -1;
+
+ return sexists && ((! dexists) || (sts.st_mtime > dts.st_mtime));
+}
+
+
+Array<std::string> filesUsed() {
+ Array<std::string> f;
+ _internal::currentFilesUsed.getMembers(f);
+ return f;
+}
+
+}
+
+#ifndef G3D_WIN32
+ #undef _stat
+#endif
diff --git a/dep/src/g3dlite/filter.cpp b/dep/src/g3dlite/filter.cpp
new file mode 100644
index 00000000000..72d6f0e05a7
--- /dev/null
+++ b/dep/src/g3dlite/filter.cpp
@@ -0,0 +1,32 @@
+/**
+ @file filter.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2007-03-01
+ @edited 2007-03-01
+
+ Copyright 2000-2007, Morgan McGuire.
+ All rights reserved.
+ */
+#include "G3D/filter.h"
+
+namespace G3D {
+
+void gaussian1D(Array<float>& coeff, int N, float std) {
+ coeff.resize(N);
+ float sum = 0.0f;
+ for (int i = 0; i < N; ++i) {
+ float x = i - (N - 1) / 2.0f;
+ float p = -square(x / std) / 2.0f;
+ float y = exp(p);
+ coeff[i] = y;
+ sum += y;
+ }
+
+ for (int i = 0; i < N; ++i) {
+ coeff[i] /= sum;
+ }
+}
+
+
+} // namespace
diff --git a/dep/src/g3dlite/format.cpp b/dep/src/g3dlite/format.cpp
index 13f01e26e6b..d9d1b516393 100644
--- a/dep/src/g3dlite/format.cpp
+++ b/dep/src/g3dlite/format.cpp
@@ -4,22 +4,13 @@
@author Morgan McGuire, graphics3d.com
@created 2000-09-09
- @edited 2006-04-30
+ @edited 2006-08-14
*/
#include "G3D/format.h"
#include "G3D/platform.h"
#include "G3D/System.h"
-#ifdef G3D_WIN32
- #include <math.h>
- #define vsnprintf _vsnprintf
- #define NEWLINE "\r\n"
-#else
- #include <stdarg.h>
- #define NEWLINE "\n"
-#endif
-
#ifdef _MSC_VER
// disable: "C++ exception handler used"
# pragma warning (push)
@@ -31,7 +22,7 @@
namespace G3D {
-std::string format(const char* fmt,...) {
+std::string __cdecl format(const char* fmt,...) {
va_list argList;
va_start(argList,fmt);
std::string result = vformat(fmt, argList);
@@ -40,10 +31,10 @@ std::string format(const char* fmt,...) {
return result;
}
-#if defined(G3D_WIN32) && (_MSC_VER >= 1300)
-// Both MSVC6 and 7 seem to use the non-standard vsnprintf
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+// Both MSVC seems to use the non-standard vsnprintf
// so we are using vscprintf to determine buffer size, however
-// only MSVC7 headers include vscprintf for some reason.
+// only MSVC7 and up headers include vscprintf for some reason.
std::string vformat(const char *fmt, va_list argPtr) {
// We draw the line at a 1MB string.
const int maxSize = 1000000;
@@ -52,8 +43,9 @@ std::string vformat(const char *fmt, va_list argPtr) {
// allocate it on the stack because this saves
// the malloc/free time.
const int bufSize = 161;
- char stackBuffer[bufSize];
+ char stackBuffer[bufSize];
+ // MSVC does not support va_copy
int actualSize = _vscprintf(fmt, argPtr) + 1;
if (actualSize > bufSize) {
@@ -64,11 +56,11 @@ std::string vformat(const char *fmt, va_list argPtr) {
if (actualSize < maxSize) {
heapBuffer = (char*)System::malloc(maxSize + 1);
- vsnprintf(heapBuffer, maxSize, fmt, argPtr);
+ _vsnprintf(heapBuffer, maxSize, fmt, argPtr);
heapBuffer[maxSize] = '\0';
} else {
heapBuffer = (char*)System::malloc(actualSize);
- vsprintf(heapBuffer, fmt, argPtr);
+ vsprintf(heapBuffer, fmt, argPtr);
}
std::string formattedString(heapBuffer);
@@ -81,7 +73,7 @@ std::string vformat(const char *fmt, va_list argPtr) {
}
}
-#elif defined(G3D_WIN32) && (_MSC_VER < 1300)
+#elif defined(_MSC_VER) && (_MSC_VER < 1300)
std::string vformat(const char *fmt, va_list argPtr) {
// We draw the line at a 1MB string.
@@ -91,9 +83,12 @@ std::string vformat(const char *fmt, va_list argPtr) {
// allocate it on the stack because this saves
// the malloc/free time.
const int bufSize = 161;
- char stackBuffer[bufSize];
+ char stackBuffer[bufSize];
- int actualWritten = vsnprintf(stackBuffer, bufSize, fmt, argPtr);
+ // MSVC6 doesn't support va_copy, however it also seems to compile
+ // correctly if we just pass our argument list along. Note that
+ // this whole code block is only compiled if we're on MSVC6 anyway
+ int actualWritten = _vsnprintf(stackBuffer, bufSize, fmt, argPtr);
// Not a big enough buffer, bufSize characters written
if (actualWritten == -1) {
@@ -101,8 +96,8 @@ std::string vformat(const char *fmt, va_list argPtr) {
int heapSize = 512;
double powSize = 1.0;
char* heapBuffer = (char*)System::malloc(heapSize);
-
- while ((vsnprintf(heapBuffer, heapSize, fmt, argPtr) == -1) &&
+
+ while ((_vsnprintf(heapBuffer, heapSize, fmt, argPtr) == -1) &&
(heapSize < maxSize)) {
heapSize = iCeil(heapSize * ::pow((double)2.0, powSize++));
@@ -133,18 +128,22 @@ std::string vformat(const char* fmt, va_list argPtr) {
const int bufSize = 161;
char stackBuffer[bufSize];
- int numChars = vsnprintf(stackBuffer, bufSize, fmt, argPtr);
+ va_list argPtrCopy;
+ va_copy(argPtrCopy, argPtr);
+ int numChars = vsnprintf(stackBuffer, bufSize, fmt, argPtrCopy);
+ va_end(argPtrCopy);
if (numChars >= bufSize) {
// We didn't allocate a big enough string.
char* heapBuffer = (char*)System::malloc((numChars + 1) * sizeof(char));
- assert(heapBuffer);
+ debugAssert(heapBuffer);
int numChars2 = vsnprintf(heapBuffer, numChars + 1, fmt, argPtr);
- assert(numChars2 == numChars);
+ debugAssert(numChars2 == numChars);
+ (void)numChars2;
std::string result(heapBuffer);
-
+
System::free(heapBuffer);
return result;
@@ -160,13 +159,6 @@ std::string vformat(const char* fmt, va_list argPtr) {
} // namespace
-#ifdef G3D_WIN32
-# undef vsnprintf
-#endif
-
#ifdef _MSC_VER
# pragma warning (pop)
#endif
-
-#undef NEWLINE
-
diff --git a/dep/src/g3dlite/g3dfnmatch.cpp b/dep/src/g3dlite/g3dfnmatch.cpp
new file mode 100644
index 00000000000..39ef7b31914
--- /dev/null
+++ b/dep/src/g3dlite/g3dfnmatch.cpp
@@ -0,0 +1,204 @@
+/*-
+* Copyright (c) 1992, 1993
+*The Regents of the University of California. 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.
+* 3. All advertising materials mentioning features or use of this software
+* must display the following acknowledgement:
+*This product includes software developed by the University of
+*California, Berkeley and its contributors.
+* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+*
+*@(#)fnmatch.h8.1 (Berkeley) 6/2/93
+*
+* From FreeBSD fnmatch.h 1.7
+* $Id: g3dfnmatch.cpp,v 1.2 2010/02/06 10:03:24 corey_taylor Exp $
+*/
+#include "G3D/g3dfnmatch.h"
+
+#ifdef G3D_WIN32
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+
+namespace G3D {
+
+#define EOS '\0'
+
+static const char *rangematch(const char *, char, int);
+
+int g3dfnmatch(const char *pattern, const char *string, int flags)
+{
+ const char *stringstart;
+ char c, test;
+
+ for (stringstart = string;;)
+ switch (c = *pattern++) {
+ case EOS:
+ if ((flags & FNM_LEADING_DIR) && *string == '/')
+ return (0);
+ return (*string == EOS ? 0 : FNM_NOMATCH);
+ case '?':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && (flags & FNM_PATHNAME))
+ return (FNM_NOMATCH);
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '*':
+ c = *pattern;
+ /* Collapse multiple stars. */
+ while (c == '*')
+ c = *++pattern;
+
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+
+ /* Optimize for pattern with * at end or before /. */
+ if (c == EOS)
+ if (flags & FNM_PATHNAME)
+ return ((flags & FNM_LEADING_DIR) ||
+ strchr(string, '/') == NULL ?
+ 0 : FNM_NOMATCH);
+ else
+ return (0);
+ else if (c == '/' && flags & FNM_PATHNAME) {
+ if ((string = strchr(string, '/')) == NULL)
+ return (FNM_NOMATCH);
+ break;
+ }
+
+ /* General case, use recursion. */
+ while ((test = *string) != EOS) {
+ if (!rangematch(pattern, *string, flags & ~FNM_PERIOD))
+ return (0);
+ if (test == '/' && flags & FNM_PATHNAME)
+ break;
+ ++string;
+ }
+ return (FNM_NOMATCH);
+ case '[':
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && flags & FNM_PATHNAME)
+ return (FNM_NOMATCH);
+ if ((pattern =
+ rangematch(pattern, *string, flags)) == NULL)
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '\\':
+ if (!(flags & FNM_NOESCAPE)) {
+ if ((c = *pattern++) == EOS) {
+ c = '\\';
+ --pattern;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ if (c == *string)
+ ;
+ else if ((flags & FNM_CASEFOLD) &&
+ (tolower((unsigned char)c) ==
+ tolower((unsigned char)*string)))
+ ;
+ else if ((flags & FNM_PREFIX_DIRS) && *string == EOS &&
+ ((c == '/' && string != stringstart) ||
+ (string == stringstart+1 && *stringstart == '/')))
+ return (0);
+ else
+ return (FNM_NOMATCH);
+ string++;
+ break;
+ }
+ /* NOTREACHED */
+}
+
+static const char *
+rangematch(const char *pattern, char test, int flags)
+{
+ int negate, ok;
+ char c, c2;
+
+ /*
+ * A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). This implementation treats it like '!', for
+ * consistency with the regular expression syntax.
+ * J.T. Conklin (conklin@ngai.kaleida.com)
+ */
+ if ( (negate = (*pattern == '!' || *pattern == '^')) )
+ ++pattern;
+
+ if (flags & FNM_CASEFOLD)
+ test = tolower((unsigned char)test);
+
+ for (ok = 0; (c = *pattern++) != ']';) {
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = *pattern++;
+ if (c == EOS)
+ return (NULL);
+
+ if (flags & FNM_CASEFOLD)
+ c = tolower((unsigned char)c);
+
+ if (*pattern == '-'
+ && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+ c2 = *pattern++;
+ if (c2 == EOS)
+ return (NULL);
+
+ if (flags & FNM_CASEFOLD)
+ c2 = tolower((unsigned char)c2);
+
+ if ((unsigned char)c <= (unsigned char)test &&
+ (unsigned char)test <= (unsigned char)c2)
+ ok = 1;
+ } else if (c == test)
+ ok = 1;
+ }
+ return (ok == negate ? NULL : pattern);
+}
+
+}
+
+#else
+
+namespace G3D {
+int g3dfnmatch(const char * a, const char *b, int c) {
+ return fnmatch(a, b, c);
+}
+}
+
+#endif
+
diff --git a/dep/src/g3dlite/g3dmath.cpp b/dep/src/g3dlite/g3dmath.cpp
new file mode 100644
index 00000000000..ad85e9efb9b
--- /dev/null
+++ b/dep/src/g3dlite/g3dmath.cpp
@@ -0,0 +1,108 @@
+/**
+ @file g3dmath.cpp
+
+ @author Morgan McGuire, graphics3d.com
+
+ @created 2001-06-02
+ @edited 2004-02-24
+ */
+
+#include "G3D/g3dmath.h"
+#include <cstdlib>
+#include <cstring>
+
+namespace G3D {
+
+float gaussRandom(float mean, float stdev) {
+
+ // Using Box-Mueller method from http://www.taygeta.com/random/gaussian.html
+ // Modified to specify standard deviation and mean of distribution
+ float w, x1, x2;
+
+ // Loop until w is less than 1 so that log(w) is negative
+ do {
+ x1 = uniformRandom(-1.0, 1.0);
+ x2 = uniformRandom(-1.0, 1.0);
+
+ w = float(square(x1) + square(x2));
+ } while (w > 1.0f);
+
+ // Transform to gassian distribution
+ // Multiply by sigma (stdev ^ 2) and add mean.
+ return x2 * (float)square(stdev) * sqrtf((-2.0f * logf(w) ) / w) + mean;
+}
+
+/**
+ This value should not be tested against directly, instead
+ G3D::isNan() and G3D::isFinite() will return reliable results. */
+double inf() {
+ return std::numeric_limits<double>::infinity();
+}
+
+bool isNaN(float x) {
+ static const float n = nan();
+ return memcmp(&x, &n, sizeof(float)) == 0;
+}
+
+bool isNaN(double x) {
+ static const double n = nan();
+ return memcmp(&x, &n, sizeof(double)) == 0;
+}
+
+
+/**
+ This value should not be tested against directly, instead
+ G3D::isNan() and G3D::isFinite() will return reliable results. */
+float finf() {
+ return std::numeric_limits<float>::infinity();
+}
+
+/** This value should not be tested against directly, instead
+ G3D::isNan() and G3D::isFinite() will return reliable results. */
+double nan() {
+ // double is a standard type and should have quiet NaN
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+float fnan() {
+ // double is a standard type and should have quiet NaN
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+
+int highestBit(uint32 x) {
+ // Binary search.
+ int base = 0;
+
+ if (x & 0xffff0000) {
+ base = 16;
+ x >>= 16;
+ }
+ if (x & 0x0000ff00) {
+ base += 8;
+ x >>= 8;
+ }
+ if (x & 0x000000f0) {
+ base += 4;
+ x >>= 4;
+ }
+
+ static const int lut[] = {-1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3};
+ return base + lut[x];
+}
+
+
+int iRandom(int low, int high) {
+ int r = iFloor(low + (high - low + 1) * (double)rand() / RAND_MAX);
+
+ // There is a *very small* chance of generating
+ // a number larger than high.
+ if (r > high) {
+ return high;
+ } else {
+ return r;
+ }
+}
+
+
+}
diff --git a/dep/src/g3dlite/license.cpp b/dep/src/g3dlite/license.cpp
new file mode 100644
index 00000000000..5049184cf9b
--- /dev/null
+++ b/dep/src/g3dlite/license.cpp
@@ -0,0 +1,73 @@
+/**
+ @file license.cpp
+
+ @author Morgan McGuire, graphics3d.com
+
+ @created 2004-04-15
+ @edited 2004-04-15
+*/
+
+#include "G3D/format.h"
+#include <string>
+
+namespace G3D {
+
+std::string license() {
+ return format(
+
+"This software is based in part on the PNG Reference Library which is\n"
+"Copyright (c) 2004 Glenn Randers-Pehrson\n\n"
+"This software is based in part on the work of the Independent JPEG Group.\n\n"
+"This software is based on part on the FFmpeg libavformat and libavcodec libraries\n"
+"(\"FFmpeg\", http://ffmpeg.mplayerhq.hu), which are included under the terms of the\n"
+"GNU Lesser General Public License (LGPL), (http://www.gnu.org/copyleft/lesser.html).\n\n"
+"%s"
+"This program uses the G3D Library (http://g3d.sf.net), which\n"
+"is licensed under the \"Modified BSD\" Open Source license. The G3D library\n"
+"source code is Copyright © 2000-2010, Morgan McGuire, All rights reserved.\n"
+"This program uses The OpenGL Extension Wrangler Library, which \n"
+"is licensed under the \"Modified BSD\" Open Source license. \n"
+"The OpenGL Extension Wrangler Library source code is\n"
+"Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>\n"
+"Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>\n"
+"Copyright (C) 2002, Lev Povalahev\n"
+"All rights reserved.\n\n"
+"The Modified BSD license is below, and requires the following statement:\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"
+"\n"
+"* Redistributions of source code must retain the above copyright notice, \n"
+" this list of conditions and the following disclaimer.\n"
+"* Redistributions in binary form must reproduce the above copyright notice, \n"
+" this list of conditions and the following disclaimer in the documentation \n"
+" and/or other materials provided with the distribution.\n"
+"* The name of the author 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\" \n"
+"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \n"
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
+"ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \n"
+"LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \n"
+"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \n"
+"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n"
+"INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n"
+"CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n"
+"ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n"
+"THE POSSIBILITY OF SUCH DAMAGE.\n"
+"\n\n"
+"G3D VERSION %d\n",
+
+#ifdef G3D_WIN32
+ "" // Win32 doesn't use SDL
+#else
+ "This software uses the Simple DirectMedia Layer library (\"SDL\",\n"
+ "http://www.libsdl.org), which is included under the terms of the\n"
+ "GNU Lesser General Public License, (http://www.gnu.org/copyleft/lesser.html).\n\n"
+#endif
+,
+G3D_VER);
+}
+
+}
diff --git a/dep/src/g3dlite/license.html b/dep/src/g3dlite/license.html
index 9bbb2ad5f9a..11c33882248 100644
--- a/dep/src/g3dlite/license.html
+++ b/dep/src/g3dlite/license.html
@@ -3,107 +3,113 @@
<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
- <title>G3D: License</title>
+ <title>G3D Innovation Engine: License</title>
<link href="stylesheet.css" rel="stylesheet" type="text/css">
- <style type="text/css">
- span.menu_tab a {
- background: #FFE183;
- border-width: 1px;
- border-style: solid;
- border-color: #FFB143;
- padding: 5px;
- margin: 0px;
- margin-left: 2px;
- font-size: 11px;
- font-weight: bold;
- font-family: arial;
- color: #000000;
- position: relative;
- display: inline;
- }
-
- span.menu_tab a:link, a:visited {
- text-decoration: none;
- }
- span.menu_tab a:hover {
- background: #FDEFA0;
- color: #000000;
- text-decoration: none;
- }
- .widthadjust {
- min-width: 800px;
- width: 80%;
- background: #FFFFFF;
- padding-left: 5px;
- padding-right: 5px;
- }
- * html .widthadjust {
- width: expression(document.body.clientWidth < 1000? "1000px": "auto";
- }
- </style>
</head>
<body style="width: 100%; background: #aaaaaa">
<table class="widthadjust" align=center><tr><td>
<table style="height: 44px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #FFc161;" width=100% cellspacing=0 cellpadding=0>
+
+ <tr>
+ <td rowspan="2" valign="bottom" style="width: 51;">
+ <a href="index.html">
+ <img src="G3D-small-shadow.jpg" border="0" align="left">
+ </a>
+ </td>
+ <td style="width: 65%;" nowrap="true" valign="bottom">
+ <font size="2">
+ <center>
+ <a href="http://groups.google.com/group/g3d-users/topics">Support Forum</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <a href="http://g3d.cvs.sourceforge.net/g3d/G3D/">Library Source</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <a href="http://sourceforge.net/projects/g3d/">SourceForge Page</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <a href="http://g3d.sf.net/">Web Page</a>
+ </center>
+ </font>
+ </td>
+ </tr>
<tr cellspacing=0 cellpadding=0>
- <td style="width: 70%;" nowrap=true>
- <img src="G3D-small-shadow.jpg">
- <span class="menu_tab"><a href="index.html">Contents</a></span>
- <span class="menu_tab"><a href="globals_func.html">Functions</a></span>
- <span class="menu_tab"><a href="classes.html">Classes</a></span>
- <span class="menu_tab"><a href="indexedbytopic.html">Topics</a></span>
- <span class="menu_tab"><a href="http://sourceforge.net/forum/forum.php?forum_id=262426">User Forum</a></span>
- <span class="menu_tab"><a href="http://cvs.sourceforge.net/viewcvs.py/g3d-cpp/cpp/">CVS</a></span>
- </td>
+<td style="width: 65%;" nowrap=true valign=bottom>
+
+ <span class="menu_tab">
+ <a href="http://sourceforge.net/apps/mediawiki/g3d/index.php?title=Main_Page">Wiki Doc</a>
+ </span>
+ <span class="menu_tab">
+ <a href="dataindex.html">Data</a>
+ </span>
+ <span class="menu_tab">
+ <a href="annotated.html">API Index</a>
+ </span>
+ <span class="menu_tab">
+ <a href="apiindex.html">APIs by Level</a>
+ </span>
+ <span class="menu_tab">
+ <a href="topicindex.html">APIs by Task</a>
+ </span>
+</td>
</tr>
</table>
-
+<br>
+<br>
<table cellspacing=0 cellpadding=0 width=100% >
<tr><td>
<!-- code goes here -->
-<!-- Generated by Doxygen 1.4.6-NO -->
-<h1><a class="anchor" name="license">License</a></h1>
-<TABLE BORDER=0 WIDTH=80%><TR><TD><I><FONT FACE="Arial">
-<A HREF="guideintro.html"><IMG SRC="backarrow.gif" BORDER=0 ALIGN=MIDDLE>
-Introduction</A></I></FONT></TD><TD ALIGN=RIGHT><FONT FACE="Arial"><I>
-<A HREF="guideinstall.html">
-Installation <IMG SRC="forwardarrow.gif" BORDER=0 ALIGN=MIDDLE></A></I></FONT></TD></TR></TABLE>
-<h2><a class="anchor" name="intent">
+
+<!-- Generated by Doxygen 1.6.1 -->
+<div class="contents">
+
+
+<h1><a class="anchor" id="license">License </a></h1><h2><a class="anchor" id="intent">
Intent of License</a></h2>
-(This section is informal and not legally binding.)<p>
-<br>
- This library is free code-- you can use it without charge and it is minimally legally encumbered. Unlike some other free libraries, we &lt;u&gt;do not&lt;/u&gt; require you to release your source code or make your own program open source.<p>
-I intend the license (below) to protect me and the other contributors from liability and allow you to use the source however you want. You can make your own closed or open-source programs, sell them, give them away, whatever.<p>
-You have an obligation to say "this software is based in part on the work of the Independent JPEG Group" in your documentation or application help if you use the <a class="el" href="classG3D_1_1GImage.html">G3D::GImage</a> class because it is based on the IJG library. The OpenGL headers and ZLib headers included may be freely distributed provided their copyright notices remain intact.<p>
-For convenience, <a class="el" href="namespaceG3D.html#2d6bccd0c2fa5b44882b7d0c732e2712">G3D::license</a> is a function that returns the license string you must put in your documentation. <a class="el" href="classG3D_1_1GApp.html">G3D::GApp</a> will automatically write a file (g3d-license.txt) to disk with the contents of this license unless you tell it not to.<p>
-Most of the data resources have either entered the public domain and have been in several published papers or are data that I have explicitly received permission to distribute with <a class="el" href="namespaceG3D.html">G3D</a>. The <a class="el" href="namespaceG3D.html">G3D</a> fonts are actually font images, not TrueType font descriptions and may be freely distributed. As a rule of thumb, you can freely use and distribute anything you find in the data directory but may need permission to use it in a commercial product. Check the various copyright.txt files in the data directories for specific information.<p>
-You are required by the BSD license to acknowledge <a class="el" href="namespaceG3D.html">G3D</a> in your documentation. This can be as minimal as a note buried in the fine print at the end of a manual or a text file accompanying your program. I appreciate it if you acknowledged the library more publicly but you aren't required to.<p>
-Likewise, you are encouraged but not required to submit patches to improve the library for the benefit of all. E-mail me with bugs, patches, and questions.<p>
--Morgan McGuire &lt;<em><a href="mailto:matrix@graphics3d.com">matrix@graphics3d.com</a></em>&gt;<p>
-<hr>
-<h2><a class="anchor" name="reallicense">
+<p>(This section is informal and not legally binding.)</p>
+<p><br/>
+ This library is free code-- you can use it without charge and it is minimally legally encumbered. Unlike some other free libraries, we <b>do not</b> require you to release your source code or make your own program open source.</p>
+<p>I intend the license (below) to protect me and the other contributors from liability and allow you to use the source however you want. You can make your own closed or open-source programs, sell them, give them away, whatever.</p>
+<p>The license for <a class="el" href="namespace_g3_d.html">G3D</a> itself and the libaries included in the <a class="el" href="namespace_g3_d.html">G3D</a> distribution create certain documentation obligations for you. For convenience, <a class="el" href="namespace_g3_d.html#a2d6bccd0c2fa5b44882b7d0c732e2712" title="G3D, SDL, and IJG libraries require license documentation to be distributed with...">G3D::license</a> is a function that returns the license string you must put in your documentation. <a class="el" href="class_g3_d_1_1_g_app.html" title="For each frame, the GApp has several tasks that can be implemented by overriding...">G3D::GApp</a> will automatically write a file (g3d-license.txt) to disk with the contents of this license unless you tell it not to, thus automatically satisfying your documentation requirement after the first time you run a <a class="el" href="namespace_g3_d.html">G3D</a> program.</p>
+<p>Most of the data resources have either entered the public domain and have been in several published papers or are data that I have explicitly received permission to distribute with <a class="el" href="namespace_g3_d.html">G3D</a>. The <a class="el" href="namespace_g3_d.html">G3D</a> fonts are actually font images, not TrueType font descriptions and may be freely distributed. As a rule of thumb, you can freely use and distribute anything you find in the data directory but may need permission to use it in a commercial product. Check the various copyright.txt files in the data directories for specific information.</p>
+<p>You are required by the BSD license to acknowledge <a class="el" href="namespace_g3_d.html">G3D</a> in your documentation. This can be as minimal as a note buried in the fine print at the end of a manual or a text file accompanying your program. I appreciate it if you acknowledged the library more publicly but you aren't required to.</p>
+<p>Likewise, you are encouraged but not required to submit patches to improve the library for the benefit of all. Post bugs, patches, and questions to the g3d-users forum linked at the top of this page. </p>
+<p>-Morgan McGuire &lt;<em><a href="mailto:morgan@cs.williams.edu">morgan@cs.williams.edu</a></em>&gt;</p>
+<hr/>
+<h2><a class="anchor" id="reallicense">
License</a></h2>
-<em><a class="el" href="namespaceG3D.html">G3D</a> is licensed under the <a href="http://www.opensource.org/licenses/bsd-license.php">BSD license</a>, with portions controlled by the <a href="IJG-README.TXT">IJG license</a> and <a href="libpng-LICENSE.txt">PNG Reference Library license</a></em><p>
-<code> <div align="center">
-<img src="http://opensource.org/trademarks/osi-certified/web/osi-certified-120x100.gif" alt="osi-certified-120x100.gif">
+<p><em><a class="el" href="namespace_g3_d.html">G3D</a> is licensed under the <a href="http://www.opensource.org/licenses/bsd-license.php">BSD license</a>, with portions controlled by the <a href="IJG-README.TXT">IJG license</a>, <a href="libpng-LICENSE.txt">PNG Reference Library license</a>.</em></p>
+<p><code> </p>
+<div align="center">
+<img src="http://opensource.org/trademarks/osi-certified/web/osi-certified-120x100.gif" alt="osi-certified-120x100.gif"/>
</div>
- </code><p>
-<code>This product uses software from the <a class="el" href="namespaceG3D.html">G3D</a> project (<a href="http://g3d-cpp.sf.net">http://g3d-cpp.sf.net</a>) </code><p>
-<code>Copyright &copy; 2000-2006, Morgan McGuire </code><p>
-<code>All rights reserved. </code><p>
-<code> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: </code><p>
-<code> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. </code><p>
-<code> 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. </code><p>
-<code> Neither the name of Morgan McGuire, Williams College, Brown University, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. </code><p>
-<code> 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 COPYRIGHT OWNER 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. </code><p>
-You must also agree to be bound by the terms of the Independent JPEG Group license for the portions of this library that are based on the work of the Independent JPEG Group, <b>if you use those portions</b>. Note: if you do not use the <a class="el" href="classG3D_1_1GImage.html">G3D::GImage</a> class, this clause does not apply to you because the linker will strip that code from your project. The <a href="IJG-README.TXT"
->IJG-README.TXT</a> file contains the Independent JPEG Group license.</A>
+<p> </code></p>
+<p><code>This product uses software from the <a class="el" href="namespace_g3_d.html">G3D</a> project (<a href="http://g3d.sf.net">http://g3d.sf.net</a>) </code></p>
+<p><code>Copyright &copy; 2000-2010, Morgan McGuire </code></p>
+<p><code>All rights reserved. </code></p>
+<p><code> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: </code></p>
+<p><code> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. </code></p>
+<p><code> 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. </code></p>
+<p><code> Neither the name of Morgan McGuire, Williams College, Brown University, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. </code></p>
+<p><code> 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 COPYRIGHT OWNER 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. </code> </p>
+</div>
+</A>
<hr><address style="align: right;"><small>
-Generated on Tue Jul 18 12:05:54 2006 for G3D by <a href="http://www.doxygen.org/index.html">
+G3D Innovation Engine documentation generated on Thu Mar 25 14:54:30 2010 using <a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 width=55 height=26>
-</a> 1.4.6-NO</small></address>
+</a> 1.6.1</small></address>
+ <!-- Removed to make page loading faster
Hosted by <A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=76879&amp;type=5" width="210" height="62" border="0" alt="SourceForge.net Logo"></A>
+-->
+
+<!-- Piwik -->
+<script type="text/javascript">
+var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/g3d/" : "http://apps.sourceforge.net/piwik/g3d/");
+document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
+</script><script type="text/javascript">
+piwik_action_name = '';
+piwik_idsite = 2;
+piwik_url = pkBaseURL + "piwik.php";
+piwik_log(piwik_action_name, piwik_idsite, piwik_url);
+</script>
+<object><noscript><p><img src="http://apps.sourceforge.net/piwik/g3d/piwik.php?idsite=2" alt="piwik"/></p></noscript></object>
+<!-- End Piwik Tag -->
+
</body>
</html>
diff --git a/dep/src/g3dlite/prompt.cpp b/dep/src/g3dlite/prompt.cpp
new file mode 100644
index 00000000000..6a28e6462b4
--- /dev/null
+++ b/dep/src/g3dlite/prompt.cpp
@@ -0,0 +1,729 @@
+/**
+ @file prompt.cpp
+
+ @author Morgan McGuire, http://graphics.cs.williams.edu
+ @cite Windows dialog interface by Max McGuire, mmcguire@ironlore.com
+ @cite Font setting code by Kurt Miller, kurt@flipcode.com
+
+ @created 2000-08-26
+ @edited 2005-01-14
+ */
+
+#include "G3D/prompt.h"
+#include "G3D/platform.h"
+
+#include <stdio.h>
+
+#ifdef G3D_WIN32
+# include <sstream>
+# include <conio.h>
+#else
+# define _getch getchar
+#endif
+
+#ifdef G3D_OSX
+
+/*#ifdef __LP64__
+# undef __LP64__
+#endif
+*/
+
+# include <Carbon/Carbon.h>
+
+/*
+#ifdef G3D_64BIT
+# define __LP64__
+#endif
+*/
+
+#endif
+
+namespace G3D {
+
+#ifdef G3D_WIN32
+
+namespace _internal {
+/**
+ Generic Win32 dialog facility.
+ @author Max McGuire
+ */
+class DialogTemplate {
+public:
+
+ DialogTemplate(LPCSTR caption, DWORD style,
+ int x, int y, int w, int h,
+ LPCSTR font = NULL, WORD fontSize = 8) {
+
+ usedBufferLength = sizeof(DLGTEMPLATE);
+ totalBufferLength = usedBufferLength;
+
+ dialogTemplate = (DLGTEMPLATE*)malloc(totalBufferLength);
+
+ dialogTemplate->style = style;
+
+ if (font != NULL) {
+ dialogTemplate->style |= DS_SETFONT;
+ }
+
+ dialogTemplate->x = (short)x;
+ dialogTemplate->y = (short)y;
+ dialogTemplate->cx = (short)w;
+ dialogTemplate->cy = (short)h;
+ dialogTemplate->cdit = 0;
+
+ dialogTemplate->dwExtendedStyle = 0;
+
+ // The dialog box doesn't have a menu or a special class
+ AppendData("\0", 2);
+ AppendData("\0", 2);
+
+ // Add the dialog's caption to the template
+
+ AppendString(caption);
+
+ if (font != NULL) {
+ AppendData(&fontSize, sizeof(WORD));
+ AppendString(font);
+ }
+ }
+
+ void AddComponent(LPCSTR type, LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
+
+ DLGITEMTEMPLATE item;
+
+ item.style = style;
+ item.x = (short)x;
+ item.y = (short)y;
+ item.cx = (short)w;
+ item.cy = (short)h;
+ item.id = id;
+
+ item.dwExtendedStyle = exStyle;
+
+ AppendData(&item, sizeof(DLGITEMTEMPLATE));
+
+ AppendString(type);
+ AppendString(caption);
+
+ WORD creationDataLength = 0;
+ AppendData(&creationDataLength, sizeof(WORD));
+
+ // Increment the component count
+ dialogTemplate->cdit++;
+
+ }
+
+
+ void AddButton(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
+
+ AddStandardComponent(0x0080, caption, style, exStyle, x, y, w, h, id);
+
+ WORD creationDataLength = 0;
+ AppendData(&creationDataLength, sizeof(WORD));
+
+ }
+
+
+ void AddEditBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
+
+ AddStandardComponent(0x0081, caption, style, exStyle, x, y, w, h, id);
+
+ WORD creationDataLength = 0;
+ AppendData(&creationDataLength, sizeof(WORD));
+
+ }
+
+
+ void AddStatic(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
+
+ AddStandardComponent(0x0082, caption, style, exStyle, x, y, w, h, id);
+
+ WORD creationDataLength = 0;
+ AppendData(&creationDataLength, sizeof(WORD));
+
+ }
+
+
+ void AddListBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
+
+ AddStandardComponent(0x0083, caption, style, exStyle, x, y, w, h, id);
+
+ WORD creationDataLength = sizeof(WORD) + 5 * sizeof(WCHAR);
+ AppendData(&creationDataLength, sizeof(WORD));
+
+ AppendString("TEST");
+
+ }
+
+
+ void AddScrollBar(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
+
+ AddStandardComponent(0x0084, caption, style, exStyle, x, y, w, h, id);
+
+ WORD creationDataLength = 0;
+ AppendData(&creationDataLength, sizeof(WORD));
+
+ }
+
+
+ void AddComboBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
+
+ AddStandardComponent(0x0085, caption, style, exStyle, x, y, w, h, id);
+
+ WORD creationDataLength = 0;
+ AppendData(&creationDataLength, sizeof(WORD));
+
+ }
+
+
+ /**
+ *
+ * Returns a pointer to the Win32 dialog template which the object
+ * represents. This pointer may become invalid if additional components
+ * are added to the template.
+ *
+ */
+ operator const DLGTEMPLATE*() const {
+ return dialogTemplate;
+ }
+
+ virtual ~DialogTemplate() {
+ free(dialogTemplate);
+ }
+
+protected:
+
+ void AddStandardComponent(WORD type, LPCSTR caption, DWORD style, DWORD exStyle,
+ int x, int y, int w, int h, WORD id, LPSTR font = NULL, WORD fontSize = 8) {
+
+ DLGITEMTEMPLATE item;
+
+ // DWORD align the beginning of the component data
+
+ AlignData(sizeof(DWORD));
+
+ item.style = style;
+ if (font != NULL) {
+ item.style |= DS_SETFONT;
+ }
+ item.x = (short)x;
+ item.y = (short)y;
+ item.cx = (short)w;
+ item.cy = (short)h;
+ item.id = id;
+
+ item.dwExtendedStyle = exStyle;
+
+ AppendData(&item, sizeof(DLGITEMTEMPLATE));
+
+ WORD preType = 0xFFFF;
+
+ AppendData(&preType, sizeof(WORD));
+ AppendData(&type, sizeof(WORD));
+
+ AppendString(caption);
+
+ if (font != NULL) {
+ AppendData(&fontSize, sizeof(WORD));
+ AppendString(font);
+ }
+
+ // Increment the component count
+ dialogTemplate->cdit++;
+ }
+
+
+ void AlignData(int size) {
+
+ int paddingSize = usedBufferLength % size;
+
+ if (paddingSize != 0) {
+ EnsureSpace(paddingSize);
+ usedBufferLength += paddingSize;
+ }
+
+ }
+
+ void AppendString(LPCSTR string) {
+
+ int length = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0);
+
+ WCHAR* wideString = (WCHAR*)malloc(sizeof(WCHAR) * length);
+ MultiByteToWideChar(CP_ACP, 0, string, -1, wideString, length);
+
+ AppendData(wideString, length * sizeof(WCHAR));
+ free(wideString);
+
+ }
+
+ void AppendData(const void* data, int dataLength) {
+
+ EnsureSpace(dataLength);
+
+ memcpy((char*)dialogTemplate + usedBufferLength, data, dataLength);
+ usedBufferLength += dataLength;
+
+ }
+
+ void EnsureSpace(int length) {
+ if (length + usedBufferLength > totalBufferLength) {
+ totalBufferLength += length * 2;
+
+ void* newBuffer = malloc(totalBufferLength);
+ memcpy(newBuffer, dialogTemplate, usedBufferLength);
+
+ free(dialogTemplate);
+ dialogTemplate = (DLGTEMPLATE*)newBuffer;
+ }
+ }
+
+private:
+
+ DLGTEMPLATE* dialogTemplate;
+
+ int totalBufferLength;
+ int usedBufferLength;
+
+};
+
+
+struct PromptParams {
+ const char* message;
+ const char* title;
+};
+
+/**
+ * Constants for controls.
+ */
+#define IDC_MESSAGE 1000
+#define IDC_BUTTON0 2000
+
+INT_PTR CALLBACK PromptDlgProc(HWND hDlg, UINT msg,
+ WPARAM wParam, LPARAM lParam) {
+ switch(msg) {
+ case WM_INITDIALOG:
+ {
+ PromptParams *params = (PromptParams*)lParam;
+ ::SetWindowTextA(::GetDlgItem(hDlg, IDC_MESSAGE), params->message);
+
+ ::SetFocus(::GetDlgItem(hDlg, IDC_BUTTON0));
+
+ SetWindowTextA(hDlg, params->title);
+
+ HFONT hfont =
+ CreateFontA(16, 0, 0, 0, FW_NORMAL,
+ FALSE, FALSE, FALSE,
+ ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
+ PROOF_QUALITY, FIXED_PITCH | FF_MODERN, "Courier New");
+
+ SendDlgItemMessage(hDlg, IDC_MESSAGE, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE,0));
+
+
+ break;
+ }
+ case WM_COMMAND:
+ {
+ int choiceNumber = LOWORD(wParam) - IDC_BUTTON0;
+ if ((choiceNumber >= 0) && (choiceNumber < 10)) {
+ EndDialog(hDlg, choiceNumber);
+ return TRUE;
+ }
+ }
+
+ break;
+
+ case WM_NCDESTROY:
+ // Under SDL 1.2.6 we get a NCDESTROY message for no reason and the
+ // window is immediately closed. This is here to debug the problem.
+ (void)0;
+ break;
+
+ }
+
+ return FALSE;
+}
+
+}; // namespace _internal
+
+
+using namespace _internal;
+
+/**
+ * Show a dialog prompt.
+ */
+static int guiPrompt(
+ const char* windowTitle,
+ const char* prompt,
+ const char** choice,
+ int numChoices) {
+
+ int width = 280;
+ int height = 128;
+
+ const int buttonSpacing = 2;
+ const int buttonWidth =
+ (width - buttonSpacing * 2 -
+ buttonSpacing * (numChoices - 1)) / numChoices;
+ const int buttonHeight = 13;
+
+
+ DialogTemplate dialogTemplate(
+ windowTitle,
+ WS_CAPTION | DS_CENTER | WS_SYSMENU,
+ 10, 10, width, height,
+ "Tahoma");
+
+ dialogTemplate.AddEditBox(
+ "Edit", WS_VISIBLE | ES_READONLY | ES_OEMCONVERT | ES_MULTILINE | WS_TABSTOP, WS_EX_STATICEDGE,
+ 2, 2, width - 4, height - buttonHeight - 7, IDC_MESSAGE);
+
+ int i;
+ for (i = 0; i < numChoices; i++) {
+
+ int x = buttonSpacing + i * (buttonWidth + buttonSpacing);
+ int y = height - buttonHeight - buttonSpacing;
+
+ dialogTemplate.AddButton(choice[i], WS_VISIBLE | WS_TABSTOP, 0,
+ x, y, buttonWidth, buttonHeight, IDC_BUTTON0 + (WORD)i);
+
+ }
+
+ // Convert all single \n characters to \r\n for proper printing
+ int strLen = 0;
+ const char* pStr = prompt;
+
+ while (*pStr != '\0') {
+ if ((*pStr == '\n') && (pStr != prompt)) {
+ if (*(pStr - 1) != '\r') {
+ ++strLen;
+ }
+ }
+ ++strLen;
+ ++pStr;
+ }
+
+ char* newStr = (char*)malloc(strLen + 1);
+
+ const char* pStr2 = prompt;
+ char* pNew = newStr;
+
+ while (*pStr2 != '\0') {
+ if ((*pStr2 == '\n') && (pStr2 != prompt)) {
+ if (*(pStr2 - 1) != '\r') {
+ *pNew = '\r';
+ ++pNew;
+ }
+ }
+ *pNew = *pStr2;
+ ++pNew;
+ ++pStr2;
+ }
+
+ *pNew = '\0';
+
+ PromptParams params;
+ params.message = newStr;;
+ params.title = windowTitle;
+
+ HMODULE module = GetModuleHandle(0);
+ int ret = DialogBoxIndirectParam(module, dialogTemplate, NULL, (DLGPROC) PromptDlgProc, (DWORD)&params);
+
+ free(newStr);
+
+ /*
+ For debugging when DialogBoxIndirectParam fails:
+
+ // The last error value. (Which is preserved across the call).
+ DWORD lastErr = GetLastError();
+
+ // The decoded message from FormatMessage
+ LPTSTR formatMsg = NULL;
+
+ if (NULL == formatMsg) {
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ lastErr,
+ 0,
+ (LPTSTR)&formatMsg,
+ 0,
+ NULL);
+ }
+
+ // Make sure the message got translated into something.
+ LPTSTR realLastErr;
+ if (NULL != formatMsg) {
+ realLastErr = formatMsg;
+ } else {
+ realLastErr = "Last error code does not exist.";
+ }
+
+ // Get rid of the allocated memory from FormatMessage.
+ if (NULL != formatMsg) {
+ LocalFree((LPVOID)formatMsg);
+ }
+ */
+
+ return ret;
+}
+
+#endif
+
+
+/**
+ * Show a prompt on stdout
+ */
+static int textPrompt(
+ const char* windowTitle,
+ const char* prompt,
+ const char** choice,
+ int numChoices) {
+
+ printf("\n___________________________________________________\n");
+ printf("%s\n", windowTitle);
+ printf("%s", prompt);
+
+ if (numChoices > 10) {
+ numChoices = 10;
+ }
+
+ int c = -1;
+ if (numChoices > 1) {
+ printf("\n");
+ printf("Choose an option by number:");
+
+ while ((c < 0) || (c >= numChoices)) {
+ printf("\n");
+
+ for (int i = 0; i < numChoices; i++) {
+ if (numChoices <= 3) {
+ printf(" (%d) %s ", i, choice[i]);
+ } else {
+ printf(" (%d) %s\n", i, choice[i]);
+ }
+ }
+
+ printf("\n> ");
+ c = _getch() - '0';
+
+ if ((c < 0) || (c >= numChoices)) {
+ printf("'%d' is not a valid choice.", c);
+ } else {
+ printf("%d", c);
+ }
+ }
+
+ } else if (numChoices == 1) {
+
+ printf("\nPress any key for '%s'...", choice[0]);
+ _getch();
+ c = 0;
+
+ } else {
+
+ printf("\nPress any key...");
+ _getch();
+ c = 0;
+ }
+
+ printf("\n___________________________________________________\n");
+ return c;
+}
+
+#ifdef G3D_OSX
+
+// See http://developer.apple.com/documentation/Carbon/Reference/Carbon_Event_Manager_Ref/index.html
+
+#define CARBON_COMMANDID_START 128
+#define CARBON_BUTTON_SPACING 12
+#define CARBON_BUTTON_HEIGHT 20
+#define CARBON_BUTTON_MINWIDTH 69
+#define CARBON_WINDOW_PADDING 20
+
+struct CallbackData {
+ WindowRef refWindow;
+
+ /** Index of this particular button */
+ int myIndex;
+
+ /** Buttons store their index into here when pressed. */
+ int* whichButton;
+};
+
+/**
+ Assumes that userData is a pointer to a carbon_evt_data_t.
+
+ */
+static pascal OSStatus DoCommandEvent(EventHandlerCallRef handlerRef, EventRef event, void* userData) {
+ // See http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/index.html
+
+ CallbackData& callbackData = *(CallbackData*)userData;
+
+# pragma unused(handlerRef)
+
+ callbackData.whichButton[0] = callbackData.myIndex;
+
+ // If we get here we can close the window
+ ::QuitAppModalLoopForWindow(callbackData.refWindow);
+
+ // Return noErr to indicate that we handled the event
+ return noErr;
+}
+
+static int guiPrompt
+(const char* windowTitle,
+ const char* prompt,
+ const char** choice,
+ int numChoices) {
+
+ WindowRef window;
+
+ int iNumButtonRows = 0;
+ int iButtonWidth = -1;
+ OSStatus err = noErr;
+
+ // Determine number of rows of buttons
+ while (iButtonWidth < CARBON_BUTTON_MINWIDTH) {
+ ++iNumButtonRows;
+ iButtonWidth =
+ (550 - (CARBON_WINDOW_PADDING*2 +
+ (CARBON_BUTTON_SPACING*numChoices))) /
+ (numChoices/iNumButtonRows);
+ }
+
+ // Window Variables
+ Rect rectWin = {0, 0, 200 + ((iNumButtonRows-1) * (CARBON_BUTTON_HEIGHT+CARBON_BUTTON_SPACING)), 550}; // top, left, bottom, right
+ CFStringRef szWindowTitle = CFStringCreateWithCString(kCFAllocatorDefault, windowTitle, kCFStringEncodingUTF8);
+
+ window = NULL;
+
+ err = CreateNewWindow(kMovableAlertWindowClass, kWindowStandardHandlerAttribute|kWindowCompositingAttribute, &rectWin, &window);
+ err = SetWindowTitleWithCFString(window, szWindowTitle);
+ err = SetThemeWindowBackground(window, kThemeBrushAlertBackgroundActive, false);
+ assert(err == noErr);
+
+ // Event Handler Variables
+ EventTypeSpec buttonSpec[] = {{ kEventClassControl, kEventControlHit }, { kEventClassCommand, kEventCommandProcess }};
+ EventHandlerUPP buttonHandler = NewEventHandlerUPP(DoCommandEvent);
+
+ // Static Text Variables
+ Rect rectStatic = {20, 20, 152, 530};
+ CFStringRef szStaticText = CFStringCreateWithCString(kCFAllocatorDefault, prompt, kCFStringEncodingUTF8);
+ ControlRef refStaticText = NULL;
+ err = CreateStaticTextControl(window, &rectStatic, szStaticText, NULL, &refStaticText);
+
+ // Button Variables
+ Rect bounds[numChoices];
+ CFStringRef caption[numChoices];
+ ControlRef button[numChoices];
+
+ int whichButton=-1;
+ CallbackData callbackData[numChoices];
+
+ // Create the Buttons and assign event handlers
+ for (int i = 0; i < numChoices; ++i) {
+ bounds[i].top = 160 + ((CARBON_BUTTON_HEIGHT+CARBON_BUTTON_SPACING)*(i%iNumButtonRows));
+ bounds[i].right = 530 - ((iButtonWidth+CARBON_BUTTON_SPACING)*(i/iNumButtonRows));
+ bounds[i].left = bounds[i].right - iButtonWidth;
+ bounds[i].bottom = bounds[i].top + CARBON_BUTTON_HEIGHT;
+
+ // Convert the button captions to Apple strings
+ caption[i] = CFStringCreateWithCString(kCFAllocatorDefault, choice[i], kCFStringEncodingUTF8);
+
+ err = CreatePushButtonControl(window, &bounds[i], caption[i], &button[i]);
+ assert(err == noErr);
+
+ err = SetControlCommandID(button[i], CARBON_COMMANDID_START + i);
+ assert(err == noErr);
+
+ callbackData[i].refWindow = window;
+ callbackData[i].myIndex = i;
+ callbackData[i].whichButton = &whichButton;
+
+ err = InstallControlEventHandler(button[i], buttonHandler,
+ GetEventTypeCount(buttonSpec), buttonSpec,
+ &callbackData[i], NULL);
+ assert(err == noErr);
+ }
+
+ // Show Dialog
+ err = RepositionWindow(window, NULL, kWindowCenterOnMainScreen);
+ ShowWindow(window);
+ BringToFront(window);
+ err = ActivateWindow(window, true);
+
+ // Hack to get our window/process to the front...
+ ProcessSerialNumber psn = { 0, kCurrentProcess};
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess (&psn);
+
+ // Run in Modal State
+ err = RunAppModalLoopForWindow(window);
+
+ // Dispose of Button Related Data
+ for (int i = 0; i < numChoices; ++i) {
+ // Dispose of controls
+ DisposeControl(button[i]);
+
+ // Release CFStrings
+ CFRelease(caption[i]);
+ }
+
+ // Dispose of Other Controls
+ DisposeControl(refStaticText);
+
+ // Dispose of Event Handlers
+ DisposeEventHandlerUPP(buttonHandler);
+
+ // Dispose of Window
+ DisposeWindow(window);
+
+ // Release CFStrings
+ CFRelease(szWindowTitle);
+ CFRelease(szStaticText);
+
+ // Return Selection
+ return whichButton;
+}
+
+#endif
+
+int prompt(
+ const char* windowTitle,
+ const char* prompt,
+ const char** choice,
+ int numChoices,
+ bool useGui) {
+
+ #ifdef G3D_WIN32
+ if (useGui) {
+ // Build the message box
+ return guiPrompt(windowTitle, prompt, choice, numChoices);
+ }
+ #endif
+
+ #ifdef G3D_OSX
+ if (useGui){
+ //Will default to text prompt if numChoices > 4
+ return guiPrompt(windowTitle, prompt, choice, numChoices);
+ }
+ #endif
+ return textPrompt(windowTitle, prompt, choice, numChoices);
+}
+
+
+void msgBox(
+ const std::string& message,
+ const std::string& title) {
+
+ const char *choice[] = {"Ok"};
+ prompt(title.c_str(), message.c_str(), choice, 1, true);
+}
+
+#ifndef G3D_WIN32
+ #undef _getch
+#endif
+
+};// namespace
+
diff --git a/dep/src/g3dlite/stringutils.cpp b/dep/src/g3dlite/stringutils.cpp
new file mode 100644
index 00000000000..c3876ebb6a4
--- /dev/null
+++ b/dep/src/g3dlite/stringutils.cpp
@@ -0,0 +1,275 @@
+/**
+ @file stringutils.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2000-09-09
+ @edited 2008-01-10
+*/
+
+#include "G3D/platform.h"
+#include "G3D/stringutils.h"
+#include "G3D/BinaryInput.h"
+#include <algorithm>
+
+namespace G3D {
+
+#ifdef _MSC_VER
+ // disable: "C++ exception handler used"
+# pragma warning (push)
+# pragma warning (disable : 4530)
+#endif
+#ifdef G3D_WIN32
+ const char* NEWLINE = "\r\n";
+#else
+ const char* NEWLINE = "\n";
+ static bool iswspace(int ch) { return (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'); }
+#endif
+
+void parseCommaSeparated(const std::string s, Array<std::string>& array, bool stripQuotes) {
+ array.fastClear();
+ if (s == "") {
+ return;
+ }
+
+ size_t begin = 0;
+ const char delimiter = ',';
+ const char quote = '\"';
+ do {
+ size_t end = begin;
+ // Find the next comma, or the end of the string
+ bool inQuotes = false;
+ while ((end < s.length()) && (inQuotes || (s[end] != delimiter))) {
+ if (s[end] == quote) {
+ if ((end < s.length() - 2) && (s[end + 1] == quote) && (s[end + 2]) == quote) {
+ // Skip over the superquote
+ end += 2;
+ }
+ inQuotes = ! inQuotes;
+ }
+ ++end;
+ }
+ array.append(s.substr(begin, end - begin));
+ begin = end + 1;
+ } while (begin < s.length());
+
+ if (stripQuotes) {
+ for (int i = 0; i < array.length(); ++i) {
+ std::string& t = array[i];
+ int L = t.length();
+ if ((L > 1) && (t[0] == quote) && (t[L - 1] == quote)) {
+ if ((L > 6) && (t[1] == quote) && (t[2] == quote) && (t[L - 3] == quote) && (t[L - 2] == quote)) {
+ // Triple-quote
+ t = t.substr(3, L - 6);
+ } else {
+ // Double-quote
+ t = t.substr(1, L - 2);
+ }
+ }
+ }
+ }
+}
+
+bool beginsWith(
+ const std::string& test,
+ const std::string& pattern) {
+
+ if (test.size() >= pattern.size()) {
+ for (int i = 0; i < (int)pattern.size(); ++i) {
+ if (pattern[i] != test[i]) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+bool endsWith(
+ const std::string& test,
+ const std::string& pattern) {
+
+ if (test.size() >= pattern.size()) {
+ int te = test.size() - 1;
+ int pe = pattern.size() - 1;
+ for (int i = pattern.size() - 1; i >= 0; --i) {
+ if (pattern[pe - i] != test[te - i]) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+std::string wordWrap(
+ const std::string& input,
+ int numCols) {
+
+ std::string output;
+ size_t c = 0;
+ int len;
+
+ // Don't make lines less than this length
+ int minLength = numCols / 4;
+ size_t inLen = input.size();
+
+ bool first = true;
+ while (c < inLen) {
+ if (first) {
+ first = false;
+ } else {
+ output += NEWLINE;
+ }
+
+ if ((int)inLen - (int)c - 1 < numCols) {
+ // The end
+ output += input.substr(c, inLen - c);
+ break;
+ }
+
+ len = numCols;
+
+ // Look at character c + numCols, see if it is a space.
+ while ((len > minLength) &&
+ (input[c + len] != ' ')) {
+ len--;
+ }
+
+ if (len == minLength) {
+ // Just crop
+ len = numCols;
+
+ }
+
+ output += input.substr(c, len);
+ c += len;
+ if (c < input.size()) {
+ // Collapse multiple spaces.
+ while ((input[c] == ' ') && (c < input.size())) {
+ c++;
+ }
+ }
+ }
+
+ return output;
+}
+
+
+int stringCompare(
+ const std::string& s1,
+ const std::string& s2) {
+
+ return stringPtrCompare(&s1, &s2);
+}
+
+
+int stringPtrCompare(
+ const std::string* s1,
+ const std::string* s2) {
+
+ return s1->compare(*s2);
+}
+
+
+std::string toUpper(const std::string& x) {
+ std::string result = x;
+ std::transform(result.begin(), result.end(), result.begin(), toupper);
+ return result;
+}
+
+
+std::string toLower(const std::string& x) {
+ std::string result = x;
+ std::transform(result.begin(), result.end(), result.begin(), tolower);
+ return result;
+}
+
+
+Array<std::string> stringSplit(
+ const std::string& x,
+ char splitChar) {
+
+ Array<std::string> out;
+
+ // Pointers to the beginning and end of the substring
+ const char* start = x.c_str();
+ const char* stop = start;
+
+ while ((stop = strchr(start, splitChar))) {
+ out.append(std::string(start, stop - start));
+ start = stop + 1;
+ }
+
+ // Append the last one
+ out.append(std::string(start));
+
+ return out;
+}
+
+
+std::string stringJoin(
+ const Array<std::string>& a,
+ char joinChar) {
+
+ std::string out;
+
+ for (int i = 0; i < (int)a.size() - 1; ++i) {
+ out += a[i] + joinChar;
+ }
+
+ if (a.size() > 0) {
+ return out + a.last();
+ } else {
+ return out;
+ }
+}
+
+
+std::string stringJoin(
+ const Array<std::string>& a,
+ const std::string& joinStr) {
+
+ std::string out;
+
+ for (int i = 0; i < (int)a.size() - 1; ++i) {
+ out += a[i] + joinStr;
+ }
+
+ if (a.size() > 0) {
+ return out + a.last();
+ } else {
+ return out;
+ }
+}
+
+
+std::string trimWhitespace(
+ const std::string& s) {
+
+ size_t left = 0;
+
+ // Trim from left
+ while ((left < s.length()) && iswspace(s[left])) {
+ ++left;
+ }
+
+ int right = s.length() - 1;
+ // Trim from right
+ while ((right > (int)left) && iswspace(s[right])) {
+ --right;
+ }
+
+ return s.substr(left, right - left + 1);
+}
+
+}; // namespace
+
+#undef NEWLINE
+#ifdef _MSC_VER
+# pragma warning (pop)
+#endif
diff --git a/dep/src/g3dlite/uint128.cpp b/dep/src/g3dlite/uint128.cpp
new file mode 100644
index 00000000000..1f596fc3e51
--- /dev/null
+++ b/dep/src/g3dlite/uint128.cpp
@@ -0,0 +1,155 @@
+/**
+ @file uint128.cpp
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @author Kyle Whitson
+
+ @created 2008-07-17
+ @edited 2008-07-17
+ */
+
+#include "G3D/uint128.h"
+
+namespace G3D {
+
+/** Adds two 64-bit integers, placing the result and the overflow into 64-bit integers.*/
+static void addAndCarry(const uint64& _a, const uint64& _b, uint64& carry, uint64& result) {
+
+ // Break each number into 4 32-bit chunks. Since we are using uints, right-shifting will fill with zeros.
+ // This eliminates the need to and with 0xFFFFFFFF.
+ uint32 a [2] = {_a & 0xFFFFFFFF, _a >> 32};
+ uint32 b [2] = {_b & 0xFFFFFFFF, _b >> 32};
+
+ uint64 tmp = uint64(a[0]) + b[0];
+
+ result = tmp & 0xFFFFFFFF;
+ uint32 c = tmp >> 32;
+
+ tmp = uint64(c) + a[1] + b[1];
+ result += tmp << 32;
+ carry = (tmp >> 32);
+}
+
+/** Multiplies two unsigned 64-bit integers, placing the result into one 64-bit int and the overflow into another.*/
+void multiplyAndCarry(const uint64& _a, const uint64& _b, uint64& carry, uint64& result) {
+
+ // Break each number into 4 32-bit chunks. Since we are using uints, right-shifting will fill with zeros.
+ // This eliminates the need to and with 0xFFFFFFFF.
+ uint32 a [2] = {_a & 0xFFFFFFFF, _a >> 32};
+ uint32 b [2] = {_b & 0xFFFFFFFF, _b >> 32};
+
+ uint64 prod [2][2];
+ for(int i = 0; i < 2; ++i) {
+ for(int j = 0; j < 2; ++j) {
+ prod[i][j] = uint64(a[i]) * b[j];
+ }
+ }
+
+ // The product of the low bits of a and b will always fit into the result
+ result = prod[0][0];
+
+ // The product of the high bits of a and b will never fit into the result
+ carry = prod[1][1];
+
+ // The high 32 bits of prod[0][1] and prod[1][0] will never fit into the result
+ carry += prod[0][1] >> 32;
+ carry += prod[1][0] >> 32;
+
+ uint64 tmp;
+ addAndCarry(result, (prod[0][1] << 32), tmp, result);
+ carry += tmp;
+ addAndCarry(result, (prod[1][0] << 32), tmp, result);
+ carry += tmp;
+}
+
+
+uint128::uint128(const uint64& hi, const uint64& lo) : hi(hi), lo(lo) {
+}
+
+uint128::uint128(const uint64& lo) : hi(0), lo(lo) {
+}
+
+uint128& uint128::operator+=(const uint128& x) {
+
+ G3D::uint64 carry;
+ addAndCarry(lo, x.lo, carry, lo);
+
+ // Adding the carry will change hi. Save the old hi bits in case this == x.
+ const uint64 xHi = x.hi;
+ hi += carry;
+ hi += xHi;
+ return *this;
+}
+
+uint128& uint128::operator*=(const uint128& x) {
+
+ // The low bits will get overwritten when doing the multiply, so back up both (in case &x == this)
+ const uint64 oldLo = lo;
+ const uint64 oldXLo = x.lo;
+
+ G3D::uint64 carry;
+ multiplyAndCarry(oldLo, oldXLo, carry, lo);
+
+ // Overflow doesn't matter here because the result is going into hi - any overflow will exceed the capacity of a 128-bit number
+ // Note: hi * x.hi will always overflow, since (x * 2^64) * (y * 2^64) = x*y*(2^128). The largest number expressable in 128 bits is
+ // 2^128 - 1.
+ hi = carry + (oldLo * x.hi) + (hi * oldXLo);
+
+ return *this;
+}
+
+uint128& uint128::operator^=(const uint128& x) {
+ hi ^= x.hi;
+ lo ^= x.lo;
+ return *this;
+}
+
+uint128& uint128::operator&=(const uint128& x) {
+ hi &= x.hi;
+ lo &= x.lo;
+ return *this;
+}
+
+uint128& uint128::operator|=(const uint128& x) {
+ hi |= x.hi;
+ lo |= x.lo;
+ return *this;
+}
+
+bool uint128::operator==(const uint128& x) {
+ return (hi == x.hi) && (lo == x.lo);
+}
+
+uint128& uint128::operator>>=(const int x) {
+
+ //Before shifting, mask out the bits that will be shifted out of hi.
+ //Put a 1 in the first bit that will not be lost in the shift, then subtract 1 to get the mask.
+ uint64 mask = ((uint64)1L << x) - 1;
+ uint64 tmp = hi & mask;
+ hi >>= x;
+
+ //Shift lo and add the bits shifted down from hi
+ lo = (lo >> x) + (tmp << (64 - x));
+
+ return *this;
+}
+
+uint128& uint128::operator<<=(const int x) {
+
+ //Before shifting, mask out the bits that will be shifted out of lo.
+ //Put a 1 in the last bit that will be lost in the shift, then subtract 1 to get the logical inverse of the mask.
+ //A bitwise NOT will then produce the correct mask.
+ uint64 mask = ~((((uint64)1L) << (64 - x)) - 1);
+ uint64 tmp = lo & mask;
+ lo <<= x;
+
+ //Shift hi and add the bits shifted up from lo
+ hi = (hi << x) + (tmp >> (64 - x));
+
+ return *this;
+}
+
+uint128 uint128::operator&(const uint128& x) {
+ return uint128(hi & x.hi, lo & x.lo);
+}
+}
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index bbb81bd3c9b..fbfae17a48b 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -1539,7 +1539,7 @@ bool Creature::FallGround()
float x, y, z;
GetPosition(x, y, z);
- float ground_Z = GetMap()->GetVmapHeight(x, y, z);
+ float ground_Z = GetMap()->GetHeight(x, y, z);
if (fabs(ground_Z - z) < 0.1f)
return false;
diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h
index 28eef9f714e..bd72026d753 100644
--- a/src/game/DBCEnums.h
+++ b/src/game/DBCEnums.h
@@ -250,8 +250,8 @@ enum AreaFlags
AREA_FLAG_UNK7 = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn
AREA_FLAG_UNK8 = 0x00800000, // Westguard Inn, Acherus: The Ebon Hold, Valgarde
AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp and it's subzones
- AREA_FLAG_UNK9 = 0x02000000, // unknown
- AREA_FLAG_UNK10 = 0x04000000, // unknown
+ AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
+ AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
AREA_FLAG_OUTDOOR_PVP2 = 0x08000000, // Wintergrasp and it's subzones
AREA_FLAG_NO_FLY_ZONE = 0x20000000 // Marks zones where you cannot fly
};
diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp
index fff32dff566..ba0e3af9a64 100644
--- a/src/game/DBCStores.cpp
+++ b/src/game/DBCStores.cpp
@@ -32,11 +32,32 @@
typedef std::map<uint16,uint32> AreaFlagByAreaID;
typedef std::map<uint32,uint32> AreaFlagByMapID;
+struct WMOAreaTableTripple
+{
+ WMOAreaTableTripple(int32 r, int32 a, int32 g) : rootId(r), adtId(a), groupId(g)
+ {
+ }
+
+ bool operator <(const WMOAreaTableTripple& b) const
+ {
+ return memcmp(this, &b, sizeof(WMOAreaTableTripple))<0;
+ }
+
+ // ordered by entropy; that way memcmp will have a minimal medium runtime
+ int32 groupId;
+ int32 rootId;
+ int32 adtId;
+};
+
+typedef std::map<WMOAreaTableTripple, WMOAreaTableEntry const *> WMOAreaInfoByTripple;
+
DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt);
DBCStorage <AreaGroupEntry> sAreaGroupStore(AreaGroupEntryfmt);
DBCStorage <AreaPOIEntry> sAreaPOIStore(AreaPOIEntryfmt);
static AreaFlagByAreaID sAreaFlagByAreaID;
-static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files
+static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files
+
+static WMOAreaInfoByTripple sWMOAreaInfoByTripple;
DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt);
DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt);
@@ -161,7 +182,8 @@ static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
-DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
+DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore(WMOAreaTableEntryfmt);
+DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
@@ -542,6 +564,14 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWMOAreaTableStore, dbcPath,"WMOAreaTable.dbc");
+ for(uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i)
+ {
+ if(WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i))
+ {
+ sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry));
+ }
+ }
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc");
@@ -635,6 +665,14 @@ int32 GetAreaFlagByAreaID(uint32 area_id)
return i->second;
}
+WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid)
+{
+ WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid));
+ if(i == sWMOAreaInfoByTripple.end())
+ return NULL;
+ return i->second;
+}
+
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id)
{
int32 areaflag = GetAreaFlagByAreaID(area_id);
diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h
index acf5ac8ec41..b14814e07a1 100644
--- a/src/game/DBCStores.h
+++ b/src/game/DBCStores.h
@@ -37,6 +37,8 @@ AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id);
uint32 GetAreaFlagByMapId(uint32 mapid);
+WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid);
+
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
enum ContentLevels
@@ -155,6 +157,7 @@ extern TaxiPathNodesByPath sTaxiPathNodesByPath;
extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore;
extern DBCStorage <VehicleEntry> sVehicleStore;
extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
+extern DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore;
//extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 584fc70984c..0fc0d1251f5 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1815,6 +1815,23 @@ struct VehicleSeatEntry
bool IsUsable() const { return m_flags & 0x2000000; }
};
+struct WMOAreaTableEntry
+{
+ uint32 Id; // 0 index
+ int32 rootId; // 1 used in root WMO
+ int32 adtId; // 2 used in adt file
+ int32 groupId; // 3 used in group WMO
+ //uint32 field4;
+ //uint32 field5;
+ //uint32 field6;
+ //uint32 field7;
+ //uint32 field8;
+ uint32 Flags; // 9 used for indoor/outdoor determination
+ uint32 areaId; // 10 link to AreaTableEntry.ID
+ //char *Name[16];
+ //uint32 nameFlags;
+};
+
struct WorldMapAreaEntry
{
//uint32 ID; // 0
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
index bed688cc126..1f1b010a6fd 100644
--- a/src/game/DBCfmt.h
+++ b/src/game/DBCfmt.h
@@ -114,6 +114,7 @@ const char TaxiPathNodeEntryfmt[]="diiifffiixx";
const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
+const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx";
const char WorldMapAreaEntryfmt[]="xinxffffixx";
const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx";
const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index b06e3628a27..11189d519a0 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -741,6 +741,15 @@ bool ChatHandler::HandleGPSCommand(const char* args)
uint32 have_map = Map::ExistMap(obj->GetMapId(),gx,gy) ? 1 : 0;
uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0;
+ if(have_vmap)
+ {
+ if(map->IsOutdoors(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ()))
+ PSendSysMessage("You are outdoors");
+ else
+ PSendSysMessage("You are indoor");
+ }
+ else PSendSysMessage("no VMAP available for area info");
+
PSendSysMessage(LANG_MAP_POSITION,
obj->GetMapId(), (mapEntry ? mapEntry->name[GetSessionDbcLocale()] : "<unknown>"),
zone_id, (zoneEntry ? zoneEntry->area_name[GetSessionDbcLocale()] : "<unknown>"),
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 53efb35e373..f8e48d3a326 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -1746,220 +1746,105 @@ float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
}
}
-float Map::GetVmapHeight(float x, float y, float z) const
+inline bool IsOutdoorWMO(uint32 mogpFlags, int32 adtId, int32 rootId, int32 groupId, WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry)
{
- float mapHeight;
-
- mapHeight = GetHeight(x, y, z, false);
- if (fabs(mapHeight - z) < 0.1)
- return mapHeight;
+ bool outdoor = true;
- VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
- if (!vmgr->isLineOfSightCalcEnabled())
- return mapHeight;
+ if(wmoEntry && atEntry)
+ {
+ if(atEntry->flags & AREA_FLAG_OUTSIDE)
+ return true;
+ if(atEntry->flags & AREA_FLAG_INSIDE)
+ return false;
+ }
- float vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f, z + 2.0f - mapHeight);
- if (vmapHeight > VMAP_INVALID_HEIGHT_VALUE)
- return vmapHeight;
+ outdoor = mogpFlags&0x8;
- return mapHeight;
+ if(wmoEntry)
+ {
+ if(wmoEntry->Flags & 4)
+ return true;
+ if((wmoEntry->Flags & 2)!=0)
+ outdoor = false;
+ }
+ return outdoor;
}
-uint16 Map::GetAreaFlag(float x, float y, float z) const
+bool Map::IsOutdoors(float x, float y, float z) const
{
- uint16 areaflag;
- if (GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
- areaflag = gmap->getArea(x, y);
- // this used while not all *.map files generated (instances)
- else
- areaflag = GetAreaFlagByMapId(GetId());
-
- //FIXME: some hacks for areas above or underground for ground area
- // required for area specific spells/etc, until map/vmap data
- // not provided correct areaflag with this hacks
- switch(areaflag)
- {
- case 2817: // Argent Tournament Grounds (Icecrown)
- if (x < 8445.0f && x > 8390.0f && y > 640.0f && y < 689.0f && 548.0f < z && z < 562.0f)
- areaflag = 2875; // Sunreaver Pavilion (Icecrown)
- else if (x > 8587.0f && x < 8629.0f && y > 646.0f && y < 686.0f && 548.0f < z && z < 562.0f)
- areaflag = 2879; // Silver Covenant Pavilion (Icecrown)
- break;
- case 2227: // The Foot Steppes (Storm Peaks)
- case 2207: // Sifreldar Village (Storm Peaks)
- if (6924.0f < x && x < 6980.0f && -1520.0f < y && y < -1432.0f && 838.0f < z && z < 843.0f)
- areaflag = 2213; // The Forlorn Mine (Storm Peaks)
- break;
- case 2209: // Brunnhildar Village (Storm Peaks)
- if (6885.0f < x && x < 6938.0f && -1200.0f < y && y < -1138.0f && 801.0f < z && z < 809.0f)
- areaflag = 2213; // The Forlorn Mine (Storm Peaks)
- break;
- case 166: // Storm Peaks
- if (6812.0f < x && x < 7048.0f && -1463.0f < y && y < -1200.0f && 807.0f < z && z < 843.0f)
- areaflag = 2213; // The Forlorn Mine (Storm Peaks)
- break;
- case 446: // (Stonelaton Mountains)
- case 944: // Boulderslide Ravine (Stonelaton Mountains)
- if (-128.0f < x && x < 35.0f && 221.0f < y && y < 456.0f && 87.0f < z && z < 130.0f)
- areaflag = 1019; // Boulderslide Cavern (Stonelaton Mountains)
- break;
- case 272: // Palemane Rock (Mulgore)
- if (-2466.0f < x && x < -2295.0f && 366.0f < y && y < 530.0f && 40.0f < z && z < 70.0f)
- areaflag = 668; // Palemane Rock (Mulgore)
- break;
- case 65535: // Multipe places.
- if (-128.0f < x && x < 35.0f && 221.0f < y && y < 456.0f && 87.0f < z && z < 130.0f)
- areaflag = 1019; // Boulderslide Cavern (Stonelaton Mountains)
- else if (-2466.0f < x && x < -2295.0f && 366.0f < y && y < 530.0f && 40.0f < z && z < 70.0f)
- areaflag = 668; // Palemane Rock (Mulgore)
- break;
- // Acherus: The Ebon Hold (Plaguelands: The Scarlet Enclave)
- case 1984: // Plaguelands: The Scarlet Enclave
- case 2076: // Death's Breach (Plaguelands: The Scarlet Enclave)
- case 2745: // The Noxious Pass (Plaguelands: The Scarlet Enclave)
- if (z > 350.0f) areaflag = 2048; break;
- // Acherus: The Ebon Hold (Eastern Plaguelands)
- case 856: // The Noxious Glade (Eastern Plaguelands)
- case 2456: // Death's Breach (Eastern Plaguelands)
- if (z > 350.0f) areaflag = 1950; break;
- // Dalaran
- case 2492: // Forlorn Woods (Crystalsong Forest)
- case 2371: // Valley of Echoes (Icecrown Glacier)
- if (x > 5568.0f && x < 6022.0f && y > 374.0f && y < 918.0f && z > 563.0f)
- {
- areaflag = 2153;
- if (y - 1.41f * x + 7649.55f > 0) // Violet Hold
- {
- if (y < 595.0f)
- areaflag = 2540;
- }
- else if (y + 2.91 * x - 17522.57f < 0) // Krasus landing
- areaflag = 2531;
- }
- break;
- // The Violet Citadel (Dalaran) or Dalaran
- case 2484: // The Twilight Rivulet (Crystalsong Forest)
- case 1593: // Crystalsong Forest
- // Dalaran
- if (x > 5568.0f && x < 6116.0f && y > 282.0f && y < 918.0f && z > 563.0f)
- {
- // The Violet Citadel (Dalaran), fast check
- if (x > 5721.1f && x < 5884.66f && y > 764.4f && y < 948.0f)
- {
- // The Violet Citadel (Dalaran)
- if ((x-5803.0f)*(x-5803.0f)+(y-846.18f)*(y-846.18f) < 6690.0f)
- {
- areaflag = 2696;
- break;
- }
- }
+ uint32 mogpFlags;
+ int32 adtId, rootId, groupId;
- // The Eventide (Dalaran), fast check against diagonal box with lower limit
- if (z > 635.0f && x+y < 6375.0f && x+y > 6295.0f && x-y < 5106.0f && x-y > 4972.0f)
- {
- areaflag = 2543;
- break;
- }
+ // no wmo found? -> outside by default
+ if(!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
+ return true;
- // The Violet Hold (Dalaran), fast check
- if (x < 5791.0f && y > 404.0f && y < 595.0f)
- {
- areaflag = 2540;
- break;
- }
+ AreaTableEntry const* atEntry = 0;
+ WMOAreaTableEntry const* wmoEntry= GetWMOAreaTableEntryByTripple(rootId, adtId, groupId);
+ if(wmoEntry)
+ {
+ DEBUG_LOG("Got WMOAreaTableEntry! flag %u, areaid %u", wmoEntry->Flags, wmoEntry->areaId);
+ atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
+ }
+ return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
+}
- // Dalaran
- areaflag = 2153;
- }
- break;
- // Vargoth's Retreat (Dalaran) or The Violet Citadel (Dalaran) or Dalaran
- case 2504: // Violet Stand (Crystalsong Forest)
- // Dalaran
- if (x > 5568.0f && x < 6116.0f && y > 282.0f && y < 982.0f && z > 563.0f)
- {
- // The Violet Citadel (Dalaran), fast check
- if (x > 5721.1f && x < 5884.66f && y > 764.4f && y < 948.0f)
- {
- // Vargoth's Retreat (Dalaran), nice slow circle with upper limit
- if (z < 898.0f && (x-5765.0f)*(x-5765.0f)+(y-862.4f)*(y-862.4f) < 262.0f)
- {
- areaflag = 2748;
- break;
- }
+bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
+{
+ float vmap_z = z;
+ VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
+ if (vmgr->getAreaInfo(GetId(), x, y, vmap_z, flags, adtId, rootId, groupId))
+ {
+ // check if there's terrain between player height and object height
+ if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ {
+ float _mapheight = gmap->getHeight(x,y);
+ // z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
+ if(z + 2.0f > _mapheight && _mapheight > vmap_z)
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
- // The Violet Citadel (Dalaran)
- if ((x-5803.0f)*(x-5803.0f)+(y-846.18f)*(y-846.18f) < 6690.0f)
- {
- areaflag = 2696;
- break;
- }
- }
+uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const
+{
+ uint32 mogpFlags;
+ int32 adtId, rootId, groupId;
+ WMOAreaTableEntry const* wmoEntry = 0;
+ AreaTableEntry const* atEntry = 0;
+ bool haveAreaInfo = false;
- // Dalaran
- areaflag = 2153;
- }
- break;
- // Maw of Neltharion (cave)
- case 164: // Dragonblight
- case 1797: // Obsidian Dragonshrine (Dragonblight)
- if (x > 4364.0f && x < 4632.0f && y > 1545.0f && y < 1886.0f && z < 200.0f) areaflag = 1853; break;
- // Undercity (sewers enter and path)
- case 179: // Tirisfal Glades
- if (x > 1595.0f && x < 1699.0f && y > 535.0f && y < 643.5f && z < 30.5f) areaflag = 685; break;
- // Undercity (Royal Quarter)
- case 210: // Silverpine Forest
- case 316: // The Shining Strand (Silverpine Forest)
- case 438: // Lordamere Lake (Silverpine Forest)
- if (x > 1237.0f && x < 1401.0f && y > 284.0f && y < 440.0f && z < -40.0f) areaflag = 685; break;
- // Undercity (cave and ground zone, part of royal quarter)
- case 607: // Ruins of Lordaeron (Tirisfal Glades)
- // ground and near to ground (by city walls)
- if (z > 0.0f)
- {
- if (x > 1510.0f && x < 1839.0f && y > 29.77f && y < 433.0f) areaflag = 685;
- }
- // more wide underground, part of royal quarter
- else
- {
- if (x > 1299.0f && x < 1839.0f && y > 10.0f && y < 440.0f) areaflag = 685;
- }
- break;
- // The Makers' Perch (ground) and Makers' Overlook (ground and cave)
- case 1335: // Sholazar Basin
- // The Makers' Perch ground (fast box)
- if (x > 6100.0f && x < 6250.0f && y > 5650.0f && y < 5800.0f)
- {
- // nice slow circle
- if ((x-6183.0f)*(x-6183.0f)+(y-5717.0f)*(y-5717.0f) < 2500.0f)
- areaflag = 2189;
- }
- // Makers' Overlook (ground and cave)
- else if (x > 5634.48f && x < 5774.53f && y < 3475.0f && z > 300.0f)
- {
- if (y > 3380.26f || (y > 3265.0f && z < 360.0f))
- areaflag = 2187;
- }
- break;
- // The Makers' Perch (underground)
- case 2147: // The Stormwright's Shelf (Sholazar Basin)
- if (x > 6199.0f && x < 6283.0f && y > 5705.0f && y < 5817.0f && z < 38.0f) areaflag = 2189; break;
- // Makers' Overlook (deep cave)
- case 267: // Icecrown
- if (x > 5684.0f && x < 5798.0f && y > 3035.0f && y < 3367.0f && z < 358.0f) areaflag = 2187; break;
- // Wyrmrest Temple (Dragonblight)
- case 1814: // Path of the Titans (Dragonblight)
- case 1897: // The Dragon Wastes (Dragonblight)
- // fast box
- if (x > 3400.0f && x < 3700.0f && y > 130.0f && y < 420.0f)
- {
- // nice slow circle
- if ((x-3546.87f)*(x-3546.87f)+(y-272.71f)*(y-272.71f) < 19600.0f) areaflag = 1791;
- }
- break;
+ if (GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
+ {
+ haveAreaInfo = true;
+ if (wmoEntry = GetWMOAreaTableEntryByTripple(rootId, adtId, groupId))
+ atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
+ }
+
+ uint16 areaflag;
+
+ if (atEntry)
+ areaflag = atEntry->exploreFlag;
+ else
+ {
+ if (GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ areaflag = gmap->getArea(x, y);
+ // this used while not all *.map files generated (instances)
+ else
+ areaflag = GetAreaFlagByMapId(i_mapEntry->MapID);
}
+ if (isOutdoors)
+ {
+ if (haveAreaInfo)
+ *isOutdoors = IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
+ else
+ *isOutdoors = true;
+ }
return areaflag;
-}
+ }
uint8 Map::GetTerrainType(float x, float y) const
{
@@ -1971,10 +1856,51 @@ uint8 Map::GetTerrainType(float x, float y) const
ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data) const
{
- if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
- return gmap->getLiquidStatus(x, y, z, ReqLiquidType, data);
- else
- return LIQUID_MAP_NO_WATER;
+ ZLiquidStatus result = LIQUID_MAP_NO_WATER;
+ VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
+ float liquid_level, ground_level = INVALID_HEIGHT;
+ uint32 liquid_type;
+ if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
+ {
+ sLog.outDebug("getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type);
+ // Check water level and ground level
+ if (liquid_level > ground_level && z > ground_level - 2)
+ {
+ // All ok in water -> store data
+ if (data)
+ {
+ data->type = liquid_type;
+ data->level = liquid_level;
+ data->depth_level = ground_level;
+ }
+
+ // For speed check as int values
+ int delta = int((liquid_level - z) * 10);
+
+ // Get position delta
+ if (delta > 20) // Under water
+ return LIQUID_MAP_UNDER_WATER;
+ if (delta > 0 ) // In water
+ return LIQUID_MAP_IN_WATER;
+ if (delta > -1) // Walk on water
+ return LIQUID_MAP_WATER_WALK;
+ result = LIQUID_MAP_ABOVE_WATER;
+ }
+ }
+
+ if(GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ {
+ LiquidData map_data;
+ ZLiquidStatus map_result = gmap->getLiquidStatus(x, y, z, ReqLiquidType, &map_data);
+ // Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
+ if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
+ {
+ if (data)
+ *data = map_data;
+ return map_result;
+ }
+ }
+ return result;
}
float Map::GetWaterLevel(float x, float y) const
@@ -2013,17 +1939,15 @@ void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 area
zoneid = entry ? ((entry->zone != 0) ? entry->zone : entry->ID) : 0;
}
-bool Map::IsInWater(float x, float y, float pZ, float min_depth) const
+bool Map::IsInWater(float x, float y, float pZ, LiquidData *data) const
{
// Check surface in x, y point for liquid
if (const_cast<Map*>(this)->GetGrid(x, y))
{
LiquidData liquid_status;
- if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, &liquid_status))
- {
- if (liquid_status.level - liquid_status.depth_level > min_depth)
+ LiquidData *liquid_ptr = data ? data : &liquid_status;
+ if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr))
return true;
- }
}
return false;
}
diff --git a/src/game/Map.h b/src/game/Map.h
index a192390ba37..ceb526b8244 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -314,14 +314,17 @@ class Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockabl
// some calls like isInWater should not use vmaps due to processor power
// can return INVALID_HEIGHT if under z+2 z coord not found height
float GetHeight(float x, float y, float z, bool pCheckVMap=true) const;
- float GetVmapHeight(float x, float y, float z) const;
- bool IsInWater(float x, float y, float z, float min_depth = 2.0f) const;
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0) const;
- uint16 GetAreaFlag(float x, float y, float z) const;
+ uint16 GetAreaFlag(float x, float y, float z, bool *isOutdoors=0) const;
+ bool GetAreaInfo(float x, float y, float z, uint32 &mogpflags, int32 &adtId, int32 &rootId, int32 &groupId) const;
+
+ bool IsOutdoors(float x, float y, float z) const;
+
uint8 GetTerrainType(float x, float y) const;
float GetWaterLevel(float x, float y) const;
+ bool IsInWater(float x, float y, float z, LiquidData *data = 0) const;
bool IsUnderWater(float x, float y, float z) const;
static uint32 GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id);
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 43965f5646a..2221098a9be 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1065,7 +1065,9 @@ void Player::HandleDrowning(uint32 time_diff)
uint32 damage = urand(600, 700);
if (m_MirrorTimerFlags&UNDERWATER_INLAVA)
EnvironmentalDamage(DAMAGE_LAVA, damage);
- else
+ // need to skip Slime damage in Undercity,
+ // maybe someone can find better way to handle environmental damage
+ else if (m_zoneUpdateId != 1497)
EnvironmentalDamage(DAMAGE_SLIME, damage);
}
}
@@ -4574,7 +4576,7 @@ bool Player::FallGround(uint8 FallMode)
float x, y, z;
GetPosition(x, y, z);
- float ground_Z = GetMap()->GetVmapHeight(x, y, z);
+ float ground_Z = GetMap()->GetHeight(x, y, z);
float z_diff = 0.0f;
if ((z_diff = fabs(ground_Z - z)) < 0.1f)
return false;
@@ -6123,7 +6125,7 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
if (GetTrader() && !IsWithinDistInMap(GetTrader(), INTERACTION_DISTANCE))
GetSession()->SendCancelTrade();
- CheckExploreSystem();
+ CheckAreaExploreAndOutdoor();
return true;
}
@@ -6197,7 +6199,7 @@ void Player::SendMovieStart(uint32 MovieId)
SendDirectMessage(&data);
}
-void Player::CheckExploreSystem()
+void Player::CheckAreaExploreAndOutdoor()
{
if (!isAlive())
return;
@@ -6213,8 +6215,13 @@ void Player::CheckExploreSystem()
GetSession()->HandleOnAreaChange(GetAreaEntryByAreaID(m_AreaID));
}
- uint16 areaFlag = GetBaseMap()->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ());
- if (areaFlag == 0xffff)
+ bool isOutdoor;
+ uint16 areaFlag = GetBaseMap()->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ(), &isOutdoor);
+
+ if (sWorld.getConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor)
+ RemoveAurasWithAttribute(SPELL_ATTR_OUTDOORS_ONLY);
+
+ if (areaFlag==0xffff)
return;
int offset = areaFlag / 32;
@@ -22019,8 +22026,8 @@ void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
{
m_MirrorTimerFlags &= ~(UNDERWATER_INWATER|UNDERWATER_INLAVA|UNDERWATER_INSLIME|UNDERWARER_INDARKWATER);
// Small hack for enable breath in WMO
- if (IsInWater())
- m_MirrorTimerFlags|=UNDERWATER_INWATER;
+ /* if (IsInWater())
+ m_MirrorTimerFlags|=UNDERWATER_INWATER; */
return;
}
diff --git a/src/game/Player.h b/src/game/Player.h
index af8c5fb971d..d6de8679323 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1845,7 +1845,7 @@ class Player : public Unit, public GridObject<Player>
void SetSemaphoreTeleportFar(bool semphsetting) { mSemaphoreTeleport_Far = semphsetting; }
void ProcessDelayedOperations();
- void CheckExploreSystem(void);
+ void CheckAreaExploreAndOutdoor(void);
static uint32 TeamForRace(uint8 race);
uint32 GetTeam() const { return m_team; }
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index b039767c463..5016e5ebc2b 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4404,6 +4404,17 @@ SpellCastResult Spell::CheckCast(bool strict)
if (bg->GetStatus() == STATUS_WAIT_LEAVE)
return SPELL_FAILED_DONT_REPORT;
+ if(m_caster->GetTypeId() == TYPEID_PLAYER && VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled())
+ {
+ if(m_spellInfo->Attributes & SPELL_ATTR_OUTDOORS_ONLY &&
+ !m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
+ return SPELL_FAILED_ONLY_OUTDOORS;
+
+ if(m_spellInfo->Attributes & SPELL_ATTR_INDOORS_ONLY &&
+ m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
+ return SPELL_FAILED_ONLY_INDOORS;
+ }
+
// only check at first call, Stealth auras are already removed at second call
// for now, ignore triggered spells
if (strict && !m_IsTriggeredSpell)
@@ -5248,7 +5259,7 @@ SpellCastResult Spell::CheckCast(bool strict)
{
float x, y, z;
m_caster->GetPosition(x, y, z);
- float ground_Z = m_caster->GetMap()->GetVmapHeight(x, y, z);
+ float ground_Z = m_caster->GetMap()->GetHeight(x, y, z);
if (fabs(ground_Z - z) < 0.1f)
return SPELL_FAILED_DONT_REPORT;
break;
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 4f0c693efbb..2f7486d53d9 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -50,10 +50,10 @@
#include "BattleGroundEY.h"
#include "BattleGroundWS.h"
#include "OutdoorPvPMgr.h"
-#include "VMapFactory.h"
#include "Language.h"
#include "SocialMgr.h"
#include "Util.h"
+#include "VMapFactory.h"
#include "TemporarySummon.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
@@ -7309,13 +7309,8 @@ void Spell::EffectTransmitted(uint32 effIndex)
Map *cMap = m_caster->GetMap();
if (goinfo->type == GAMEOBJECT_TYPE_FISHINGNODE)
{
- //dirty way to hack serpent shrine pool
- if (cMap->GetId() == 548 && m_caster->GetDistance(36.69, -416.38, -19.9645) <= 16)//center of strange pool
- {
- fx = 36.69+irand(-8,8);//random place for the bobber
- fy = -416.38+irand(-8,8);
- fz = -19.9645;//serpentshrine water level
- }else if (!cMap->IsInWater(fx, fy, fz-0.5f, 0.5f)) // Hack to prevent fishing bobber from failing to land on fishing hole
+ LiquidData liqData;
+ if ( !cMap->IsInWater(fx, fy, fz + 1.f/* -0.5f */, &liqData)) // Hack to prevent fishing bobber from failing to land on fishing hole
{ // but this is not proper, we really need to ignore not materialized objects
SendCastResult(SPELL_FAILED_NOT_HERE);
SendChannelUpdate(0);
@@ -7323,8 +7318,8 @@ void Spell::EffectTransmitted(uint32 effIndex)
}
// replace by water level in this case
- if (cMap->GetId() != 548)//if map is not serpentshrine caverns
- fz = cMap->GetWaterLevel(fx, fy);
+ //fz = cMap->GetWaterLevel(fx, fy);
+ fz = liqData.level;
}
// if gameobject is summoning object, it should be spawned right on caster's position
else if (goinfo->type == GAMEOBJECT_TYPE_SUMMONING_RITUAL)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index be0ee41f576..720e177075f 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -4169,6 +4169,18 @@ void Unit::RemoveAurasByType(AuraType auraType, uint64 casterGUID, Aura * except
}
}
+void Unit::RemoveAurasWithAttribute(uint32 flags)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
+ {
+ SpellEntry const *spell = iter->second->GetBase()->GetSpellProto();
+ if (spell->Attributes & flags)
+ RemoveAura(iter);
+ else
+ ++iter;
+ }
+}
+
void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase)
{
// single target auras from other casters
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 567fba03370..a2f4b2cd388 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1575,6 +1575,7 @@ class Unit : public WorldObject
void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except = NULL, bool negative = true, bool positive = true);
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = NULL);
+ void RemoveAurasWithAttribute(uint32 flags);
void RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID);
void RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode = AURA_REMOVE_BY_DEFAULT, uint32 except=0);
void RemoveMovementImpairingAuras();
diff --git a/src/game/World.cpp b/src/game/World.cpp
index 1629aa61af9..0b00621dc72 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1188,6 +1188,7 @@ void World::LoadConfigSettings(bool reload)
sLog.outString("Using DataDir %s",m_dataPath.c_str());
}
+ m_configs[CONFIG_VMAP_INDOOR_CHECK] = sConfig.GetBoolDefault("vmap.enableIndoorCheck", 0);
bool enableLOS = sConfig.GetBoolDefault("vmap.enableLOS", false);
bool enableHeight = sConfig.GetBoolDefault("vmap.enableHeight", false);
std::string ignoreMapIds = sConfig.GetStringDefault("vmap.ignoreMapIds", "");
diff --git a/src/game/World.h b/src/game/World.h
index 37e869f7ddf..2a4f963bfdb 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -279,6 +279,7 @@ enum WorldConfigs
CONFIG_STATS_SAVE_ONLY_ON_LOGOUT,
CONFIG_BG_XP_FOR_KILL,
CONFIG_RANDOM_BG_RESET_HOUR,
+ CONFIG_VMAP_INDOOR_CHECK,
CONFIG_VALUE_COUNT
};
diff --git a/src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp b/src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp
index 5dea18434a6..c4cf9ede397 100644
--- a/src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp
+++ b/src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp
@@ -1126,7 +1126,7 @@ struct mob_frost_wyrmAI : public hyjal_trashAI
float x,y,z;
me->GetPosition(x,y,z);
- z = me->GetMap()->GetVmapHeight(x, y, z);
+ z = me->GetMap()->GetHeight(x, y, z);
me->GetMotionMaster()->MovePoint(0,x,y,z);
me->GetMap()->CreatureRelocation(me, x,y,z,0);
}
@@ -1238,7 +1238,7 @@ struct mob_gargoyleAI : public hyjal_trashAI
{
float x,y,z;
me->GetPosition(x,y,z);
- z = me->GetMap()->GetVmapHeight(x, y, z);
+ z = me->GetMap()->GetHeight(x, y, z);
me->GetMotionMaster()->MovePoint(0,x,y,z);
me->GetMap()->CreatureRelocation(me, x,y,z,0);
hyjal_trashAI::JustDied(victim);
diff --git a/src/scripts/outland/black_temple/boss_teron_gorefiend.cpp b/src/scripts/outland/black_temple/boss_teron_gorefiend.cpp
index 4c3887e2ba3..670edc4d869 100644
--- a/src/scripts/outland/black_temple/boss_teron_gorefiend.cpp
+++ b/src/scripts/outland/black_temple/boss_teron_gorefiend.cpp
@@ -399,7 +399,7 @@ struct boss_teron_gorefiendAI : public ScriptedAI
float X = CalculateRandomLocation(pTarget->GetPositionX(), 20);
float Y = CalculateRandomLocation(pTarget->GetPositionY(), 20);
float Z = pTarget->GetPositionZ();
- Z = me->GetMap()->GetVmapHeight(X, Y, Z);
+ Z = me->GetMap()->GetHeight(X, Y, Z);
Creature* DoomBlossom = me->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
if (DoomBlossom)
{
diff --git a/src/shared/vmap/BIH.cpp b/src/shared/vmap/BIH.cpp
new file mode 100644
index 00000000000..4bd6b3c701e
--- /dev/null
+++ b/src/shared/vmap/BIH.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#include "BIH.h"
+
+void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats)
+{
+ // create space for the first node
+ tempTree.push_back(3 << 30); // dummy leaf
+ tempTree.insert(tempTree.end(), 2, 0);
+ //tempTree.add(0);
+
+ // seed bbox
+ AABound gridBox = { bounds.low(), bounds.high() };
+ AABound nodeBox = gridBox;
+ // seed subdivide function
+ subdivide(0, dat.numPrims - 1, tempTree, dat, gridBox, nodeBox, 0, 1, stats);
+}
+
+void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
+{
+ if ((right - left + 1) <= dat.maxPrims || depth >= MAX_STACK_SIZE)
+ {
+ // write leaf node
+ stats.updateLeaf(depth, right - left + 1);
+ createNode(tempTree, nodeIndex, left, right);
+ return;
+ }
+ // calculate extents
+ int axis = -1, prevAxis, rightOrig;
+ float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
+ float split = G3D::fnan(), prevSplit;
+ bool wasLeft = true;
+ while (true)
+ {
+ prevAxis = axis;
+ prevSplit = split;
+ // perform quick consistency checks
+ Vector3 d( gridBox.hi - gridBox.lo );
+ if (d.x < 0 || d.y < 0 || d.z < 0)
+ throw std::logic_error("negative node extents");
+ for (int i = 0; i < 3; i++)
+ {
+ if (nodeBox.hi[i] < gridBox.lo[i] || nodeBox.lo[i] > gridBox.hi[i])
+ {
+ //UI.printError(Module.ACCEL, "Reached tree area in error - discarding node with: %d objects", right - left + 1);
+ throw std::logic_error("invalid node overlap");
+ }
+ }
+ // find longest axis
+ axis = d.primaryAxis();
+ split = 0.5f * (gridBox.lo[axis] + gridBox.hi[axis]);
+ // partition L/R subsets
+ clipL = -G3D::inf();
+ clipR = G3D::inf();
+ rightOrig = right; // save this for later
+ float nodeL = G3D::inf();
+ float nodeR = -G3D::inf();
+ for (int i = left; i <= right;)
+ {
+ int obj = dat.indices[i];
+ float minb = dat.primBound[obj].low()[axis];
+ float maxb = dat.primBound[obj].high()[axis];
+ float center = (minb + maxb) * 0.5f;
+ if (center <= split)
+ {
+ // stay left
+ i++;
+ if (clipL < maxb)
+ clipL = maxb;
+ }
+ else
+ {
+ // move to the right most
+ int t = dat.indices[i];
+ dat.indices[i] = dat.indices[right];
+ dat.indices[right] = t;
+ right--;
+ if (clipR > minb)
+ clipR = minb;
+ }
+ nodeL = std::min(nodeL, minb);
+ nodeR = std::max(nodeR, maxb);
+ }
+ // check for empty space
+ if (nodeL > nodeBox.lo[axis] && nodeR < nodeBox.hi[axis])
+ {
+ float nodeBoxW = nodeBox.hi[axis] - nodeBox.lo[axis];
+ float nodeNewW = nodeR - nodeL;
+ // node box is too big compare to space occupied by primitives?
+ if (1.3f * nodeNewW < nodeBoxW)
+ {
+ stats.updateBVH2();
+ int nextIndex = tempTree.size();
+ // allocate child
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ // write bvh2 clip node
+ stats.updateInner();
+ tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
+ tempTree[nodeIndex + 1] = floatToRawIntBits(nodeL);
+ tempTree[nodeIndex + 2] = floatToRawIntBits(nodeR);
+ // update nodebox and recurse
+ nodeBox.lo[axis] = nodeL;
+ nodeBox.hi[axis] = nodeR;
+ subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
+ return;
+ }
+ }
+ // ensure we are making progress in the subdivision
+ if (right == rightOrig)
+ {
+ // all left
+ if (prevAxis == axis && prevSplit == split) {
+ // we are stuck here - create a leaf
+ stats.updateLeaf(depth, right - left + 1);
+ createNode(tempTree, nodeIndex, left, right);
+ return;
+ }
+ if (clipL <= split) {
+ // keep looping on left half
+ gridBox.hi[axis] = split;
+ prevClip = clipL;
+ wasLeft = true;
+ continue;
+ }
+ gridBox.hi[axis] = split;
+ prevClip = G3D::fnan();
+ }
+ else if (left > right)
+ {
+ // all right
+ if (prevAxis == axis && prevSplit == split) {
+ // we are stuck here - create a leaf
+ stats.updateLeaf(depth, right - left + 1);
+ createNode(tempTree, nodeIndex, left, right);
+ return;
+ }
+ right = rightOrig;
+ if (clipR >= split) {
+ // keep looping on right half
+ gridBox.lo[axis] = split;
+ prevClip = clipR;
+ wasLeft = false;
+ continue;
+ }
+ gridBox.lo[axis] = split;
+ prevClip = G3D::fnan();
+ }
+ else
+ {
+ // we are actually splitting stuff
+ if (prevAxis != -1 && !isnan(prevClip))
+ {
+ // second time through - lets create the previous split
+ // since it produced empty space
+ int nextIndex = tempTree.size();
+ // allocate child node
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ if (wasLeft) {
+ // create a node with a left child
+ // write leaf node
+ stats.updateInner();
+ tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
+ tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
+ tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::inf());
+ } else {
+ // create a node with a right child
+ // write leaf node
+ stats.updateInner();
+ tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
+ tempTree[nodeIndex + 1] = floatToRawIntBits(-G3D::inf());
+ tempTree[nodeIndex + 2] = floatToRawIntBits(prevClip);
+ }
+ // count stats for the unused leaf
+ depth++;
+ stats.updateLeaf(depth, 0);
+ // now we keep going as we are, with a new nodeIndex:
+ nodeIndex = nextIndex;
+ }
+ break;
+ }
+ }
+ // compute index of child nodes
+ int nextIndex = tempTree.size();
+ // allocate left node
+ int nl = right - left + 1;
+ int nr = rightOrig - (right + 1) + 1;
+ if (nl > 0) {
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ } else
+ nextIndex -= 3;
+ // allocate right node
+ if (nr > 0) {
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ tempTree.push_back(0);
+ }
+ // write leaf node
+ stats.updateInner();
+ tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
+ tempTree[nodeIndex + 1] = floatToRawIntBits(clipL);
+ tempTree[nodeIndex + 2] = floatToRawIntBits(clipR);
+ // prepare L/R child boxes
+ AABound gridBoxL(gridBox), gridBoxR(gridBox);
+ AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
+ gridBoxL.hi[axis] = gridBoxR.lo[axis] = split;
+ nodeBoxL.hi[axis] = clipL;
+ nodeBoxR.lo[axis] = clipR;
+ // recurse
+ if (nl > 0)
+ subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
+ else
+ stats.updateLeaf(depth + 1, 0);
+ if (nr > 0)
+ subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
+ else
+ stats.updateLeaf(depth + 1, 0);
+}
+
+bool BIH::writeToFile(FILE *wf) const
+{
+ uint32 treeSize = tree.size();
+ uint32 check=0, count=0;
+ check += fwrite(&bounds.low(), sizeof(float), 3, wf);
+ check += fwrite(&bounds.high(), sizeof(float), 3, wf);
+ check += fwrite(&treeSize, sizeof(uint32), 1, wf);
+ check += fwrite(&tree[0], sizeof(uint32), treeSize, wf);
+ count = objects.size();
+ check += fwrite(&count, sizeof(uint32), 1, wf);
+ check += fwrite(&objects[0], sizeof(uint32), count, wf);
+ return check == (3 + 3 + 2 + treeSize + count);
+}
+
+bool BIH::readFromFile(FILE *rf)
+{
+ uint32 treeSize;
+ Vector3 lo, hi;
+ uint32 check=0, count=0;
+ check += fread(&lo, sizeof(float), 3, rf);
+ check += fread(&hi, sizeof(float), 3, rf);
+ bounds = AABox(lo, hi);
+ check += fread(&treeSize, sizeof(uint32), 1, rf);
+ tree.resize(treeSize);
+ check += fread(&tree[0], sizeof(uint32), treeSize, rf);
+ check += fread(&count, sizeof(uint32), 1, rf);
+ objects.resize(count); // = new uint32[nObjects];
+ check += fread(&objects[0], sizeof(uint32), count, rf);
+ return check == (3 + 3 + 2 + treeSize + count);
+}
+
+void BIH::BuildStats::updateLeaf(int depth, int n)
+{
+ numLeaves++;
+ minDepth = std::min(depth, minDepth);
+ maxDepth = std::max(depth, maxDepth);
+ sumDepth += depth;
+ minObjects = std::min(n, minObjects);
+ maxObjects = std::max(n, maxObjects);
+ sumObjects += n;
+ int nl = std::min(n, 5);
+ ++numLeavesN[nl];
+}
+
+void BIH::BuildStats::printStats()
+{
+ printf("Tree stats:\n");
+ printf(" * Nodes: %d\n", numNodes);
+ printf(" * Leaves: %d\n", numLeaves);
+ printf(" * Objects: min %d\n", minObjects);
+ printf(" avg %.2f\n", (float) sumObjects / numLeaves);
+ printf(" avg(n>0) %.2f\n", (float) sumObjects / (numLeaves - numLeavesN[0]));
+ printf(" max %d\n", maxObjects);
+ printf(" * Depth: min %d\n", minDepth);
+ printf(" avg %.2f\n", (float) sumDepth / numLeaves);
+ printf(" max %d\n", maxDepth);
+ printf(" * Leaves w/: N=0 %3d%%\n", 100 * numLeavesN[0] / numLeaves);
+ printf(" N=1 %3d%%\n", 100 * numLeavesN[1] / numLeaves);
+ printf(" N=2 %3d%%\n", 100 * numLeavesN[2] / numLeaves);
+ printf(" N=3 %3d%%\n", 100 * numLeavesN[3] / numLeaves);
+ printf(" N=4 %3d%%\n", 100 * numLeavesN[4] / numLeaves);
+ printf(" N>4 %3d%%\n", 100 * numLeavesN[5] / numLeaves);
+ printf(" * BVH2 nodes: %d (%3d%%)\n", numBVH2, 100 * numBVH2 / (numNodes + numLeaves - 2 * numBVH2));
+}
diff --git a/src/shared/vmap/BIH.h b/src/shared/vmap/BIH.h
new file mode 100644
index 00000000000..15ae90c23eb
--- /dev/null
+++ b/src/shared/vmap/BIH.h
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#ifndef _BIH_H
+#define _BIH_H
+
+#include <G3D/Vector3.h>
+#include <G3D/Ray.h>
+#include <G3D/AABox.h>
+
+#include <Platform/Define.h>
+
+#include <stdexcept>
+#include <vector>
+#include <algorithm>
+#include <limits>
+#include <cmath>
+
+#define MAX_STACK_SIZE 64
+
+#ifdef _MSC_VER
+ #define isnan(x) _isnan(x)
+#endif
+
+using G3D::Vector3;
+using G3D::AABox;
+using G3D::Ray;
+
+static inline uint32 floatToRawIntBits(float f)
+{
+ union
+ {
+ uint32 ival;
+ float fval;
+ } temp;
+ temp.fval=f;
+ return temp.ival;
+}
+
+static inline float intBitsToFloat(uint32 i)
+{
+ union
+ {
+ uint32 ival;
+ float fval;
+ } temp;
+ temp.ival=i;
+ return temp.fval;
+}
+
+struct AABound
+{
+ Vector3 lo, hi;
+};
+
+/** Bounding Interval Hierarchy Class.
+ Building and Ray-Intersection functions based on BIH from
+ Sunflow, a Java Raytracer, released under MIT/X11 License
+ http://sunflow.sourceforge.net/
+ Copyright (c) 2003-2007 Christopher Kulla
+*/
+
+class BIH
+{
+ public:
+ BIH() {};
+ template< class T, class BoundsFunc >
+ void build(const std::vector<T> &primitives, BoundsFunc &getBounds, uint32 leafSize = 3, bool printStats=false)
+ {
+ if(primitives.size() == 0)
+ return;
+ buildData dat;
+ dat.maxPrims = leafSize;
+ dat.numPrims = primitives.size();
+ dat.indices = new uint32[dat.numPrims];
+ dat.primBound = new AABox[dat.numPrims];
+ getBounds(primitives[0], bounds);
+ for (uint32 i=0; i<dat.numPrims; ++i)
+ {
+ dat.indices[i] = i;
+ AABox tb;
+ getBounds(primitives[i], dat.primBound[i]);
+ bounds.merge(dat.primBound[i]);
+ }
+ std::vector<uint32> tempTree;
+ BuildStats stats;
+ buildHierarchy(tempTree, dat, stats);
+ if (printStats)
+ stats.printStats();
+
+ objects.resize(dat.numPrims);
+ for (uint32 i=0; i<dat.numPrims; ++i)
+ objects[i] = dat.indices[i];
+ //nObjects = dat.numPrims;
+ tree = tempTree;
+ delete[] dat.primBound;
+ delete[] dat.indices;
+ }
+ uint32 primCount() { return objects.size(); }
+
+ template<typename RayCallback>
+ void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
+ {
+ float intervalMin = 0.f;
+ float intervalMax = maxDist;
+ Vector3 org = r.origin();
+ Vector3 dir = r.direction();
+ Vector3 invDir;
+ float t1, t2;
+ for(int i=0; i<3; ++i)
+ {
+ invDir[i] = 1.f / dir[i];
+ t1 = (bounds.low()[i] - org[i]) * invDir[i];
+ t2 = (bounds.high()[i] - org[i]) * invDir[i];
+ if (invDir[i] > 0) {
+ if (t1 > intervalMin)
+ intervalMin = t1;
+ if (t2 < intervalMax)
+ intervalMax = t2;
+ } else {
+ if (t2 > intervalMin)
+ intervalMin = t2;
+ if (t1 < intervalMax)
+ intervalMax = t1;
+ }
+ if (intervalMin > intervalMax)
+ return;
+ }
+
+ uint32 offsetFront[3];
+ uint32 offsetBack[3];
+ uint32 offsetFront3[3];
+ uint32 offsetBack3[3];
+ // compute custom offsets from direction sign bit
+
+ for(int i=0; i<3; ++i)
+ {
+ offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
+ offsetBack[i] = offsetFront[i] ^ 1;
+ offsetFront3[i] = offsetFront[i] * 3;
+ offsetBack3[i] = offsetBack[i] * 3;
+
+ // avoid always adding 1 during the inner loop
+ ++offsetFront[i];
+ ++offsetBack[i];
+ }
+
+ StackNode stack[MAX_STACK_SIZE];
+ int stackPos = 0;
+ int node = 0;
+
+ while (true) {
+ while (true)
+ {
+ uint32 tn = tree[node];
+ uint32 axis = (tn & (3 << 30)) >> 30;
+ bool BVH2 = tn & (1 << 29);
+ int offset = tn & ~(7 << 29);
+ if (!BVH2)
+ {
+ if (axis < 3)
+ {
+ // "normal" interior node
+ float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
+ float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
+ // ray passes between clip zones
+ if (tf < intervalMin && tb > intervalMax)
+ break;
+ int back = offset + offsetBack3[axis];
+ node = back;
+ // ray passes through far node only
+ if (tf < intervalMin) {
+ intervalMin = (tb >= intervalMin) ? tb : intervalMin;
+ continue;
+ }
+ node = offset + offsetFront3[axis]; // front
+ // ray passes through near node only
+ if (tb > intervalMax) {
+ intervalMax = (tf <= intervalMax) ? tf : intervalMax;
+ continue;
+ }
+ // ray passes through both nodes
+ // push back node
+ stack[stackPos].node = back;
+ stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
+ stack[stackPos].tfar = intervalMax;
+ stackPos++;
+ // update ray interval for front node
+ intervalMax = (tf <= intervalMax) ? tf : intervalMax;
+ continue;
+ }
+ else
+ {
+ // leaf - test some objects
+ int n = tree[node + 1];
+ while (n > 0) {
+ bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirst);
+ if(stopAtFirst && hit) return;
+ --n;
+ ++offset;
+ }
+ break;
+ }
+ }
+ else
+ {
+ if (axis>2)
+ return; // should not happen
+ float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
+ float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
+ node = offset;
+ intervalMin = (tf >= intervalMin) ? tf : intervalMin;
+ intervalMax = (tb <= intervalMax) ? tb : intervalMax;
+ if (intervalMin > intervalMax)
+ break;
+ continue;
+ }
+ } // traversal loop
+ do
+ {
+ // stack is empty?
+ if (stackPos == 0)
+ return;
+ // move back up the stack
+ stackPos--;
+ intervalMin = stack[stackPos].tnear;
+ if (maxDist < intervalMin)
+ continue;
+ node = stack[stackPos].node;
+ intervalMax = stack[stackPos].tfar;
+ break;
+ } while (true);
+ }
+ }
+
+ template<typename IsectCallback>
+ void intersectPoint(const Vector3 &p, IsectCallback& intersectCallback) const
+ {
+ if (!bounds.contains(p))
+ return;
+
+ StackNode stack[MAX_STACK_SIZE];
+ int stackPos = 0;
+ int node = 0;
+
+ while (true) {
+ while (true)
+ {
+ uint32 tn = tree[node];
+ uint32 axis = (tn & (3 << 30)) >> 30;
+ bool BVH2 = tn & (1 << 29);
+ int offset = tn & ~(7 << 29);
+ if (!BVH2)
+ {
+ if (axis < 3)
+ {
+ // "normal" interior node
+ float tl = intBitsToFloat(tree[node + 1]);
+ float tr = intBitsToFloat(tree[node + 2]);
+ // point is between clip zones
+ if (tl < p[axis] && tr > p[axis])
+ break;
+ int right = offset + 3;
+ node = right;
+ // point is in right node only
+ if (tl < p[axis]) {
+ continue;
+ }
+ node = offset; // left
+ // point is in left node only
+ if (tr > p[axis]) {
+ continue;
+ }
+ // point is in both nodes
+ // push back right node
+ stack[stackPos].node = right;
+ stackPos++;
+ continue;
+ }
+ else
+ {
+ // leaf - test some objects
+ int n = tree[node + 1];
+ while (n > 0) {
+ intersectCallback(p, objects[offset]); // !!!
+ --n;
+ ++offset;
+ }
+ break;
+ }
+ }
+ else // BVH2 node (empty space cut off left and right)
+ {
+ if (axis>2)
+ return; // should not happen
+ float tl = intBitsToFloat(tree[node + 1]);
+ float tr = intBitsToFloat(tree[node + 2]);
+ node = offset;
+ if (tl > p[axis] || tr < p[axis])
+ break;
+ continue;
+ }
+ } // traversal loop
+
+ // stack is empty?
+ if (stackPos == 0)
+ return;
+ // move back up the stack
+ stackPos--;
+ node = stack[stackPos].node;
+ }
+ }
+
+ bool writeToFile(FILE *wf) const;
+ bool readFromFile(FILE *rf);
+
+ protected:
+ std::vector<uint32> tree;
+ std::vector<uint32> objects;
+ AABox bounds;
+
+ struct buildData
+ {
+ uint32 *indices;
+ AABox *primBound;
+ uint32 numPrims;
+ int maxPrims;
+ };
+ struct StackNode
+ {
+ uint32 node;
+ float tnear;
+ float tfar;
+ };
+
+ class BuildStats
+ {
+ private:
+ int numNodes;
+ int numLeaves;
+ int sumObjects;
+ int minObjects;
+ int maxObjects;
+ int sumDepth;
+ int minDepth;
+ int maxDepth;
+ int numLeavesN[6];
+ int numBVH2;
+
+ public:
+ BuildStats():
+ numNodes(0), numLeaves(0), sumObjects(0), minObjects(0x0FFFFFFF),
+ maxObjects(0xFFFFFFFF), sumDepth(0), minDepth(0x0FFFFFFF),
+ maxDepth(0xFFFFFFFF), numBVH2(0)
+ {
+ for(int i=0; i<6; ++i) numLeavesN[i] = 0;
+ }
+
+ void updateInner() { numNodes++; }
+ void updateBVH2() { numBVH2++; }
+ void updateLeaf(int depth, int n);
+ void printStats();
+ };
+
+ void buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats);
+
+ void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) {
+ // write leaf node
+ tempTree[nodeIndex + 0] = (3 << 30) | left;
+ tempTree[nodeIndex + 1] = right - left + 1;
+ }
+
+ void subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats);
+};
+
+#endif // _BIH_H
diff --git a/src/shared/vmap/BaseModel.cpp b/src/shared/vmap/BaseModel.cpp
deleted file mode 100644
index 14c42c8039f..00000000000
--- a/src/shared/vmap/BaseModel.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include "BaseModel.h"
-#include "VMapTools.h"
-
-using namespace G3D;
-
-namespace VMAP
-{
- //==========================================================
-
- void BaseModel::getMember(Array<TriangleBox>& pMembers)
- {
- for (unsigned int i=0; i<iNTriangles; i++)
- {
- pMembers.append(iTriangles[i]);
- }
- }
-
- //==========================================================
- BaseModel::BaseModel(unsigned int pNNodes, unsigned int pNTriangles)
- {
- init(pNNodes, pNTriangles);
- };
-
- //==========================================================
-
- void BaseModel::init(unsigned int pNNodes, unsigned int pNTriangles)
- {
- iNNodes = pNNodes;
- iNTriangles = pNTriangles;
- iTriangles = 0;
- iTreeNodes = 0;
- if(iNNodes >0) iTreeNodes = new TreeNode[iNNodes];
- if(iNTriangles >0) iTriangles = new TriangleBox[iNTriangles];
- }
-
- //==========================================================
-
- void BaseModel::free()
- {
- if(getTriangles() != 0) delete [] getTriangles(); setNTriangles(0);
- if(getTreeNodes() != 0) delete [] getTreeNodes(); setNNodes(0);
- }
-
- //==========================================================
-
- void BaseModel::intersect(const G3D::AABox& pBox, const G3D::Ray& pRay, float& pMaxDist, G3D::Vector3& pOutLocation, G3D::Vector3& /*pOutNormal*/) const
- {
- bool isInside = false;
-
- float d = MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
- pRay.origin, pRay.direction,
- pBox,
- pOutLocation, isInside);
- if (!isInside && ((d > 0) && (d < pMaxDist)))
- {
- pMaxDist = d;
- }
- }
-
- //==========================================================
-
- bool BaseModel::intersect(const G3D::AABox& pBox, const G3D::Ray& pRay, float& pMaxDist) const
- {
- // See if the ray will ever hit this node or its children
- Vector3 location;
- bool alreadyInsideBounds = false;
- bool rayWillHitBounds =
- MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
- pRay.origin, pRay.direction, pBox, location, alreadyInsideBounds);
-
- bool canHitThisNode = (alreadyInsideBounds ||
- (rayWillHitBounds && ((location - pRay.origin).squaredLength() < (pMaxDist * pMaxDist))));
-
- return canHitThisNode;
- }
-
-} // VMAP
-
diff --git a/src/shared/vmap/BaseModel.h b/src/shared/vmap/BaseModel.h
deleted file mode 100644
index 806bb2c365b..00000000000
--- a/src/shared/vmap/BaseModel.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _BASEMODEL_H_
-#define _BASEMODEL_H_
-
-#include <G3D/AABox.h>
-#include <G3D/Vector3.h>
-
-#include "ShortVector.h"
-#include "ShortBox.h"
-#include "TreeNode.h"
-
-/**
-A model is based on triangles. To be able to check intersection we need a BSP-Tree.
-This Class holds the array of triangles as well as the management information for the BSP-Tree.
-Both are stored in static array and index information is used instead of pointers.
-Therefore we can load the whole object as a binary block.
-
-The vectors are relative to a base position.
-*/
-
-namespace VMAP
-{
-
- class BaseModel
- {
- protected:
- TriangleBox *iTriangles;
- TreeNode *iTreeNodes;
- unsigned int iNTriangles;
- unsigned int iNNodes;
- G3D::Vector3 iBasePosition;
- public:
- BaseModel() { iNTriangles = 0; iNNodes = 0; iTriangles = 0; iTreeNodes = 0;};
- BaseModel(unsigned int pNNodes , TreeNode* pTreeNode, unsigned int pNTriangles, TriangleBox* pTriangleBox)
- {
- iNNodes = pNNodes; iNTriangles = pNTriangles; iTriangles = pTriangleBox; iTreeNodes = pTreeNode;
- };
- BaseModel(unsigned int pNNodes, unsigned int pNTriangles);
-
- // destructor does nothing ! The subclass controles the array memory and knows when to free it
- ~BaseModel() {}
-
- void free();
- void init(unsigned int pNNodes, unsigned int pNTriangles);
-
- void getMember(G3D::Array<TriangleBox>& pMembers);
-
- inline const TriangleBox& getTriangle(int pPos) const { return(iTriangles[pPos]); }
- inline TriangleBox& getTriangle(int pPos) { return(iTriangles[pPos]); }
-
- inline void setTriangle(const TriangleBox& pTriangleBox, int pPos) { iTriangles[pPos] = pTriangleBox; }
-
- inline const TreeNode& getTreeNode(int pPos) const { return(getTreeNodes()[pPos]); }
- inline TreeNode& getTreeNode(int pPos) { return(getTreeNodes()[pPos]); }
-
- inline void setTreeNode(const TreeNode& pTreeNode, int pPos) { getTreeNodes()[pPos] = pTreeNode; }
-
- inline void setBasePosition(const G3D::Vector3& pBasePosition) { iBasePosition = pBasePosition; }
-
- inline const G3D::Vector3& getBasePosition() const { return(iBasePosition); }
-
- inline unsigned int getNNodes() const { return(iNNodes); }
- inline unsigned int getNTriangles() const { return(iNTriangles); }
-
- inline void setNNodes(unsigned int pNNodes) { iNNodes = pNNodes; }
- inline void setNTriangles(unsigned int pNTriangles) { iNTriangles = pNTriangles; }
-
- inline void setTriangleArray(TriangleBox *pGlobalTriangleArray ) { iTriangles = pGlobalTriangleArray ; }
- inline void setTreeNodeArray(TreeNode *pGlobalTreeNodeArray ) { iTreeNodes = pGlobalTreeNodeArray ; }
-
- inline TriangleBox* getTriangles() const { return(iTriangles); }
-
- inline TreeNode* getTreeNodes() const{ return(iTreeNodes); }
-
- inline size_t getMemUsage() { return(iNTriangles * sizeof(TriangleBox) + iNNodes * sizeof(TreeNode) + sizeof(BaseModel)); }
-
- void intersect(const G3D::AABox& pBox, const G3D::Ray& pRay, float& pMaxDist, G3D::Vector3& pOutLocation, G3D::Vector3& pOutNormal) const;
- bool intersect(const G3D::AABox& pBox, const G3D::Ray& pRay, float& pMaxDist) const;
- };
-
-}
-#endif /*BASEMODEL_H_*/
-
diff --git a/src/shared/vmap/CMakeLists.txt b/src/shared/vmap/CMakeLists.txt
index 76ba24e55d1..898e0d6c5f0 100644
--- a/src/shared/vmap/CMakeLists.txt
+++ b/src/shared/vmap/CMakeLists.txt
@@ -2,38 +2,28 @@
########### next target ###############
SET(vmaps_STAT_SRCS
- AABSPTree.h
- BaseModel.cpp
- BaseModel.h
- CoordModelMapping.cpp
- CoordModelMapping.h
- DebugCmdLogger.cpp
- DebugCmdLogger.h
+ BIH.h
+ BIH.cpp
IVMapManager.h
- ManagedModelContainer.cpp
- ManagedModelContainer.h
- ModelContainer.cpp
- ModelContainer.h
- NodeValueAccess.h
- ShortBox.h
- ShortVector.h
- SubModel.cpp
- SubModel.h
+ MapTree.cpp
+ MapTree.h
+ ModelInstance.cpp
+ ModelInstance.h
TileAssembler.cpp
TileAssembler.h
- TreeNode.cpp
- TreeNode.h
VMapDefinitions.h
VMapFactory.cpp
VMapFactory.h
- VMapManager.cpp
- VMapManager.h
+ VMapManager2.cpp
+ VMapManager2.h
VMapTools.h
+ WorldModel.cpp
+ WorldModel.h
)
include_directories(
+ ${CMAKE_SOURCE_DIR}/src/framework
${CMAKE_SOURCE_DIR}/dep/include/g3dlite
)
add_library(vmaps STATIC ${vmaps_STAT_SRCS})
-
diff --git a/src/shared/vmap/CoordModelMapping.cpp b/src/shared/vmap/CoordModelMapping.cpp
deleted file mode 100644
index 20fe733c48e..00000000000
--- a/src/shared/vmap/CoordModelMapping.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include "CoordModelMapping.h"
-
-#include <string.h>
-#include <stdio.h>
-
-using namespace G3D;
-
-namespace VMAP
-{
-
- //============================================================
- //============================================================
-
- void CMappingEntry::addFilename(char *pName)
- {
- std::string name = std::string(pName);
- if(!iFilenames.contains(name))
- iFilenames.append(std::string(pName));
- }
-
- //============================================================
-
- const std::string CMappingEntry::getKeyString() const
- {
- return(CMappingEntry::getKeyString(iMapId,xPos, yPos));
- }
-
- const std::string CMappingEntry::getKeyString( unsigned int pMapId, int pXPos, int pYPos )
- {
- char b[100];
- sprintf(b,"%03u_%d_%d", pMapId, pXPos, pYPos);
- return(std::string(b));
- }
-
- //============================================================
- //============================================================
- //============================================================
-
- CoordModelMapping::~CoordModelMapping()
- {
- Array<std::string> keys = iMapObjectFiles.getKeys();
- for (int k = 0; k < keys.length(); k++)
- {
- CMappingEntry *value = getCMappingEntry(keys[k]);
- if(value != 0)
- {
- iMapObjectFiles.remove(keys[k]);
- delete value;
- }
- }
- }
-
- //============================================================
-
- int findPosChar(const char *namebuffer, char pSearch, int pCount)
- {
- int result = -1;
- int pos=0;
- while(namebuffer[pos] != 0)
- {
- if(namebuffer[pos] == pSearch)
- {
- --pCount;
- }
- if(pCount == 0)
- {
- result = pos;
- break;
- }
- ++pos;
- }
- return result;
- }
- //============================================================
- bool CoordModelMapping::readCoordinateMapping(const std::string& pDirectoryFileName)
- {
- FILE *f = fopen(pDirectoryFileName.c_str(), "rb");
- if(!f)
- {
- printf("ERROR: Can't open file: %s\n",pDirectoryFileName.c_str());
- return false;
- }
-
- char buffer[500+1];
-
- CMappingEntry* cMappingEntry;
- while(fgets(buffer, 500, f))
- {
- //char namebuffer[500];
- char positionbuffer[500];
- int xpos, ypos, noVec;
- float scale;
- xpos = ypos = noVec = 0;
-
- //sscanf(buffer, "%d %d %s %s %f %d", &xpos, &ypos, namebuffer,positionbuffer, &scale, &noVec);
-
- // this is ugly, but the format has no read delimiter and a space could be in the first part of the name
- int nameStart = findPosChar(buffer, ' ', 2);// find the 2. space
- if(nameStart > -1 && (iFilterMethod == NULL || (*iFilterMethod)(buffer)))
- {
- ++nameStart;
- // find the 1. / (now a space only can be found at the end of the name)
- int nameEnd = nameStart + findPosChar(&buffer[nameStart], '/', 1);
- // find the 1. space (after the name)
- nameEnd += findPosChar(&buffer[nameEnd], ' ', 1);
- buffer[nameEnd] = 0; // terminate the name
-
- sscanf(buffer, "%d %d", &xpos, &ypos);
- sscanf(&buffer[nameEnd+1], "%s %f %d", positionbuffer, &scale, &noVec);
- unsigned int mapId = getMapIdFromFilename(std::string(&buffer[nameStart]));
- if(!iMapIds.contains(mapId))
- {
- iMapIds.append(mapId);
- printf("Coords for map %u...\n",mapId);
- }
- if(!isWorldAreaMap(mapId))
- {
- xpos = 0; // store all files under the groupKey
- ypos = 0;
- }
-
- std::string key = CMappingEntry::getKeyString(mapId, xpos, ypos);
- cMappingEntry = getCMappingEntry(key);
- if(cMappingEntry == 0)
- {
- cMappingEntry = new CMappingEntry(mapId, xpos, ypos);
- addCMappingEntry(cMappingEntry);
- }
- char namebuffer2[500];
- sprintf(namebuffer2, "%d %s#%s_%f", noVec, &buffer[nameStart], positionbuffer, scale);
- cMappingEntry->addFilename(namebuffer2);
- //break;
- }
- }
- fclose(f);
- return true;
- }
-
- //============================================================
-
- const NameCollection CoordModelMapping::getFilenamesForCoordinate(unsigned int pMapId, int xPos, int yPos)
- {
- NameCollection result;
- Array<std::string> rawNames;
-
- CMappingEntry *entry = getCMappingEntry(CMappingEntry::getKeyString(pMapId, xPos, yPos));
- if(entry != 0)
- {
- rawNames = entry->getFilenames();
-
- int pos = 0;
- while(pos < rawNames.size())
- {
- char namebuffer[500];
- int noVerc;
- int startName = findPosChar(rawNames[pos].c_str(), ' ', 1) + 1;
- int endName = (int) rawNames[pos].length();
- sscanf(rawNames[pos].c_str(), "%d", &noVerc);
- memcpy(namebuffer, &rawNames[pos].c_str()[startName], endName-startName);
- namebuffer[endName-startName] = 0;
- sscanf(rawNames[pos].c_str(), "%d", &noVerc);
- std::string modelPosFileName = std::string(namebuffer);
- if(noVerc > MIN_VERTICES_FOR_OWN_CONTAINER_FILE)
- {
- result.appendToSingle(modelPosFileName);
- }
- else
- {
- result.appendToMain(modelPosFileName);
- }
- ++pos;
- }
- }
- return result;
- }
-
- //=================================================================
-
-}
-
diff --git a/src/shared/vmap/CoordModelMapping.h b/src/shared/vmap/CoordModelMapping.h
deleted file mode 100644
index 641f4d17f37..00000000000
--- a/src/shared/vmap/CoordModelMapping.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _COORDMODELMAPPING_H_
-#define _COORDMODELMAPPING_H_
-
-#include <cstdio>
-#include <G3D/Table.h>
-#include <G3D/Array.h>
-
-/**
-This Class is a helper Class to convert the raw vector data into BSP-Trees.
-We read the directory file of the raw data output and build logical groups.
-Models with a lot of vectors are not merged into a resulting model, but separated into an additional file.
-*/
-
-namespace VMAP
-{
-
- #define MIN_VERTICES_FOR_OWN_CONTAINER_FILE 65000
-
- // if we are in an instance
- #define MIN_INST_VERTICES_FOR_OWN_CONTAINER_FILE 40000
-
- //=====================================================
- class NameCollection
- {
- public:
- G3D::Array<std::string> iMainFiles;
- G3D::Array<std::string> iSingeFiles;
-
- void appendToMain(const std::string& pStr) { iMainFiles.append(pStr); }
- void appendToSingle(const std::string& pStr) { iSingeFiles.append(pStr); }
-
- size_t size() { return (iMainFiles.size() + iSingeFiles.size()); }
- };
-
- //=====================================================
-
- class CMappingEntry
- {
- private:
- int xPos;
- int yPos;
- unsigned int iMapId;
- G3D::Array<std::string> iFilenames;
-
- public:
- CMappingEntry() { };
- CMappingEntry(unsigned int pMapId, const int pXPos, const int pYPos)
- {
- iMapId = pMapId;
- xPos = pXPos; yPos = pYPos;
- };
- ~CMappingEntry() {};
-
- void addFilename(char *pName);
- const std::string getKeyString() const;
- inline const G3D::Array<std::string>& getFilenames() const { return(iFilenames); }
-
- static const std::string getKeyString(unsigned int pMapId, int pXPos, int pYPos);
-
- };
-
- //=====================================================
-
- class CoordModelMapping
- {
- private:
- G3D::Table<std::string, CMappingEntry *> iMapObjectFiles;
- G3D::Table<std::string, std::string> iProcesseSingleFiles;
- G3D::Array<unsigned int> iMapIds;
- G3D::Array<unsigned int> iWorldAreaGroups;
- bool (*iFilterMethod)(char *pName);
-
- inline void addCMappingEntry(CMappingEntry* pCMappingEntry)
- {
- iMapObjectFiles.set(pCMappingEntry->getKeyString(), pCMappingEntry);
- }
-
- inline CMappingEntry* getCMappingEntry(const std::string& pKey)
- {
- if(iMapObjectFiles.containsKey(pKey))
- return(iMapObjectFiles.get(pKey));
- else
- return 0;
- }
-
- public:
- CoordModelMapping() { iFilterMethod = NULL; }
- virtual ~CoordModelMapping();
-
- bool readCoordinateMapping(const std::string& pDirectoryFileName);
-
- const NameCollection getFilenamesForCoordinate(unsigned int pMapId, int xPos, int yPos);
-
- static unsigned int getMapIdFromFilename(const std::string& pName)
- {
- size_t spos;
-
- spos = pName.find_last_of('/');
- std::string basename = pName.substr(0, spos);
- spos = basename.find_last_of('/');
- std::string groupname = basename.substr(spos+1, basename.length());
- unsigned int mapId = atoi(groupname.c_str());
- return(mapId);
- }
-
- const G3D::Array<unsigned int>& getMaps() const { return iMapIds; }
- bool isAlreadyProcessedSingleFile(const std::string& pName) const { return iProcesseSingleFiles.containsKey(pName); }
- void addAlreadyProcessedSingleFile(const std::string& pName) { iProcesseSingleFiles.set(pName,pName); }
-
- inline void addWorldAreaMap(unsigned int pMapId)
- {
- if(!iWorldAreaGroups.contains(pMapId))
- {
- iWorldAreaGroups.append(pMapId);
- }
- }
- inline bool isWorldAreaMap(unsigned int pMapId) { return(iWorldAreaGroups.contains(pMapId)); }
- void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
-
- };
-}
-#endif /*_COORDMODELMAPPING_H_*/
-
diff --git a/src/shared/vmap/DebugCmdLogger.cpp b/src/shared/vmap/DebugCmdLogger.cpp
deleted file mode 100644
index a0a40612f16..00000000000
--- a/src/shared/vmap/DebugCmdLogger.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include <cstdio>
-
-#include "DebugCmdLogger.h"
-#include <stdio.h>
-
-using namespace G3D;
-
-namespace VMAP
-{
-
- bool CommandFileRW::appendCmd(const Command&
-#ifdef _DEBUG
- pCommand
-#endif
- )
- {
- #ifdef _DEBUG
- bool result = false;
- if(iWritingEnabled || pCommand.isCoreCmd())
- {
- FILE* f = fopen(iFileName.c_str(), "ab");
- if(f)
- {
- result = true;
- if(fwrite(&pCommand, sizeof(Command), 1, f) != 1) { result = false; }
- fclose(f);
- }
- }
- else
- {
- result = true;
- }
- return result;
- #else
- return true;
- #endif
- }
-
- //=========================================================
-
- bool CommandFileRW::appendCmds(const Array<Command>&
-#ifdef _DEBUG
- pCmdArray
-#endif
- )
- {
- #ifdef _DEBUG
- bool result = false;
- if(iWritingEnabled)
- {
- FILE* f;
- if(resetfile)
- f = fopen(iFileName.c_str(), "wb");
- else
- f = fopen(iFileName.c_str(), "ab");
- resetfile = false;
-
- if(f)
- {
- result = true;
- for (int i=0; i<pCmdArray.size(); ++i)
- {
- if(fwrite(&pCmdArray[i], sizeof(Command), 1, f) != 1) { result = false; break; }
- }
- fclose(f);
- }
- }
- else
- {
- result = true;
- }
- return result;
- #else
- return true;
- #endif
- }
-
- //=========================================================
-
- bool CommandFileRW::getNewCommands(Array<Command>& pCmdArray)
- {
- bool result = false;
- FILE* f = fopen(iFileName.c_str(), "rb");
- if(f)
- {
- Command cmd;
- if(fseek(f, iLastPos, SEEK_SET) == 0) { result = true; }
- while(result)
- {
- if(fread(&cmd, sizeof(Command), 1, f) != 1)
- {
- result = false;
- }
- iLastPos = ftell(f);
- if(cmd.getType() == STOP)
- {
- break;
- }
- pCmdArray.append(cmd);
- }
- fclose(f);
- }
- if(result)
- {
- iCommandArray.append(pCmdArray);
- }
- return(result);
- }
- //========================================================
-}
-
diff --git a/src/shared/vmap/DebugCmdLogger.h b/src/shared/vmap/DebugCmdLogger.h
deleted file mode 100644
index 775e529c55e..00000000000
--- a/src/shared/vmap/DebugCmdLogger.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _DEBUGCMDLOGGER_H
-#define _DEBUGCMDLOGGER_H
-
-#include <G3D/Vector3.h>
-#include <G3D/Array.h>
-
-/**
-Class is used for debugging. We log activities into a file.
-With an external Class we read that log and display the activity in a graphical view.
-*/
-
-namespace VMAP
-{
-
- //==========================================
- enum C_TYPES
- {
- STOP,
- START,
- LOAD_TILE,
- UNLOAD_TILE,
- SET_POS,
- TEST_VIS,
- LOAD_INSTANCE,
- UNLOAD_INSTANCE,
- TEST_HEIGHT,
- TEST_OBJECT_HIT,
- };
-
- class Command
- {
- int iType;
- float floats[9];
- int ints[4];
- char buffer[100];
- public:
-
- Command() { iType = STOP; }
-
- inline int getType() { return iType; }
- inline G3D::Vector3 getVector(int pos) { return(G3D::Vector3(floats[pos*3+0], floats[pos*3+1], floats[pos*3+2])); }
- inline int getInt(int pos) { return(ints[pos]); }
- inline char* getBuffer() { return(buffer); }
-
- void fillStopCmd() { iType = STOP; }
- void fillStartCmd() { iType = START; }
- void fillLoadTileCmd(int x, int y, G3D::uint32 pMapId) { iType = LOAD_TILE; ints[0] = x; ints[1] = y; ints[2] = pMapId; }
- //void fillLoadTileCmd(int x,int y) { iType = LOAD_TILE; ints[0] = x; ints[1] = y; }
- void fillUnloadTileCmd(G3D::uint32 pMapId) { iType = UNLOAD_INSTANCE; ints[0] = pMapId; }
- void fillUnloadTileCmd(unsigned int pMapId, int x,int y) { iType = UNLOAD_TILE; ints[0] = x; ints[1] = y; ints[0]=pMapId; }
- void fillSetPosCmd(G3D::Vector3 pPos) { iType = SET_POS; floats[0] = pPos.x; floats[1]=pPos.y; floats[2]=pPos.z; }
- void fillTestVisCmd(int pMapId, G3D::Vector3 pPos1, G3D::Vector3 pPos2, bool result)
- {
- iType = TEST_VIS; floats[0] = pPos1.x; floats[1]=pPos1.y; floats[2]=pPos1.z;
- floats[3] = pPos2.x; floats[4]=pPos2.y; floats[5]=pPos2.z;
- ints[0] = result; ints[1] = pMapId;
- }
- void fillTestHeightCmd(int pMapId, G3D::Vector3 pPos, float result)
- {
- iType = TEST_HEIGHT; floats[0] = pPos.x; floats[1]=pPos.y; floats[2]=pPos.z;
- floats[3] = result; ints[0] = pMapId;
- }
- void fillTestObjectHitCmd(int pMapId, G3D::Vector3 pPos1, G3D::Vector3 pPos2, G3D::Vector3 pResultPos, bool result)
- {
- iType = TEST_OBJECT_HIT; floats[0] = pPos1.x; floats[1]=pPos1.y; floats[2]=pPos1.z;
- floats[3] = pPos2.x; floats[4]=pPos2.y; floats[5]=pPos2.z;
- floats[6] = pResultPos.x; floats[7]=pResultPos.y; floats[8]=pResultPos.z;
- ints[0] = result; ints[1] = pMapId;
- }
-
- bool isCoreCmd() const { return(iType != TEST_VIS); }
- };
-
- //==========================================
-
- class CommandFileRW
- {
- private:
- std::string iFileName;
- long iLastPos;
- G3D::Array<G3D::Array<Command> > iCommandArray;
- bool resetfile;
- bool iWritingEnabled;
- public:
- CommandFileRW() { iLastPos=0; iWritingEnabled = true; resetfile = true;}
- CommandFileRW(const std::string& pFileName) { iLastPos = 0; iFileName = pFileName; iWritingEnabled = true; resetfile = true; }
- void setResetFile() { resetfile = true; }
- void enableWriting(bool pValue) { iWritingEnabled = pValue; }
- void setFileName(const std::string& pName) { iFileName = pName; }
- bool getNewCommands(G3D::Array<Command>& commandArray);
- const G3D::Array<G3D::Array<Command> >& getFullCommandArray() { return iCommandArray; }
-
- bool appendCmd(const Command& pCommand);
- bool appendCmds(const G3D::Array<Command>& pCmdArray);
- };
-
-}
-#endif
-
diff --git a/src/shared/vmap/IVMapManager.h b/src/shared/vmap/IVMapManager.h
index 81911f74a7a..00629eb122c 100644
--- a/src/shared/vmap/IVMapManager.h
+++ b/src/shared/vmap/IVMapManager.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
@@ -10,19 +8,19 @@
*
* 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _IVMAPMANAGER_H
#define _IVMAPMANAGER_H
#include<string>
-#include "VMapDefinitions.h"
+#include <Platform/Define.h>
//===========================================================
@@ -63,7 +61,7 @@ namespace VMAP
virtual void unloadMap(unsigned int pMapId) = 0;
virtual bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) = 0;
- virtual float getHeight(unsigned int pMapId, float x, float y, float z, float ray_lenght = MAX_CAN_FALL_DISTANCE) = 0;
+ virtual float getHeight(unsigned int pMapId, float x, float y, float z) = 0;
/**
test if we hit an object. return true if we hit one. rx,ry,rz will hold the hit position or the dest position, if no intersection was found
return a position, that is pReduceDist closer to the origin
@@ -96,8 +94,13 @@ namespace VMAP
e.g.: "0,1,530"
*/
virtual void preventMapsFromBeingUsed(const char* pMapIdString) =0;
+ /**
+ Query world model area info.
+ \param z gets adjusted to the ground height for which this are info is valid
+ */
+ virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const=0;
+ virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0;
};
}
#endif
-
diff --git a/src/shared/vmap/ManagedModelContainer.cpp b/src/shared/vmap/ManagedModelContainer.cpp
deleted file mode 100644
index dce666fb288..00000000000
--- a/src/shared/vmap/ManagedModelContainer.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include "ManagedModelContainer.h"
-
-using namespace G3D;
-
-namespace VMAP
-{
-
- ManagedModelContainer::ManagedModelContainer(void) : ModelContainer()
- {
- refCount = 0;
- }
-
- ManagedModelContainer::~ManagedModelContainer(void)
- {
- }
-
-}
-
diff --git a/src/shared/vmap/ManagedModelContainer.h b/src/shared/vmap/ManagedModelContainer.h
deleted file mode 100644
index e1ad2664fe8..00000000000
--- a/src/shared/vmap/ManagedModelContainer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _MANAGEDMODELCONTAINER_H
-#define _MANAGEDMODELCONTAINER_H
-
-#include "ModelContainer.h"
-
-//=======================================================
-/**
-This is a ModelContainer with reference count information.
-*/
-
-namespace VMAP
-{
- //=======================================================
-
- class ManagedModelContainer :
- public ModelContainer
- {
- private:
- int refCount;
- public:
- ManagedModelContainer(void) ;
- ~ManagedModelContainer(void);
-
- void incRefCount() { ++refCount; }
- void decRefCount() { --refCount; if(refCount < 0) refCount = 0; }
- int getRefCount() { return refCount; }
- };
-
- //=======================================================
-}
-#endif
-
diff --git a/src/shared/vmap/MapTree.cpp b/src/shared/vmap/MapTree.cpp
new file mode 100644
index 00000000000..8c77ee109f3
--- /dev/null
+++ b/src/shared/vmap/MapTree.cpp
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#include "MapTree.h"
+#include "ModelInstance.h"
+#include "VMapManager2.h"
+#include "VMapDefinitions.h"
+
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+using G3D::Vector3;
+
+namespace VMAP
+{
+
+ class MapRayCallback
+ {
+ public:
+ MapRayCallback(ModelInstance *val): prims(val) {}
+ ModelInstance *prims;
+ bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true)
+ {
+ return prims[entry].intersectRay(ray, distance, pStopAtFirstHit);
+ //std::cout << "trying to intersect '" << entity->name << "'\n";
+ }
+ };
+
+ class AreaInfoCallback
+ {
+ public:
+ AreaInfoCallback(ModelInstance *val): prims(val) {}
+ void operator()(const Vector3& point, uint32 entry)
+ {
+#ifdef VMAP_DEBUG
+ std::cout << "trying to intersect '" << prims[entry].name << "'\n";
+#endif
+ prims[entry].intersectPoint(point, aInfo);
+ }
+
+ ModelInstance *prims;
+ AreaInfo aInfo;
+ };
+
+ class LocationInfoCallback
+ {
+ public:
+ LocationInfoCallback(ModelInstance *val, LocationInfo &info): prims(val), locInfo(info), result(false) {}
+ void operator()(const Vector3& point, uint32 entry)
+ {
+#ifdef VMAP_DEBUG
+ std::cout << "trying to intersect '" << prims[entry].name << "'\n";
+#endif
+ if (prims[entry].GetLocationInfo(point, locInfo))
+ result = true;
+ }
+
+ ModelInstance *prims;
+ LocationInfo &locInfo;
+ bool result;
+ };
+
+
+ //=========================================================
+
+ std::string StaticMapTree::getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY)
+ {
+ std::stringstream tilefilename;
+ tilefilename.fill('0');
+ tilefilename << std::setw(3) << mapID << "_";
+ //tilefilename << std::setw(2) << tileX << "_" << std::setw(2) << tileY << ".vmtile";
+ tilefilename << std::setw(2) << tileY << "_" << std::setw(2) << tileX << ".vmtile";
+ return tilefilename.str();
+ }
+
+ bool StaticMapTree::getAreaInfo(Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
+ {
+ AreaInfoCallback intersectionCallBack(iTreeValues);
+ iTree.intersectPoint(pos, intersectionCallBack);
+ if (intersectionCallBack.aInfo.result)
+ {
+ flags = intersectionCallBack.aInfo.flags;
+ adtId = intersectionCallBack.aInfo.adtId;
+ rootId = intersectionCallBack.aInfo.rootId;
+ groupId = intersectionCallBack.aInfo.groupId;
+ pos.z = intersectionCallBack.aInfo.ground_Z;
+ return true;
+ }
+ return false;
+ }
+
+ bool StaticMapTree::GetLocationInfo(const Vector3 &pos, LocationInfo &info) const
+ {
+ LocationInfoCallback intersectionCallBack(iTreeValues, info);
+ iTree.intersectPoint(pos, intersectionCallBack);
+ return intersectionCallBack.result;
+ }
+
+ StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath):
+ iMapID(mapID), /* iTree(0), */ iTreeValues(0), iBasePath(basePath)
+ {
+ if (iBasePath.length() > 0 && (iBasePath[iBasePath.length()-1] != '/' || iBasePath[iBasePath.length()-1] != '\\'))
+ {
+ iBasePath.append("/");
+ }
+ }
+
+ //=========================================================
+ //! Make sure to call unloadMap() to unregister acquired model references before destroying
+ StaticMapTree::~StaticMapTree()
+ {
+ delete[] iTreeValues;
+ }
+
+ //=========================================================
+ /**
+ return dist to hit or inf() if no hit
+ */
+
+ float StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const
+ {
+ float distance = pMaxDist;
+ MapRayCallback intersectionCallBack(iTreeValues);
+ iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit);
+ return distance;
+ }
+ //=========================================================
+
+ bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const
+ {
+ bool result = true;
+ float maxDist = (pos2 - pos1).magnitude();
+ // prevent NaN values which can cause BIH intersection to enter infinite loop
+ if (maxDist < 1e-10f)
+ return true;
+ // direction with length of 1
+ G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
+ float resultDist = getIntersectionTime(ray, maxDist, true);
+ if (resultDist < maxDist)
+ {
+ result = false;
+ }
+ return result;
+ }
+ //=========================================================
+ /**
+ When moving from pos1 to pos2 check if we hit an object. Return true and the position if we hit one
+ Return the hit pos or the original dest pos
+ */
+
+ bool StaticMapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const
+ {
+ bool result=false;
+ float maxDist = (pPos2 - pPos1).magnitude();
+ // prevent NaN values which can cause BIH intersection to enter infinite loop
+ if (maxDist < 1e-10f)
+ {
+ pResultHitPos = pPos2;
+ return false;
+ }
+ Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
+ G3D::Ray ray(pPos1, dir);
+ float dist = getIntersectionTime(ray, maxDist, false);
+ if (dist < maxDist)
+ {
+ pResultHitPos = pPos1 + dir * dist;
+ if (pModifyDist < 0)
+ {
+ if ((pResultHitPos - pPos1).magnitude() > -pModifyDist)
+ {
+ pResultHitPos = pResultHitPos + dir*pModifyDist;
+ }
+ else
+ {
+ pResultHitPos = pPos1;
+ }
+ }
+ else
+ {
+ pResultHitPos = pResultHitPos + dir*pModifyDist;
+ }
+ result = true;
+ }
+ else
+ {
+ pResultHitPos = pPos2;
+ result = false;
+ }
+ return result;
+ }
+
+ //=========================================================
+
+ float StaticMapTree::getHeight(const Vector3& pPos) const
+ {
+ float height = G3D::inf();
+ Vector3 dir = Vector3(0,0,-1);
+ G3D::Ray ray(pPos, dir); // direction with length of 1
+ float maxDist = VMapDefinitions::getMaxCanFallDistance();
+ float dist = getIntersectionTime(ray, maxDist, false);
+ if (dist < maxDist)
+ {
+ height = pPos.z - dist;
+ }
+ return(height);
+ }
+
+ //=========================================================
+
+ bool StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY)
+ {
+ std::string basePath = vmapPath;
+ if (basePath.length() > 0 && (basePath[basePath.length()-1] != '/' || basePath[basePath.length()-1] != '\\'))
+ basePath.append("/");
+ std::string fullname = basePath + VMapManager2::getMapFileName(mapID);
+ bool success = true;
+ FILE *rf = fopen(fullname.c_str(), "rb");
+ if (!rf)
+ return false;
+ // TODO: check magic number when implemented...
+ char tiled;
+ char chunk[8];
+ if (!readChunk(rf, chunk, VMAP_MAGIC, 8) || fread(&tiled, sizeof(char), 1, rf) != 1)
+ {
+ fclose(rf);
+ return false;
+ }
+ if (tiled)
+ {
+ std::string tilefile = basePath + getTileFileName(mapID, tileX, tileY);
+ FILE* tf = fopen(tilefile.c_str(), "rb");
+ if (!tf)
+ success = false;
+ else
+ fclose(tf);
+ }
+ fclose(rf);
+ return success;
+ }
+
+ //=========================================================
+
+ bool StaticMapTree::InitMap(const std::string &fname, VMapManager2 *vm)
+ {
+ std::cout << "Initializing StaticMapTree '" << fname << "'\n";
+ bool success = true;
+ std::string fullname = iBasePath + fname;
+ FILE *rf = fopen(fullname.c_str(), "rb");
+ if (!rf)
+ return false;
+ else
+ {
+ char chunk[8];
+ //general info
+ if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) success = false;
+ char tiled;
+ if (success && fread(&tiled, sizeof(char), 1, rf) != 1) success = false;
+ iIsTiled = bool(tiled);
+ // Nodes
+ if (success && !readChunk(rf, chunk, "NODE", 4)) success = false;
+ if (success) success = iTree.readFromFile(rf);
+ if (success)
+ {
+ iNTreeValues = iTree.primCount();
+ iTreeValues = new ModelInstance[iNTreeValues];
+ }
+
+ if (success && !readChunk(rf, chunk, "GOBJ", 4)) success = false;
+ // global model spawns
+ // only non-tiled maps have them, and if so exactly one (so far at least...)
+ ModelSpawn spawn;
+#ifdef VMAP_DEBUG
+ std::cout << "Map isTiled:" << bool(iIsTiled) << std::endl;
+#endif
+ if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
+ {
+ WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name);
+ std::cout << "StaticMapTree::InitMap(): loading " << spawn.name << std::endl;
+ if (model)
+ {
+ // assume that global model always is the first and only tree value (could be improved...)
+ iTreeValues[0] = ModelInstance(spawn, model);
+ iLoadedSpawns[0] = 1;
+ }
+ else
+ {
+ success = false;
+ std::cout << "error: could not acquire WorldModel pointer!\n";
+ }
+ }
+
+ fclose(rf);
+ }
+ return success;
+ }
+
+ //=========================================================
+
+ void StaticMapTree::UnloadMap(VMapManager2 *vm)
+ {
+ for (loadedSpawnMap::iterator i = iLoadedSpawns.begin(); i != iLoadedSpawns.end(); ++i)
+ {
+ iTreeValues[i->first].setUnloaded();
+ for (uint32 refCount = 0; refCount < i->second; ++refCount)
+ vm->releaseModelInstance(iTreeValues[i->first].name);
+ }
+ iLoadedSpawns.clear();
+ iLoadedTiles.clear();
+ }
+
+ //=========================================================
+
+ bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm)
+ {
+ if (!iIsTiled)
+ {
+ // currently, core creates grids for all maps, whether it has terrain tiles or not
+ // so we need "fake" tile loads to know when we can unload map geometry
+ iLoadedTiles[packTileID(tileX, tileY)] = false;
+ return true;
+ }
+ if (!iTreeValues)
+ {
+ std::cout << "Tree has not been initialized!\n";
+ return false;
+ }
+ bool result = true;
+
+ std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
+ FILE* tf = fopen(tilefile.c_str(), "rb");
+ if (tf)
+ {
+ uint32 numSpawns;
+ if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
+ result = false;
+ for (uint32 i=0; i<numSpawns && result; ++i)
+ {
+ // read model spawns
+ ModelSpawn spawn;
+ result = ModelSpawn::readFromFile(tf, spawn);
+ if (result)
+ {
+ // acquire model instance
+ WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name);
+ if (!model) std::cout << "error: could not acquire WorldModel pointer!\n";
+
+ // update tree
+ uint32 referencedVal;
+
+ fread(&referencedVal, sizeof(uint32), 1, tf);
+ if (!iLoadedSpawns.count(referencedVal))
+ {
+#ifdef VMAP_DEBUG
+ if (referencedVal > iNTreeValues)
+ {
+ std::cout << "invalid tree element! (" << referencedVal << "/" << iNTreeValues << ")\n";
+ continue;
+ }
+#endif
+ iTreeValues[referencedVal] = ModelInstance(spawn, model);
+ iLoadedSpawns[referencedVal] = 1;
+ }
+ else
+ {
+ ++iLoadedSpawns[referencedVal];
+#ifdef VMAP_DEBUG
+ if (iTreeValues[referencedVal].ID != spawn.ID) std::cout << "error: trying to load wrong spawn in node!\n";
+ else if (iTreeValues[referencedVal].name != spawn.name) std::cout << "error: name collision on GUID="<< spawn.ID << "\n";
+#endif
+ }
+ }
+ }
+ iLoadedTiles[packTileID(tileX, tileY)] = true;
+ fclose(tf);
+ }
+ else
+ iLoadedTiles[packTileID(tileX, tileY)] = false;
+ return result;
+ }
+
+ //=========================================================
+
+ void StaticMapTree::UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm)
+ {
+ uint32 tileID = packTileID(tileX, tileY);
+ loadedTileMap::iterator tile = iLoadedTiles.find(tileID);
+ if (tile == iLoadedTiles.end())
+ {
+ std::cout << "WARNING: trying to unload non-loaded tile. Map:" << iMapID << " X:" << tileX << " Y:" << tileY << std::endl;
+ return;
+ }
+ if (tile->second) // file associated with tile
+ {
+ std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
+ FILE* tf = fopen(tilefile.c_str(), "rb");
+ if (tf)
+ {
+ bool result=true;
+ uint32 numSpawns;
+ if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
+ result = false;
+ for (uint32 i=0; i<numSpawns && result; ++i)
+ {
+ // read model spawns
+ ModelSpawn spawn;
+ result = ModelSpawn::readFromFile(tf, spawn);
+ if (result)
+ {
+ // release model instance
+ vm->releaseModelInstance(spawn.name);
+
+ // update tree
+ uint32 referencedNode;
+
+ fread(&referencedNode, sizeof(uint32), 1, tf);
+ if (!iLoadedSpawns.count(referencedNode))
+ {
+ std::cout << "error! trying to unload non-referenced model '" << spawn.name << "' (ID:" << spawn.ID << ")\n";
+ }
+ else if (--iLoadedSpawns[referencedNode] == 0)
+ {
+ //std::cout << "MapTree: removing '" << spawn.name << "' from tree\n";
+ iTreeValues[referencedNode].setUnloaded();
+ iLoadedSpawns.erase(referencedNode);
+ }
+ }
+ }
+ fclose(tf);
+ }
+ }
+ iLoadedTiles.erase(tile);
+ }
+
+}
diff --git a/src/shared/vmap/MapTree.h b/src/shared/vmap/MapTree.h
new file mode 100644
index 00000000000..7955cb92d68
--- /dev/null
+++ b/src/shared/vmap/MapTree.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#ifndef _MAPTREE_H
+#define _MAPTREE_H
+
+#include "Platform/Define.h"
+#include "Utilities/UnorderedMap.h"
+#include "BIH.h"
+
+namespace VMAP
+{
+ class ModelInstance;
+ class GroupModel;
+ class VMapManager2;
+
+ struct LocationInfo
+ {
+ LocationInfo(): hitInstance(0), hitModel(0), ground_Z(-G3D::inf()) {};
+ const ModelInstance *hitInstance;
+ const GroupModel *hitModel;
+ float ground_Z;
+ };
+
+ class StaticMapTree
+ {
+ typedef UNORDERED_MAP<uint32, bool> loadedTileMap;
+ typedef UNORDERED_MAP<uint32, uint32> loadedSpawnMap;
+ private:
+ uint32 iMapID;
+ bool iIsTiled;
+ BIH iTree;
+ ModelInstance *iTreeValues; // the tree entries
+ uint32 iNTreeValues;
+
+ // Store all the map tile idents that are loaded for that map
+ // some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
+ // empty tiles have no tile file, hence map with bool instead of just a set (consistency check)
+ loadedTileMap iLoadedTiles;
+ // stores <tree_index, reference_count> to invalidate tree values, unload map, and to be able to report errors
+ loadedSpawnMap iLoadedSpawns;
+ std::string iBasePath;
+
+ private:
+ float getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const;
+ //bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
+ public:
+ static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
+ static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX<<16 | tileY; }
+ static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY) { tileX = ID>>16; tileY = ID&0xFF; }
+ static bool CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY);
+
+ StaticMapTree(uint32 mapID, const std::string &basePath);
+ ~StaticMapTree();
+
+ bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2) const;
+ bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
+ float getHeight(const G3D::Vector3& pPos) const;
+ bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
+ bool GetLocationInfo(const Vector3 &pos, LocationInfo &info) const;
+
+ bool InitMap(const std::string &fname, VMapManager2 *vm);
+ void UnloadMap(VMapManager2 *vm);
+ bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm);
+ void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm);
+ bool isTiled() const { return iIsTiled; }
+ uint32 numLoadedTiles() const { return iLoadedTiles.size(); }
+ };
+
+ struct AreaInfo
+ {
+ AreaInfo(): result(false), ground_Z(-G3D::inf()) {};
+ bool result;
+ float ground_Z;
+ uint32 flags;
+ int32 adtId;
+ int32 rootId;
+ int32 groupId;
+ };
+} // VMAP
+
+#endif // _MAPTREE_H
diff --git a/src/shared/vmap/ModelContainer.cpp b/src/shared/vmap/ModelContainer.cpp
deleted file mode 100644
index 98c10789901..00000000000
--- a/src/shared/vmap/ModelContainer.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include <iostream>
-#include <fstream>
-
-#include <string.h>
-
-#include "ModelContainer.h"
-#include "VMapDefinitions.h"
-
-using namespace G3D;
-
-namespace VMAP
-{
- //==========================================================
- /**
- Functions to use ModelContainer with a AABSPTree
- */
- size_t hashCode(const ModelContainer& pMc)
- {
- return (pMc.getBasePosition() * pMc.getNTriangles()).hashCode();
- }
- //==========================================================
-
- ModelContainer::ModelContainer(unsigned int pNTriangles, unsigned int pNNodes, unsigned int pNSubModel) :
- BaseModel(pNNodes, pNTriangles)
- {
-
- iNSubModel = pNSubModel;
- iSubModel = 0;
- if(pNSubModel > 0) iSubModel = new SubModel[iNSubModel];
- }
-
- //==========================================================
-
- bool ModelContainer::operator==(const ModelContainer& pMc2) const
- {
- if (this->iNSubModel == 0 && pMc2.iNSubModel == 0 && this->iSubModel == 0 && pMc2.iSubModel == 0)
- return true;
- return this == &pMc2;
- }
-
- //==========================================================
-
- void ModelContainer::countSubModelsAndNodesAndTriangles(AABSPTree<SubModel *>::Node& pNode, int& nSubModels, int& nNodes, int& nTriangles)
- {
- // For this node we will need a TreeNode as well as for the internal nodes
- ++nNodes;
-
- nSubModels += pNode.valueArray.size();
- for (int i=0; i<pNode.valueArray.size(); i++)
- {
- G3D::_AABSPTree::Handle<SubModel*>* h= pNode.valueArray[i];
- SubModel *m = h->value;
- // add the internal nodes as well
- nNodes += m->getNNodes();
- nTriangles += m->getNTriangles();
- }
-
- if(pNode.child[0] != 0)
- {
- countSubModelsAndNodesAndTriangles(*pNode.child[0], nSubModels, nNodes, nTriangles);
- }
- if(pNode.child[1] != 0)
- {
- countSubModelsAndNodesAndTriangles(*pNode.child[1], nSubModels, nNodes, nTriangles);
- }
- }
- //==========================================================
-
- void ModelContainer::fillContainer(const AABSPTree<SubModel *>::Node& pNode, int &pSubModelPos, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi, Vector3& pFinalLo, Vector3& pFinalHi)
- {
- // TreeNode for the SubModel
- TreeNode treeNode = TreeNode(pNode.valueArray.size(), pSubModelPos);
- treeNode.setSplitAxis(pNode.splitAxis);
- treeNode.setSplitLocation(pNode.splitLocation);
- int currentTreeNodePos = pTreeNodePos++;
-
- Vector3 lo = Vector3(inf(),inf(),inf());
- Vector3 hi = Vector3(-inf(),-inf(),-inf());
-
- for (int i=0; i<pNode.valueArray.size(); i++)
- {
- G3D::_AABSPTree::Handle<SubModel*>* h= pNode.valueArray[i];
- SubModel *m = h->value;
-
- memcpy(&getTreeNodes()[pTreeNodePos], &m->getTreeNode(0), sizeof(TreeNode) * m->getNNodes());
- memcpy(&getTriangles()[pTrianglePos], &m->getTriangle(0), sizeof(TriangleBox) * m->getNTriangles());
-
- SubModel newModel = SubModel(m->getNTriangles(), getTriangles(), pTrianglePos, m->getNNodes(), getTreeNodes(), pTreeNodePos);
- newModel.setReletiveBounds(m->getReletiveBounds().getLo(), m->getReletiveBounds().getHi());
- newModel.setBasePosition(m->getBasePosition());
- iSubModel[pSubModelPos++] = newModel;
-
- pTreeNodePos += m->getNNodes();
- pTrianglePos += m->getNTriangles();
-
- AABox box = m->getAABoxBounds();
- lo = lo.min(box.low());
- hi = hi.max(box.high());
- pFinalLo = pFinalLo.min(lo);
- pFinalHi = pFinalHi.max(hi);
- }
- /*
- if(pNode.valueArray.size() == 0) {
- int xxx = 0; // just for the breakpoint
- }
- */
- // get absolute bounds
-
- if(pNode.child[0] != 0)
- {
- treeNode.setChildPos(0, pTreeNodePos);
- fillContainer(*pNode.child[0], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi);
- }
- if(pNode.child[1] != 0)
- {
- treeNode.setChildPos(1, pTreeNodePos);
- fillContainer(*pNode.child[1], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi);
- }
-
- pLo = pLo.min(lo);
- pHi = pHi.max(hi);
-
- treeNode.setBounds(lo,hi);
-
- setTreeNode(treeNode, currentTreeNodePos);
-
- }
-
- //==========================================================
- /**
- Create the structure out of a AABSPTree
- */
-
- ModelContainer::ModelContainer(AABSPTree<SubModel *> *pTree)
- {
-
- int nSubModels, nNodes, nTriangles;
- nSubModels = nNodes = nTriangles = 0;
- countSubModelsAndNodesAndTriangles(*pTree->root, nSubModels, nNodes, nTriangles);
-
- init(nNodes, nTriangles);
-
- iNSubModel = nSubModels;
-
- iSubModel = new SubModel[iNSubModel];
-
- int subModelPos,treeNodePos, trianglePos;
- subModelPos = treeNodePos = trianglePos = 0;
-
- Vector3 lo = Vector3(inf(),inf(),inf());
- Vector3 hi = Vector3(-inf(),-inf(),-inf());
- Vector3 finalLo, finalHi;
- finalLo = lo;
- finalHi = hi;
-
- fillContainer(*pTree->root, subModelPos, treeNodePos, trianglePos, lo, hi, finalLo, finalHi);
- setBounds(finalLo, finalHi);
- }
-
- //==========================================================
-
- ModelContainer::~ModelContainer(void)
- {
- free();
- if(iSubModel != 0) delete [] iSubModel;
- }
- //==========================================================
-
- bool ModelContainer::writeFile(const char *filename)
- {
- bool result = false;
- unsigned int flags=0;
- unsigned int size;
-
- FILE *wf =fopen(filename,"wb");
- if(wf)
- {
- fwrite(VMAP_MAGIC,1,8,wf);
- result = true;
- if(result && fwrite("CTREE01",8,1,wf) != 1) result = false;
- if(result && fwrite(&flags,sizeof(unsigned int),1,wf) != 1) result = false;
-
- if(result && fwrite("POS ",4,1,wf) != 1) result = false;
- size = sizeof(float)*3;
- if(result && fwrite(&size,4,1,wf) != 1) result = false;
- Vector3 basePos = getBasePosition();
- if(result && fwrite(&basePos,sizeof(float),3,wf) != 3) result = false;
-
- if(result && fwrite("BOX ",4,1,wf) != 1) result = false;
- size = sizeof(float)*6;
- if(result && fwrite(&size,4,1,wf) != 1) result = false;
- Vector3 low = iBox.low();
- if(result && fwrite(&low,sizeof(float),3,wf) != 3) result = false;
- Vector3 high = iBox.high();
- if(result && fwrite(&high,sizeof(float),3,wf) != 3) result = false;
-
- if(result && fwrite("NODE",4,1,wf) != 1) result = false;
- size = sizeof(unsigned int)+ sizeof(TreeNode)*getNNodes();
- if(result && fwrite(&size,4,1,wf) != 1) result = false;
- unsigned int val = getNNodes();
- if(result && fwrite(&val,sizeof(unsigned int),1,wf) != 1) result = false;
- if(result && fwrite(getTreeNodes(),sizeof(TreeNode),getNNodes(),wf) != getNNodes()) result = false;
-
- if(result && fwrite("TRIB",4,1,wf) != 1) result = false;
- size = sizeof(unsigned int)+ sizeof(TriangleBox)*getNTriangles();
- if(result && fwrite(&size,4,1,wf) != 1) result = false;
- val = getNTriangles();
- if(result && fwrite(&val,sizeof(unsigned int),1,wf) != 1) result = false;
- if(result && fwrite(getTriangles(),sizeof(TriangleBox),getNTriangles(),wf) != getNTriangles()) result = false;
-
- if(result && fwrite("SUBM",4,1,wf) != 1) result = false;
- size = sizeof(unsigned int)+ sizeof(SubModel)*iNSubModel;
- if(result && fwrite(&size,4,1,wf) != 1) result = false;
- if(result && fwrite(&iNSubModel,sizeof(unsigned int),1,wf) != 1) result = false;
- if(result && fwrite(iSubModel,sizeof(SubModel),iNSubModel,wf) != iNSubModel) result = false;
-
- fclose(wf);
- }
-
- return(result);
- }
-
- //===============================================================
-
- bool ModelContainer::readFile(const char *filename)
- {
- bool result = false;
- unsigned int flags;
- unsigned int size;
- char ident[8];
- char chunk[4];
- unsigned int ival;
- FILE *rf = fopen(filename, "rb");
- if(rf)
- {
- free();
-
- result = true;
- char magic[8]; // Ignore the added magic header
- fread(magic,1,8,rf);
- if(strncmp(VMAP_MAGIC,magic,8)) result = false;
- if(result && fread(ident,8,1,rf) != 1) result = false;
- if(result && fread(&flags,sizeof(unsigned int),1,rf) != 1) result = false;
- //POS
- if(result && fread(chunk,4,1,rf) != 1) result = false;
- if(result && fread(&size,4,1,rf) != 1) result = false;
- Vector3 basePos;
- if(result && fread(&basePos,sizeof(float),3,rf) != 3) result = false;
- setBasePosition(basePos);
-
- //---- Box
- if(result && fread(chunk,4,1,rf) != 1) result = false;
- if(result && fread(&size,4,1,rf) != 1) result = false;
- Vector3 low,high;
- if(result && fread(&low,sizeof(float),3,rf) != 3) result = false;
- if(result && fread(&high,sizeof(float),3,rf) != 3) result = false;
- setBounds(low, high);
-
- //---- TreeNodes
- if(result && fread(chunk,4,1,rf) != 1) result = false;
- if(result && fread(&size,4,1,rf) != 1) result = false;
-
- if(result && fread(&ival,sizeof(unsigned int),1,rf) != 1) result = false;
- if(result) setNNodes(ival);
- if(result) setTreeNodeArray(new TreeNode[getNNodes()]);
- if(result && fread(getTreeNodes(),sizeof(TreeNode),getNNodes(),rf) != getNNodes()) result = false;
-
- //---- TriangleBoxes
- if(result && fread(chunk,4,1,rf) != 1) result = false;
- if(result && fread(&size,4,1,rf) != 1) result = false;
-
- if(result && fread(&ival,sizeof(unsigned int),1,rf) != 1) result = false;
- setNTriangles(ival);
- if(result) setTriangleArray(new TriangleBox[getNTriangles()]);
- if(result && fread(getTriangles(),sizeof(TriangleBox),getNTriangles(),rf) != getNTriangles()) result = false;
-
- //---- SubModel
- if(result && fread(chunk,4,1,rf) != 1) result = false;
- if(result && fread(&size,4,1,rf) != 1) result = false;
-
- if(result && fread(&iNSubModel,sizeof(unsigned int),1,rf) != 1) result = false;
- if(result) iSubModel = new SubModel[iNSubModel];
-
- if(result)
- {
- for (unsigned int i=0; i<iNSubModel && result; ++i)
- {
- unsigned char readBuffer[52]; // this is the size of SubModel on 32 bit systems
- if(fread(readBuffer,sizeof(readBuffer),1,rf) != 1) result = false;
- iSubModel[i].initFromBinBlock(readBuffer);
- iSubModel[i].setTriangleArray(getTriangles());
- iSubModel[i].setTreeNodeArray(getTreeNodes());
- }
- }
- fclose(rf);
- }
- return result;
- }
-
- //=================================================================
-
- size_t ModelContainer::getMemUsage()
- {
- // BaseModel is included in ModelContainer
- return(iNSubModel * sizeof(SubModel) + BaseModel::getMemUsage() + sizeof(ModelContainer) - sizeof(BaseModel));
- }
-
- //=================================================================
-#ifdef _DEBUG_VMAPS
-#ifndef gBoxArray
- extern Vector3 p1,p2,p3,p4,p5,p6,p7;
- extern Array<AABox>gBoxArray;
- extern int gCount1, gCount2, gCount3, gCount4;
- extern bool myfound;
-#endif
-#endif
-
- void ModelContainer::intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& /*pOutLocation*/, G3D::Vector3& /*pOutNormal*/) const
- {
- IntersectionCallBack<SubModel> intersectCallback;
- NodeValueAccess<TreeNode, SubModel> vna = NodeValueAccess<TreeNode, SubModel>(getTreeNodes(), iSubModel);
- Ray relativeRay = Ray::fromOriginAndDirection(pRay.origin - getBasePosition(), pRay.direction);
- iTreeNodes[0].intersectRay(pRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false);
- }
-
- //==========================================================
-
- bool ModelContainer::intersect(const G3D::Ray& pRay, float& pMaxDist) const
- {
- return BaseModel::intersect(getAABoxBounds(), pRay, pMaxDist);
- }
-
- //=================================================================
-
- template<typename RayCallback>
- void ModelContainer::intersectRay(const G3D::Ray& pRay, RayCallback& intersectCallback, float& pMaxDist, bool pStopAtFirstHit, bool intersectCallbackIsFast)
- {
- if(intersect(pRay, pMaxDist))
- {
- NodeValueAccess<TreeNode, SubModel> vna = NodeValueAccess<TreeNode, SubModel>(getTreeNodes(), iSubModel);
- iTreeNodes[0].intersectRay(pRay, intersectCallback, distance, vna, pStopAtFirstHit, true);
- }
- }
- //=================================================================
- void getBounds(const ModelContainer& pMc, G3D::AABox& pAABox)
- {
- pAABox = pMc.getAABoxBounds();
- }
-
- //=================================================================
-
- void getBounds(const ModelContainer* pMc, G3D::AABox& pAABox)
- {
- pAABox = pMc->getAABoxBounds();
- }
- //=================================================================
-} // VMAP
-
diff --git a/src/shared/vmap/ModelContainer.h b/src/shared/vmap/ModelContainer.h
deleted file mode 100644
index 5b3eeb20bb2..00000000000
--- a/src/shared/vmap/ModelContainer.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _MODELCONTAINER_H
-#define _MODELCONTAINER_H
-
-// load our modified version first !!
-#include "AABSPTree.h"
-
-#include <G3D/AABox.h>
-#include <G3D/Vector3.h>
-#include <G3D/Ray.h>
-
-#include "ShortBox.h"
-#include "TreeNode.h"
-#include "VMapTools.h"
-#include "SubModel.h"
-#include "BaseModel.h"
-
-namespace VMAP
-{
- /**
- The ModelContainer is a balanced BSP-Tree of SubModels.
- We store a map tile or an instance in one ModelContainer.
- The ModelContainer manages the memory used for the tree nodes, the SubModels and its triangles in static arrays.
- The tree nodes are used for the BSP-Tree of SubModels as well as for the BSP-Tree of triangles within one SubModel.
- The references are done by indexes within these static arrays.
- Therefore we are able to just load a binary block and do not need to mess around with memory allocation and pointers.
- */
-
- //=====================================================
-
- class ModelContainer : public BaseModel
- {
- private:
- unsigned int iNSubModel;
- SubModel *iSubModel;
- G3D::AABox iBox;
-
- ModelContainer (const ModelContainer& c): BaseModel(c) {}
- ModelContainer& operator=(const ModelContainer& ) {}
-
- public:
- ModelContainer() : BaseModel() { iNSubModel =0; iSubModel = 0; };
-
- // for the mainnode
- ModelContainer(unsigned int pNTriangles, unsigned int pNNodes, unsigned int pNSubModel);
-
- ModelContainer(G3D::AABSPTree<SubModel *> *pTree);
-
- ~ModelContainer(void);
-
- inline const void setSubModel(const SubModel& pSubModel, int pPos) { iSubModel[pPos] = pSubModel; }
-
- inline const SubModel& getSubModel(int pPos) const { return iSubModel[pPos]; }
-
- inline unsigned int getNSubModel() const { return(iNSubModel); }
-
- void countSubModelsAndNodesAndTriangles(G3D::AABSPTree<SubModel *>::Node& pNode, int& nSubModels, int& nNodes, int& nTriangles);
-
- void fillContainer(const G3D::AABSPTree<SubModel *>::Node& pNode, int &pSubModelPos, int &pTreeNodePos, int &pTrianglePos, G3D::Vector3& pLo, G3D::Vector3& pHi, G3D::Vector3& pFinalLo, G3D::Vector3& pFinalHi);
-
- bool readRawFile(const char *name);
-
- inline const G3D::AABox& getAABoxBounds() const { return(iBox); }
-
- inline void setBounds(const G3D::Vector3& lo, const G3D::Vector3& hi) { iBox.set(lo,hi); }
-
- bool writeFile(const char *filename);
-
- bool readFile(const char *filename);
-
- size_t getMemUsage();
- size_t hashCode() { return (getBasePosition() * getNTriangles()).hashCode(); }
-
- void intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& pOutLocation, G3D::Vector3& pOutNormal) const;
- bool intersect(const G3D::Ray& pRay, float& pMaxDist) const;
-
- template<typename RayCallback>
- void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& distance, bool pStopAtFirstHit, bool intersectCallbackIsFast = false);
-
- bool operator==(const ModelContainer& pMc2) const;
- };
-
- //=====================================================
-
- //=====================================================
-
- size_t hashCode(const ModelContainer& pMc);
- void getBounds(const ModelContainer& pMc, G3D::AABox& pAABox);
- void getBounds(const ModelContainer* pMc, G3D::AABox& pAABox);
-}
-#endif
-
diff --git a/src/shared/vmap/ModelInstance.cpp b/src/shared/vmap/ModelInstance.cpp
new file mode 100644
index 00000000000..677a08e147a
--- /dev/null
+++ b/src/shared/vmap/ModelInstance.cpp
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#include "ModelInstance.h"
+#include "WorldModel.h"
+#include "MapTree.h"
+
+using G3D::Vector3;
+using G3D::Ray;
+
+namespace VMAP
+{
+ ModelInstance::ModelInstance(const ModelSpawn &spawn, WorldModel *model): ModelSpawn(spawn), iModel(model)
+ {
+ iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iRot.y/180.f, G3D::pi()*iRot.x/180.f, G3D::pi()*iRot.z/180.f).inverse();
+ iInvScale = 1.f/iScale;
+ }
+
+ bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const
+ {
+ if (!iModel)
+ {
+ //std::cout << "<object not loaded>\n";
+ return false;
+ }
+ float time = pRay.intersectionTime(iBound);
+ if (time == G3D::inf())
+ {
+// std::cout << "Ray does not hit '" << name << "'\n";
+
+ return false;
+ }
+// std::cout << "Ray crosses bound of '" << name << "'\n";
+/* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z
+ << " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z
+ << " t/tmax:" << time << "/" << pMaxDist;
+ std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: "
+ << iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */
+ // child bounds are defined in object space:
+ Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale;
+ Ray modRay(p, iInvRot * pRay.direction());
+ float distance = pMaxDist * iInvScale;
+ bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit);
+ distance *= iScale;
+ pMaxDist = distance;
+ return hit;
+ }
+
+ void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo &info) const
+ {
+ if (!iModel)
+ {
+#ifdef VMAP_DEBUG
+ std::cout << "<object not loaded>\n";
+#endif
+ return;
+ }
+
+ // M2 files don't contain area info, only WMO files
+ if (flags & MOD_M2)
+ return;
+ if (!iBound.contains(p))
+ return;
+ // child bounds are defined in object space:
+ Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
+ Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
+ float zDist;
+ if (iModel->IntersectPoint(pModel, zDirModel, zDist, info))
+ {
+ Vector3 modelGround = pModel + zDist * zDirModel;
+ // Transform back to world space. Note that:
+ // Mat * vec == vec * Mat.transpose()
+ // and for rotation matrices: Mat.inverse() == Mat.transpose()
+ float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
+ if (info.ground_Z < world_Z)
+ {
+ info.ground_Z = world_Z;
+ info.adtId = adtId;
+ }
+ }
+ }
+
+ bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const
+ {
+ if (!iModel)
+ {
+#ifdef VMAP_DEBUG
+ std::cout << "<object not loaded>\n";
+#endif
+ return false;
+ }
+
+ // M2 files don't contain area info, only WMO files
+ if (flags & MOD_M2)
+ return false;
+ if (!iBound.contains(p))
+ return false;
+ // child bounds are defined in object space:
+ Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
+ Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
+ float zDist;
+ if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
+ {
+ Vector3 modelGround = pModel + zDist * zDirModel;
+ // Transform back to world space. Note that:
+ // Mat * vec == vec * Mat.transpose()
+ // and for rotation matrices: Mat.inverse() == Mat.transpose()
+ float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
+ if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection?
+ {
+ info.ground_Z = world_Z;
+ info.hitInstance = this;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const
+ {
+ // child bounds are defined in object space:
+ Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
+ //Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
+ float zDist;
+ if (info.hitModel->GetLiquidLevel(pModel, zDist))
+ {
+ // calculate world height (zDist in model coords):
+ // assume WMO not tilted (wouldn't make much sense anyway)
+ liqHeight = zDist * iScale + iPos.z;
+ return true;
+ }
+ return false;
+ }
+
+ bool ModelSpawn::readFromFile(FILE *rf, ModelSpawn &spawn)
+ {
+ uint32 check=0, nameLen;
+ check += fread(&spawn.flags, sizeof(uint32), 1, rf);
+ // EoF?
+ if (!check)
+ {
+ if (ferror(rf))
+ std::cout << "Error reading ModelSpawn!\n";
+ return false;
+ }
+ check += fread(&spawn.adtId, sizeof(uint16), 1, rf);
+ check += fread(&spawn.ID, sizeof(uint32), 1, rf);
+ check += fread(&spawn.iPos, sizeof(float), 3, rf);
+ check += fread(&spawn.iRot, sizeof(float), 3, rf);
+ check += fread(&spawn.iScale, sizeof(float), 1, rf);
+ bool has_bound = (spawn.flags & MOD_HAS_BOUND);
+ if (has_bound) // only WMOs have bound in MPQ, only available after computation
+ {
+ Vector3 bLow, bHigh;
+ check += fread(&bLow, sizeof(float), 3, rf);
+ check += fread(&bHigh, sizeof(float), 3, rf);
+ spawn.iBound = G3D::AABox(bLow, bHigh);
+ }
+ check += fread(&nameLen, sizeof(uint32), 1, rf);
+ if(check != (has_bound ? 17 : 11))
+ {
+ std::cout << "Error reading ModelSpawn!\n";
+ return false;
+ }
+ char nameBuff[500];
+ if (nameLen>500) // file names should never be that long, must be file error
+ {
+ std::cout << "Error reading ModelSpawn, file name too long!\n";
+ return false;
+ }
+ check = fread(nameBuff, sizeof(char), nameLen, rf);
+ if (check != nameLen)
+ {
+ std::cout << "Error reading ModelSpawn!\n";
+ return false;
+ }
+ spawn.name = std::string(nameBuff, nameLen);
+ return true;
+ }
+
+ bool ModelSpawn::writeToFile(FILE *wf, const ModelSpawn &spawn)
+ {
+ uint32 check=0;
+ check += fwrite(&spawn.flags, sizeof(uint32), 1, wf);
+ check += fwrite(&spawn.adtId, sizeof(uint16), 1, wf);
+ check += fwrite(&spawn.ID, sizeof(uint32), 1, wf);
+ check += fwrite(&spawn.iPos, sizeof(float), 3, wf);
+ check += fwrite(&spawn.iRot, sizeof(float), 3, wf);
+ check += fwrite(&spawn.iScale, sizeof(float), 1, wf);
+ bool has_bound = (spawn.flags & MOD_HAS_BOUND);
+ if(has_bound) // only WMOs have bound in MPQ, only available after computation
+ {
+ check += fwrite(&spawn.iBound.low(), sizeof(float), 3, wf);
+ check += fwrite(&spawn.iBound.high(), sizeof(float), 3, wf);
+ }
+ uint32 nameLen = spawn.name.length();
+ check += fwrite(&nameLen, sizeof(uint32), 1, wf);
+ if(check != (has_bound ? 17 : 11)) return false;
+ check = fwrite(spawn.name.c_str(), sizeof(char), nameLen, wf);
+ if(check != nameLen) return false;
+ return true;
+ }
+
+}
diff --git a/src/shared/vmap/ModelInstance.h b/src/shared/vmap/ModelInstance.h
new file mode 100644
index 00000000000..97b3ab632a1
--- /dev/null
+++ b/src/shared/vmap/ModelInstance.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#ifndef _MODELINSTANCE_H_
+#define _MODELINSTANCE_H_
+
+#include <G3D/Matrix3.h>
+#include <G3D/Vector3.h>
+#include <G3D/AABox.h>
+#include <G3D/Ray.h>
+
+#include "Platform/Define.h"
+
+namespace VMAP
+{
+ class WorldModel;
+ struct AreaInfo;
+ struct LocationInfo;
+
+ enum ModelFlags
+ {
+ MOD_M2 = 1,
+ MOD_WORLDSPAWN = 1<<1,
+ MOD_HAS_BOUND = 1<<2
+ };
+
+ class ModelSpawn
+ {
+ public:
+ //mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
+ uint32 flags;
+ uint16 adtId;
+ uint32 ID;
+ G3D::Vector3 iPos;
+ G3D::Vector3 iRot;
+ float iScale;
+ G3D::AABox iBound;
+ std::string name;
+ bool operator==(const ModelSpawn &other) const { return ID == other.ID; }
+ //uint32 hashCode() const { return ID; }
+ // temp?
+ const G3D::AABox& getBounds() const { return iBound; }
+
+
+ static bool readFromFile(FILE *rf, ModelSpawn &spawn);
+ static bool writeToFile(FILE *rw, const ModelSpawn &spawn);
+ };
+
+ class ModelInstance: public ModelSpawn
+ {
+ public:
+ ModelInstance(): iModel(0) {}
+ ModelInstance(const ModelSpawn &spawn, WorldModel *model);
+ void setUnloaded() { iModel = 0; }
+ bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const;
+ void intersectPoint(const G3D::Vector3& p, AreaInfo &info) const;
+ bool GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const;
+ bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const;
+ protected:
+ G3D::Matrix3 iInvRot;
+ float iInvScale;
+ WorldModel *iModel;
+ };
+} // namespace VMAP
+
+#endif // _MODELINSTANCE
diff --git a/src/shared/vmap/NodeValueAccess.h b/src/shared/vmap/NodeValueAccess.h
deleted file mode 100644
index 50a03480fe3..00000000000
--- a/src/shared/vmap/NodeValueAccess.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _NODEVALUEACCESS_H
-#define _NODEVALUEACCESS_H
-
-namespace VMAP
-{
- /**
- This is a helper Class to get access to SubModels or triangles when analyzing the BSP-Tree.
- */
-
- template<class TNode, class TValue> class NodeValueAccess
- {
- private:
- TNode const* iNodeArray;
- TValue const* iValueArray;
-
- public:
- inline NodeValueAccess() : iNodeArray(NULL), iValueArray(NULL) {}
-
- inline NodeValueAccess(TNode const* pNodeArray, TValue const* pValueArray) : iNodeArray(pNodeArray), iValueArray(pValueArray) {}
- inline TNode const* getNodePtr() const { return(iNodeArray); }
- inline TValue const* getValuePtr() const { return(iValueArray); }
-
- inline TNode const& getNode(unsigned int pPos) const { return(iNodeArray[pPos]); }
- inline void setNode(const TNode& pNode, unsigned int pPos) { iNodeArray[pPos] = pNode; }
-
- inline TValue const& getValue(unsigned int pPos) const { return(iValueArray[pPos]); }
- inline void setValue(const TValue& pValue, unsigned int pPos) { iValueArray[pPos] = pValue; }
- };
-}
-#endif
-
diff --git a/src/shared/vmap/ShortBox.h b/src/shared/vmap/ShortBox.h
deleted file mode 100644
index bf451c6a58e..00000000000
--- a/src/shared/vmap/ShortBox.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _SHORTBOX_H
-#define _SHORTBOX_H
-
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-#include <G3D/Triangle.h>
-#include <G3D/Ray.h>
-
-#include "ShortVector.h"
-
-/**
-This is a box and a triangle Class using ShortVectors. Each vector has 16 bit an a fixed point 12.4 representation.
-*/
-
-namespace VMAP
-{
-
- class ShortBox
- {
- private:
- ShortVector iV1;
- ShortVector iV2;
- public:
- ShortBox() {}
- inline const ShortVector& getLo() const { return(iV1); }
- inline const ShortVector& getHi() const { return(iV2); }
- inline void setLo(const ShortVector& pV){ iV1 = pV; }
- inline void setHi(const ShortVector& pV){ iV2 = pV; }
- inline void setLo(const G3D::Vector3& pV){ iV1 = ShortVector(pV); }
- inline void setHi(const G3D::Vector3& pV){ iV2 = ShortVector(pV); }
-
- inline bool operator==(const ShortBox& b) const
- {
- return ((iV1 == b.iV1) && (iV2 == b.iV2));
- }
-
- inline bool operator!=(const ShortBox& b) const
- {
- return !((iV1 == b.iV1) && (iV2 == b.iV2));
- }
- };
-
- //=====================================================================
-#ifdef _DEBUG_VMAPS
-#ifndef gBoxArray
- extern G3D::Vector3 p1,p2,p3,p4,p5,p6,p7;
- extern G3D::Array<G3D::AABox>gBoxArray;
- extern G3D::Array<G3D::Triangle>gTriArray;
- extern int gCount1, gCount2, gCount3, gCount4;
- extern bool myfound;
-#endif
-#endif
-
- static const G3D::Vector3 dummyZeroPosition = G3D::Vector3(0,0,0);
-
- class TriangleBox
- {
- private:
- ShortVector _vertex[3];
- //ShortBox iBox;
- public:
- inline TriangleBox() { }
- inline TriangleBox(const ShortVector& pV1, const ShortVector& pV2, const ShortVector& pV3)
- {
- _vertex[0] = pV1;
- _vertex[1] = pV2;
- _vertex[2] = pV3;
-
- }
- inline const ShortVector& vertex (int n) const
- {
- return(_vertex[n]);
- }
-
- inline const ShortBox getBounds()const
- {
- ShortBox box;
-
- ShortVector lo = _vertex[0];
- ShortVector hi = lo;
-
- for (int i = 1; i < 3; ++i)
- {
- lo = lo.min(_vertex[i]);
- hi = hi.max(_vertex[i]);
- }
- box.setLo(lo);
- box.setHi(hi);
- return(box);
- }
- inline const G3D::Vector3& getBasePosition() { return(dummyZeroPosition); }
-
- inline const G3D::AABox getAABoxBounds() const { ShortBox box = getBounds(); return(G3D::AABox(box.getLo().getVector3(), box.getHi().getVector3())); }
-
- inline bool operator==(const TriangleBox& t) const
- {
- return ((_vertex[0] == t._vertex[0]) && (_vertex[1] == t._vertex[1]) &&(_vertex[2] == t._vertex[2]));
- }
-
- inline bool operator!=(const TriangleBox& t) const
- {
- return !((_vertex[0] == t._vertex[0]) && (_vertex[1] == t._vertex[1]) &&(_vertex[2] == t._vertex[2]));
- }
-
- inline void intersect(const G3D::Ray& pRay, float& pMaxDist, bool /*pStopAtFirstHitDummy*/, G3D::Vector3& /*pOutLocationDummy*/, G3D::Vector3& /*pOutNormalDummy*/) const
- {
- static const double epsilon = 0.00001;
- G3D::Triangle testT(vertex(0).getVector3(),vertex(1).getVector3(),vertex(2).getVector3());
- float t = pRay.intersectionTime(testT);
- if ((t < pMaxDist) || t < (pMaxDist + epsilon))
- pMaxDist = t;
- else
- {
- testT = G3D::Triangle(vertex(2).getVector3(),vertex(1).getVector3(),vertex(0).getVector3());
-
-#ifdef _DEBUG_VMAPS
- {
- G3D::Triangle myt(testT.vertex(0)+p6, testT.vertex(1)+p6,testT.vertex(2)+p6);
- gTriArray.push_back(myt);
- }
-#endif
- t = pRay.intersectionTime(testT);
- if ((t < pMaxDist) || t < (pMaxDist + epsilon))
- pMaxDist = t;
- }
- }
- };
-
-}
-#endif
-
diff --git a/src/shared/vmap/ShortVector.h b/src/shared/vmap/ShortVector.h
deleted file mode 100644
index 8093c3904c3..00000000000
--- a/src/shared/vmap/ShortVector.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _SHORTVECTOR_H
-#define _SHORTVECTOR_H
-
-#include <G3D/Vector3.h>
-
-namespace VMAP
-{
- /**
- Vector with 16 bit fix point values 12.4 bit.
- */
-
- class ShortVector
- {
- private:
- short iX;
- short iY;
- short iZ;
-
- const static short maxvalue = 0x7fff;
- const static short minvalue = -0x7fff;
- const static int fixpointdiv = 16;
- const static short fixpoint_maxvalue = maxvalue / fixpointdiv;
- const static short fixpoint_minvalue = minvalue / fixpointdiv;
-
- inline short float2Short(float fv) const
- {
- short sv;
- debugAssert((fv <= fixpoint_maxvalue || fv >= 1000000) && (fv >= fixpoint_minvalue || fv <= -1000000));
- if(fv >= fixpoint_maxvalue)
- sv=maxvalue;
- else if(fv <= fixpoint_minvalue)
- sv=minvalue;
- else
- sv = (short) (fv * fixpointdiv + 0.5);
- return(sv);
- }
- inline float short2Float(short sv) const
- {
- float fv;
- if(sv >= maxvalue)
- fv=G3D::inf();
- else if(sv <= minvalue)
- fv=-G3D::inf();
- else
- fv = ((float)sv) / fixpointdiv;
- return fv;
- }
-
- inline float getFX() const { return(short2Float(iX)); }
- inline float getFY() const { return(short2Float(iY)); }
- inline float getFZ() const { return(short2Float(iZ)); }
- public:
- inline ShortVector() {}
- inline ShortVector(const G3D::Vector3& pVector)
- {
- iX = float2Short(pVector.x);
- iY = float2Short(pVector.y);
- iZ = float2Short(pVector.z);
- }
-
- inline ShortVector(float pX, float pY, float pZ)
- {
- iX = float2Short(pX);
- iY = float2Short(pY);
- iZ = float2Short(pZ);
- }
- inline ShortVector(short pX, short pY, short pZ)
- {
- iX = pX;
- iY = pY;
- iZ = pZ;
- }
- inline ShortVector(const ShortVector& pShortVector)
- {
- iX = pShortVector.iX;
- iY = pShortVector.iY;
- iZ = pShortVector.iZ;
- }
-
- inline float getX() const { return(iX); }
- inline float getY() const { return(iY); }
- inline float getZ() const { return(iZ); }
-
- inline G3D::Vector3 getVector3() const { return(G3D::Vector3(getFX(), getFY(), getFZ())); }
-
- inline ShortVector min(const ShortVector pShortVector)
- {
- ShortVector result = pShortVector;
- if(pShortVector.iX > iX) { result.iX = iX; }
- if(pShortVector.iY > iY) { result.iY = iY; }
- if(pShortVector.iZ > iZ) { result.iZ = iZ; }
- return(result);
- }
-
- inline ShortVector max(const ShortVector pShortVector)
- {
- ShortVector result = pShortVector;
- if(pShortVector.iX < iX) { result.iX = iX; }
- if(pShortVector.iY < iY) { result.iY = iY; }
- if(pShortVector.iZ < iZ) { result.iZ = iZ; }
- return(result);
- }
-
- inline bool operator==(const ShortVector& v) const
- {
- return (iX == v.iX && iY == v.iY && iZ == v.iZ);
- }
-
- inline bool operator!=(const ShortVector& v) const
- {
- return !(iX == v.iX && iY == v.iY && iZ == v.iZ);
- }
-
- };
-}
-#endif
-
diff --git a/src/shared/vmap/SubModel.cpp b/src/shared/vmap/SubModel.cpp
deleted file mode 100644
index 1f72fc6826d..00000000000
--- a/src/shared/vmap/SubModel.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include "SubModel.h"
-
-#ifdef _ASSEMBLER_DEBUG
-extern FILE *::g_df;
-#endif
-
-using namespace G3D;
-
-namespace VMAP
-{
-
- //==========================================================
- /**
- Functions to use ModelContainer with a AABSPTree
- */
- unsigned int hashCode(const SubModel& pSm)
- {
- return pSm.getNTriangles();
- }
-
- void getBounds(const SubModel& pSm, G3D::AABox& pAABox)
- {
- ShortBox box = pSm.getReletiveBounds();
- pAABox.set(box.getLo().getVector3()+pSm.getBasePosition(), box.getHi().getVector3()+pSm.getBasePosition());
- }
-
- void getBounds(const SubModel* pSm, G3D::AABox& pAABox)
- {
- ShortBox box = pSm->getReletiveBounds();
- pAABox.set(box.getLo().getVector3()+pSm->getBasePosition(), box.getHi().getVector3()+pSm->getBasePosition());
- }
-
- //==========================================================
- //==========================================================
- //==========================================================
- //==========================================================
- SubModel::SubModel(unsigned int pNTriangles, TriangleBox *pTriangles, unsigned int pTrianglesPos, unsigned int pNNodes, TreeNode *pTreeNodes, unsigned int pNodesPos) :
- BaseModel(pNNodes, pTreeNodes, pNTriangles, pTriangles)
- {
- iTrianglesPos = pTrianglesPos;
- iNodesPos = pNodesPos;
- iHasInternalMemAlloc = false;
- }
-
- //==========================================================
-
- SubModel::~SubModel(void)
- {
- if(iHasInternalMemAlloc)
- {
- free();
- }
- }
-
- //==========================================================
-
- bool SubModel::operator==(const SubModel& pSm2) const
- {
- bool result = false;
-
- if(getNNodes() == pSm2.getNNodes() &&
- getNTriangles() == pSm2.getNTriangles() &&
- getBasePosition() == pSm2.getBasePosition() &&
- getNodesPos() == pSm2.getNodesPos() &&
- getTrianglesPos() == pSm2.getTrianglesPos())
- {
- result = true;
- }
- return result;
- }
- //==========================================================
-
- enum BIN_POSITIONS
- {
- BP_iNTriangles=8,
- BP_iNNodes=12,
- BP_iBasePosition=16,
- BP_iNodesPos=28,
- BP_iTrianglesPos=32,
- BP_iHasInternalMemAlloc=36,
- BP_iBox=38,
- };
- /**
- This is ugly, but due to compatibility and 64 bit support we have to do that ... sorry
- */
- void SubModel::initFromBinBlock(void *pBinBlock)
- {
- iNTriangles = *((unsigned int *)(((char *) pBinBlock) + BP_iNTriangles));
- iNNodes = *((unsigned int *) (((char *) pBinBlock) + BP_iNNodes));
- iBasePosition = *((Vector3 *) (((char *) pBinBlock) + BP_iBasePosition));
- iNodesPos = *((unsigned int *) (((char *) pBinBlock) + BP_iNodesPos));
- iTrianglesPos = *((unsigned int *) (((char *) pBinBlock) + BP_iTrianglesPos));
- iHasInternalMemAlloc = *((bool *) (((char *) pBinBlock) + BP_iHasInternalMemAlloc));
- iBox = *((ShortBox *) (((char *) pBinBlock) + BP_iBox));
- }
-
- //==========================================================
-
- void SubModel::countNodesAndTriangles(AABSPTree<Triangle>::Node& pNode, int &pNNodes, int &pNTriabgles)
- {
- ++pNNodes;
- pNTriabgles += pNode.valueArray.size();
-
- #ifdef _ASSEMBLER_DEBUG
- fprintf(::g_df, "Nodes: %d, Tris: %d\n",pNNodes, pNTriabgles);
- #endif
-
- if(pNode.child[0] != 0)
- {
- countNodesAndTriangles(*pNode.child[0], pNNodes, pNTriabgles);
- }
- if(pNode.child[1] != 0)
- {
- countNodesAndTriangles(*pNode.child[1], pNNodes, pNTriabgles);
- }
- }
-
- //==========================================================
-
- void SubModel::fillContainer(const AABSPTree<Triangle>::Node& pNode, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi)
- {
- TreeNode treeNode = TreeNode(pNode.valueArray.size(), pTrianglePos);
- treeNode.setSplitAxis(pNode.splitAxis);
- treeNode.setSplitLocation(pNode.splitLocation);
-
- int currentTreeNodePos = pTreeNodePos++;
-
- Vector3 lo = Vector3(inf(),inf(),inf());
- Vector3 hi = Vector3(-inf(),-inf(),-inf());
-
- for (int i=0; i<pNode.valueArray.size(); i++)
- {
- G3D::_AABSPTree::Handle<Triangle>* h= pNode.valueArray[i];
- Triangle t = h->value;
- TriangleBox triangleBox = TriangleBox(t.vertex(0),t.vertex(1), t.vertex(2));
- lo = lo.min(triangleBox.getBounds().getLo().getVector3());
- hi = hi.max(triangleBox.getBounds().getHi().getVector3());
-
- getTriangles()[pTrianglePos++] = triangleBox;
- }
-
- if(pNode.child[0] != 0)
- {
- treeNode.setChildPos(0, pTreeNodePos);
- fillContainer(*pNode.child[0], pTreeNodePos, pTrianglePos, lo, hi);
- }
- if(pNode.child[1] != 0)
- {
- treeNode.setChildPos(1, pTreeNodePos);
- fillContainer(*pNode.child[1], pTreeNodePos, pTrianglePos, lo, hi);
- }
-
- treeNode.setBounds(lo,hi);
-
- // get absolute bounds
- pLo = pLo.min(lo);
- pHi = pHi.max(hi);
-
- getTreeNodes()[currentTreeNodePos] = treeNode;
- }
-
- //==========================================================
-
- SubModel::SubModel(AABSPTree<Triangle> *pTree)
- {
- int nNodes, nTriangles;
- nNodes = nTriangles = 0;
- countNodesAndTriangles(*pTree->root, nNodes, nTriangles);
-
- init(nNodes, nTriangles);
-
- iTrianglesPos = 0; // this is the global array
- iNodesPos = 0; // this is the global array
- iHasInternalMemAlloc = true;
- int treeNodePos, trianglePos;
- treeNodePos = trianglePos = 0;
-
- Vector3 lo = Vector3(inf(),inf(),inf());
- Vector3 hi = Vector3(-inf(),-inf(),-inf());
-
- fillContainer(*pTree->root, treeNodePos, trianglePos, lo, hi);
- setReletiveBounds(lo, hi);
- }
-
- //==========================================================
-#ifdef _DEBUG_VMAPS
-#ifndef gBoxArray
- extern Vector3 p1,p2,p3,p4,p5,p6,p7;
- extern Array<AABox>gBoxArray;
- extern Array<G3D::Triangle>gTriArray;
- extern int gCount1, gCount2, gCount3, gCount4;
- extern bool myfound;
-#endif
-#endif
-
- //==========================================================
- void SubModel::intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& /*pOutLocation*/, G3D::Vector3& /*pOutNormal*/) const
- {
- NodeValueAccess<TreeNode, TriangleBox> vna = NodeValueAccess<TreeNode, TriangleBox>(getTreeNodes(), getTriangles());
- IntersectionCallBack<TriangleBox> intersectCallback;
- Ray relativeRay = Ray::fromOriginAndDirection(pRay.origin - getBasePosition(), pRay.direction);
-#ifdef _DEBUG_VMAPS
- //p6=getBasePosition();
- //gBoxArray.push_back(getAABoxBounds());
-#endif
- getTreeNode(0).intersectRay(relativeRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false);
- }
-
- //==========================================================
-
- bool SubModel::intersect(const G3D::Ray& pRay, float& pMaxDist) const
- {
- return BaseModel::intersect(getAABoxBounds(), pRay, pMaxDist);
- }
-
- //==========================================================
-
- template<typename RayCallback>
- void SubModel::intersectRay(const Ray& pRay, RayCallback& pIntersectCallback, float& pMaxDist, bool pStopAtFirstHit, bool intersectCallbackIsFast)
- {
- if(intersect(pRay, pMaxDist))
- {
- NodeValueAccess<TreeNode, TriangleBox> vna = NodeValueAccess<TreeNode, TriangleBox>(getTreeNodes(), getTriangles());
- IntersectionCallBack<TriangleBox> intersectCallback;
- getTreeNode(0).intersectRay(pRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false);
- }
- }
- //==========================================================
-
-}
-
diff --git a/src/shared/vmap/SubModel.h b/src/shared/vmap/SubModel.h
deleted file mode 100644
index 206f722ca61..00000000000
--- a/src/shared/vmap/SubModel.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _SUBMODEL_H
-#define _SUBMODEL_H
-
-// load our modified version first !!
-#include "AABSPTree.h"
-
-#include "ShortVector.h"
-#include "ShortBox.h"
-#include "TreeNode.h"
-#include "VMapTools.h"
-#include "BaseModel.h"
-
-namespace VMAP
-{
- /**
- This is a balanced static BSP-Tree of triangles.
- The memory for the tree nodes and the triangles are managed by the ModelContainer.
- The exception to this is during the conversion of raw data info balanced BSP-Trees.
- During this conversion the memory management is done internally.
- */
- class SubModel : public BaseModel
- {
- private:
- unsigned int iNodesPos;
- unsigned int iTrianglesPos;
- bool iHasInternalMemAlloc;
- ShortBox iBox;
- #ifdef _DEBUG_VIEW
- G3D::Array<TriangleBox *> iDrawBox;
- #endif
- public:
- SubModel() : BaseModel(){ };
-
- SubModel(unsigned int pNTriangles, TriangleBox *pTriangles, unsigned int pTrianglesPos, unsigned int pNNodes, TreeNode *pTreeNodes, unsigned int pNodesPos);
- SubModel(G3D::AABSPTree<G3D::Triangle> *pTree);
- ~SubModel(void);
- //Gets a 50 byte binary block
- void initFromBinBlock(void *pBinBlock);
-
- void fillRenderArray(G3D::Array<TriangleBox> &pArray, const TreeNode* pTreeNode);
-
- void countNodesAndTriangles(G3D::AABSPTree<G3D::Triangle>::Node& pNode, int &pNNodes, int &pNTriabgles);
-
- void fillContainer(const G3D::AABSPTree<G3D::Triangle>::Node& pNode, int &pTreeNodePos, int &pTrianglePos, G3D::Vector3& pLo, G3D::Vector3& pHi);
-
- inline const ShortBox& getReletiveBounds() const { return(iBox); }
-
- inline void setReletiveBounds(const ShortVector& lo, const ShortVector& hi) { iBox.setLo(lo); iBox.setHi(hi); }
-
- inline const G3D::AABox getAABoxBounds() const { return(G3D::AABox(iBox.getLo().getVector3() + getBasePosition(), iBox.getHi().getVector3()+ getBasePosition())); }
-
- // get start pos bases on the global array
- inline TriangleBox const* getTriangles() const { return &BaseModel::getTriangle(iTrianglesPos); }
- inline TriangleBox * getTriangles() { return &BaseModel::getTriangle(iTrianglesPos); }
-
- // get start pos bases on the global array
- inline TreeNode const* getTreeNodes() const { return &BaseModel::getTreeNode(iNodesPos); }
- inline TreeNode * getTreeNodes() { return &BaseModel::getTreeNode(iNodesPos); }
-
- // internal method usign internal offset
- inline const TreeNode& getTreeNode(int pPos) const { return(SubModel::getTreeNodes()[pPos]); }
-
- // internal method usign internal offset
- inline const TriangleBox& getTriangle(int pPos) const { return(SubModel::getTriangles()[pPos]); }
-
- inline unsigned int getNodesPos() const { return(iNodesPos); }
- inline unsigned int getTrianglesPos() const { return(iTrianglesPos); }
-
- //unsigned int hashCode() { return (getBasePosition() * getNTriangles()).hashCode(); }
-
- void intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& pOutLocation, G3D::Vector3& pOutNormal) const;
- bool intersect(const G3D::Ray& pRay, float& pMaxDist) const;
- template<typename RayCallback>
- void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& distance, bool pStopAtFirstHit, bool intersectCallbackIsFast = false);
- bool operator==(const SubModel& pSm2) const;
- unsigned int hashCode() const { return BaseModel::getNTriangles(); }
- };
-
- unsigned int hashCode(const SubModel& pSm);
- void getBounds(const SubModel& pSm, G3D::AABox& pAABox);
- void getBounds(const SubModel* pSm, G3D::AABox& pAABox);
- //====================================
-} // VMAP
-#endif
-
diff --git a/src/shared/vmap/TileAssembler.cpp b/src/shared/vmap/TileAssembler.cpp
index a79f609fa49..d01b54a7564 100644
--- a/src/shared/vmap/TileAssembler.cpp
+++ b/src/shared/vmap/TileAssembler.cpp
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
@@ -10,44 +8,50 @@
*
* 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <G3D/Vector3.h>
-#include <G3D/Triangle.h>
-
+#include "WorldModel.h"
#include "TileAssembler.h"
-#include "CoordModelMapping.h"
-#include "ModelContainer.h"
+#include "MapTree.h"
+#include "BIH.h"
+#include "VMapDefinitions.h"
-#include <limits.h>
-#include <string.h>
+#include <set>
+#include <iomanip>
+#include <sstream>
+#include <iomanip>
-#ifdef _ASSEMBLER_DEBUG
-FILE *g_df = NULL;
-#endif
+using G3D::Vector3;
+using G3D::AABox;
+using G3D::inf;
+using std::pair;
-using namespace G3D;
+template<> struct BoundsTrait<VMAP::ModelSpawn*>
+{
+ static void getBounds(const VMAP::ModelSpawn* const &obj, G3D::AABox& out) { out = obj->getBounds(); }
+};
namespace VMAP
{
- //=================================================================
+ bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len)
+ {
+ if (fread(dest, sizeof(char), len, rf) != len) return false;
+ return memcmp(dest, compare, len) == 0;
+ }
Vector3 ModelPosition::transform(const Vector3& pIn) const
{
- //return(pIn);
Vector3 out = pIn * iScale;
- out = izMatrix * out;
- out = ixMatrix * out;
- out = iyMatrix * out;
+ out = iRotation * out;
return(out);
-
}
+
//=================================================================
TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName)
@@ -57,320 +61,300 @@ namespace VMAP
iSrcDir = pSrcDirName;
iDestDir = pDestDirName;
//mkdir(iDestDir);
- init();
+ //init();
}
- //=================================================================
-
TileAssembler::~TileAssembler()
{
- delete iCoordModelMapping;
+ //delete iCoordModelMapping;
}
- //=================================================================
-
- void TileAssembler::init()
+ bool TileAssembler::convertWorld2()
{
- iCoordModelMapping = new CoordModelMapping();
- addWorldAreaMapId(0); //Azeroth
- addWorldAreaMapId(1); //Kalimdor
- addWorldAreaMapId(530); //Expansion01
- addWorldAreaMapId(571); //Expansion02
- }
- //=================================================================
+ std::set<std::string> spawnedModelFiles;
+ bool success = readMapSpawns();
+ if (!success)
+ return false;
- std::string getModNameFromModPosName(const std::string& pModPosName)
- {
- size_t spos = pModPosName.find_first_of('#');
- std::string modelFileName = pModPosName.substr(0,spos);
- return(modelFileName);
- }
+ // export Map data
+ for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end() && success; ++map_iter)
+ {
+ // build global map tree
+ std::vector<ModelSpawn*> mapSpawns;
+ UniqueEntryMap::iterator entry;
+ for (entry = map_iter->second->UniqueEntries.begin(); entry != map_iter->second->UniqueEntries.end(); ++entry)
+ {
+ // M2 models don't have a bound set in WDT/ADT placement data, i still think they're not used for LoS at all on retail
+ if (entry->second.flags & MOD_M2)
+ {
+ if (!calculateTransformedBound(entry->second))
+ break;
+ }
+ else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/
+ {
+ // TODO: remove extractor hack and uncomment below line:
+ //entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f);
+ entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f);
+ }
+ mapSpawns.push_back(&(entry->second));
+ spawnedModelFiles.insert(entry->second.name);
+ }
- //=================================================================
+ BIH pTree;
+ pTree.build(mapSpawns, BoundsTrait<ModelSpawn*>::getBounds);
+
+ // ===> possibly move this code to StaticMapTree class
+ std::map<uint32, uint32> modelNodeIdx;
+ for (uint32 i=0; i<mapSpawns.size(); ++i)
+ modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i));
+ if (!modelNodeIdx.empty())
+ printf("min GUID: %u, max GUID: %u\n", modelNodeIdx.begin()->first, modelNodeIdx.rbegin()->first);
+
+ // write map tree file
+ std::stringstream mapfilename;
+ mapfilename << iDestDir << "/" << std::setfill('0') << std::setw(3) << map_iter->first << ".vmtree";
+ FILE *mapfile = fopen(mapfilename.str().c_str(), "wb");
+ if (!mapfile)
+ {
+ success = false;
+ printf("Cannot open %s\n", mapfilename.str().c_str());
+ break;
+ }
- unsigned int TileAssembler::getUniqueNameId(const std::string pName)
- {
- unsigned int result;
+ //general info
+ if (success && fwrite(VMAP_MAGIC, 1, 8, mapfile) != 8) success = false;
+ uint32 globalTileID = StaticMapTree::packTileID(65, 65);
+ pair<TileMap::iterator, TileMap::iterator> globalRange = map_iter->second->TileEntries.equal_range(globalTileID);
+ char isTiled = globalRange.first == globalRange.second; // only maps without terrain (tiles) have global WMO
+ if (success && fwrite(&isTiled, sizeof(char), 1, mapfile) != 1) success = false;
+ // Nodes
+ if (success && fwrite("NODE", 4, 1, mapfile) != 1) success = false;
+ if (success) success = pTree.writeToFile(mapfile);
+ // global map spawns (WDT), if any (most instances)
+ if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
+
+ for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob)
+ {
+ success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second]);
+ }
- if(!iUniqueNameIds.containsKey(pName))
- {
- ++iCurrentUniqueNameId;
- iUniqueNameIds.set(pName, iCurrentUniqueNameId);
- }
- result = iUniqueNameIds.get(pName);
- return result;
- }
+ fclose(mapfile);
- //=================================================================
+ // <====
- std::string TileAssembler::getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName)
- {
- size_t spos;
- char buffer[20];
-
- std::string modelFileName = getModNameFromModPosName(pModPosName);
- //std::string fext = pModPosName.substr(modelFileName.length(),pModPosName.length());
- unsigned int fextId = getUniqueNameId(pModPosName);
- sprintf(buffer, "_%07d",fextId);
- std::string fext(buffer);
- spos = modelFileName.find_last_of('/');
- std::string fname = modelFileName.substr(spos+1, modelFileName.length());
- spos = fname.find_last_of('.');
- fname = fname.substr(0,spos);
- sprintf(buffer, "%03u", pMapId);
- std::string dirEntry(buffer);
- dirEntry.append("_");
- dirEntry.append(fname);
- dirEntry.append(fext);
- dirEntry.append(".vmap");
- return(dirEntry);
- }
+ // write map tile files, similar to ADT files, only with extra BSP tree node info
+ TileMap &tileEntries = map_iter->second->TileEntries;
+ TileMap::iterator tile;
+ for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile)
+ {
+ const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second];
+ if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently...
+ continue;
+ uint32 nSpawns = tileEntries.count(tile->first);
+ std::stringstream tilefilename;
+ tilefilename.fill('0');
+ tilefilename << iDestDir << "/" << std::setw(3) << map_iter->first << "_";
+ uint32 x, y;
+ StaticMapTree::unpackTileID(tile->first, x, y);
+ tilefilename << std::setw(2) << x << "_" << std::setw(2) << y << ".vmtile";
+ FILE *tilefile = fopen(tilefilename.str().c_str(), "wb");
+ // write number of tile spawns
+ if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
+ // write tile spawns
+ for (uint32 s=0; s<nSpawns; ++s)
+ {
+ if (s)
+ ++tile;
+ const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
+ success = success && ModelSpawn::writeToFile(tilefile, spawn2);
+ // MapTree nodes to update when loading tile:
+ std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
+ if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false;
+ }
+ fclose(tilefile);
+ }
+ // break; //test, extract only first map; TODO: remvoe this line
+ }
- //=================================================================
+ // export objects
+ std::cout << "\nConverting Model Files" << std::endl;
+ for (std::set<std::string>::iterator mfile = spawnedModelFiles.begin(); mfile != spawnedModelFiles.end(); ++mfile)
+ {
+ std::cout << "Converting " << *mfile << std::endl;
+ if (!convertRawFile(*mfile))
+ {
+ std::cout << "error converting " << *mfile << std::endl;
+ success = false;
+ break;
+ }
+ }
- void emptyArray(Array<ModelContainer*>& mc)
- {
- int no=mc.size();
- while(no > 0)
+ //cleanup:
+ for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end(); ++map_iter)
{
- --no;
- delete mc[no];
- mc.remove(no);
+ delete map_iter->second;
}
+ return success;
}
- //=================================================================
- bool TileAssembler::convertWorld()
+ bool TileAssembler::readMapSpawns()
{
- #ifdef _ASSEMBLER_DEBUG
- # ifdef _DEBUG
- ::g_df = fopen("../TileAssembler_debug.txt", "wb");
- # else
- ::g_df = fopen("../TileAssembler_release.txt", "wb");
- # endif
- #endif
-
- std::string fname = iSrcDir;
- fname.append("/");
- fname.append("dir");
- iCoordModelMapping->setModelNameFilterMethod(iFilterMethod);
-
- printf("Read coordinate mapping...\n");
- if(!iCoordModelMapping->readCoordinateMapping(fname))
- return false;
-
- Array<unsigned int> mapIds = iCoordModelMapping->getMaps();
- if(mapIds.size() == 0)
+ std::string fname = iSrcDir + "/dir_bin";
+ FILE *dirf = fopen(fname.c_str(), "rb");
+ if (!dirf)
{
- printf("Fatal error: empty map list!\n");
+ printf("Could not read dir_bin file!\n");
return false;
}
-
- for (int i=0; i<mapIds.size(); ++i)
+ printf("Read coordinate mapping...\n");
+ uint32 mapID, tileX, tileY, check=0;
+ G3D::Vector3 v1, v2;
+ ModelSpawn spawn;
+ while (!feof(dirf))
{
- unsigned int mapId = mapIds[i];
+ check = 0;
+ // read mapID, tileX, tileY, Flags, adtID, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
+ check += fread(&mapID, sizeof(uint32), 1, dirf);
+ if (check == 0) // EoF...
+ break;
+ check += fread(&tileX, sizeof(uint32), 1, dirf);
+ check += fread(&tileY, sizeof(uint32), 1, dirf);
+ if (!ModelSpawn::readFromFile(dirf, spawn))
+ break;
- #ifdef _ASSEMBLER_DEBUG
- if(mapId == 0) // "Azeroth" just for debug
+ MapSpawns *current;
+ MapData::iterator map_iter = mapData.find(mapID);
+ if (map_iter == mapData.end())
{
- for (int x=28; x<29; ++x) //debug
- {
- for (int y=28; y<29; ++y)
- {
- #else
- // ignore DeeprunTram (369) it is too large for short vector and not important
- // ignore test (13), Test (29) , development (451)
- if(mapId != 369 && mapId != 13 && mapId != 29 && mapId != 451)
- {
- for (int x=0; x<66; ++x)
- {
- for (int y=0; y<66; ++y)
- {
- #endif
- Array<ModelContainer*> mc;
- std::string dirname;
- char buffer[100];
- if(iCoordModelMapping->isWorldAreaMap(mapId) && x<65 && y<65)
- {
- sprintf(buffer, "%03u_%d_%d",mapId,y,x); // Let's flip x and y here
- dirname = std::string(buffer);
- printf("%s...\n",dirname.c_str());
- }
- else
- {
- sprintf(buffer, "%03u",mapId);
- dirname = std::string(buffer);
-
- // prevent spam for small maps
- if(x==0 && y==0)
- printf("%s...\n",dirname.c_str());
- }
-
- bool result = fillModelContainerArray(dirname, mapId, x, y, mc);
- emptyArray(mc);
-
- if(!result)
- return false;
- }
- }
+ printf("spawning Map %d\n", mapID);
+ mapData[mapID] = current = new MapSpawns();
}
+ else current = (*map_iter).second;
+ current->UniqueEntries.insert(pair<uint32, ModelSpawn>(spawn.ID, spawn));
+ current->TileEntries.insert(pair<uint32, uint32>(StaticMapTree::packTileID(tileX, tileY), spawn.ID));
}
- #ifdef _ASSEMBLER_DEBUG
- if(::g_df) fclose(::g_df);
- #endif
-
- return true;
+ bool success = (ferror(dirf) == 0);
+ fclose(dirf);
+ return success;
}
- //=================================================================
-
- bool TileAssembler::fillModelContainerArray(const std::string& pDirFileName, unsigned int pMapId, int pXPos, int pYPos, Array<ModelContainer*>& pMC)
+ bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
{
- ModelContainer* modelContainer;
-
- NameCollection nameCollection = iCoordModelMapping->getFilenamesForCoordinate(pMapId, pXPos, pYPos);
- if(nameCollection.size() == 0)
- return true; // no data...
+ std::string modelFilename = iSrcDir + "/" + spawn.name;
+ ModelPosition modelPosition;
+ modelPosition.iDir = spawn.iRot;
+ modelPosition.iScale = spawn.iScale;
+ modelPosition.init();
- char dirfilename[500];
- sprintf(dirfilename,"%s/%s.vmdir",iDestDir.c_str(),pDirFileName.c_str());
- FILE *dirfile = fopen(dirfilename, "ab");
- if(!dirfile)
+ FILE *rf = fopen(modelFilename.c_str(), "rb");
+ if (!rf)
{
- printf("ERROR: Can't create file %s",dirfilename);
+ printf("ERROR: Can't open model file: %s\n", modelFilename.c_str());
return false;
}
- char destnamebuffer[500];
- char fullnamedestnamebuffer[500];
-
- if(nameCollection.iMainFiles.size() >0)
- {
- sprintf(destnamebuffer,"%03u_%i_%i.vmap",pMapId, pYPos, pXPos); // flip it here too
- std::string checkDoubleStr = std::string(dirfilename);
- checkDoubleStr.append("##");
- checkDoubleStr.append(std::string(destnamebuffer));
- // Check, if same file already is in the same dir file
- if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr))
- {
- iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr);
- fprintf(dirfile, "%s\n",destnamebuffer);
- sprintf(fullnamedestnamebuffer,"%s/%s",iDestDir.c_str(),destnamebuffer);
- modelContainer = processNames(nameCollection.iMainFiles, fullnamedestnamebuffer);
- if(modelContainer)
- pMC.append(modelContainer);
- else
- printf("warning: (if) problems in processing data for %s\n",destnamebuffer);
- }
- }
- // process the large singe files
- int pos = 0;
- while(pos < nameCollection.iSingeFiles.size())
- {
- std::string destFileName = iDestDir;
- destFileName.append("/");
- std::string dirEntryName = getDirEntryNameFromModName(pMapId,nameCollection.iSingeFiles[pos]);
- std::string checkDoubleStr = std::string(dirfilename);
- checkDoubleStr.append("##");
- checkDoubleStr.append(nameCollection.iSingeFiles[pos]);
- // Check, if same file already is in the same dir file
- if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr))
- {
- iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr);
- fprintf(dirfile, "%s\n",dirEntryName.c_str());
- destFileName.append(dirEntryName);
+ AABox modelBound;
+ bool boundEmpty=true;
+ char ident[8];
- Array<std::string> positionarray;
- positionarray.append(nameCollection.iSingeFiles[pos]);
+ int readOperation = 1;
- if(!iCoordModelMapping->isAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos]))
- {
- modelContainer = processNames(positionarray, destFileName.c_str());
- iCoordModelMapping->addAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos]);
- if(modelContainer)
- pMC.append(modelContainer);
- else
- printf("warning: (while) problems in processing data for %s\n",destFileName.c_str());
- }
- }
- ++pos;
- }
+ // temporary use defines to simplify read/check code (close file and return at fail)
+ #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
+ fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }readOperation++;
+ #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
+ fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
- fclose(dirfile);
- return true;
- }
+ READ_OR_RETURN(&ident, 8);
+ CMP_OR_RETURN(ident, "VMAP003");
- //=================================================================
+ // we have to read one int. This is needed during the export and we have to skip it here
+ uint32 tempNVectors;
+ READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors));
- void removeEntriesFromTree(AABSPTree<SubModel *>* pTree)
- {
- Array<SubModel *> submodelArray;
- pTree->getMembers(submodelArray);
- int no = submodelArray.size();
- while(no > 0)
- {
- --no;
- delete submodelArray[no];
- }
- }
+ uint32 groups, wmoRootId;
+ char blockId[5];
+ blockId[4] = 0;
+ int blocksize;
+ float *vectorarray = 0;
- //=================================================================
+ READ_OR_RETURN(&groups, sizeof(uint32));
+ READ_OR_RETURN(&wmoRootId, sizeof(uint32));
+ if (groups != 1) printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
- ModelContainer* TileAssembler::processNames(const Array<std::string>& pPositions, const char* pDestFileName)
- {
- ModelContainer *modelContainer = 0;
+ for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
+ {
+ fseek(rf, 3*sizeof(uint32) + 6*sizeof(float), SEEK_CUR);
- Vector3 basepos = Vector3(0,0,0);
- AABSPTree<SubModel *>* mainTree = new AABSPTree<SubModel *>();
+ READ_OR_RETURN(&blockId, 4);
+ CMP_OR_RETURN(blockId, "GRP ");
+ READ_OR_RETURN(&blocksize, sizeof(int));
+ fseek(rf, blocksize, SEEK_CUR);
- int pos = 0;
+ // ---- indexes
+ READ_OR_RETURN(&blockId, 4);
+ CMP_OR_RETURN(blockId, "INDX");
+ READ_OR_RETURN(&blocksize, sizeof(int));
+ fseek(rf, blocksize, SEEK_CUR);
- bool result = true;
- while(result && (pos < pPositions.size()))
- {
- std::string modelPosString = pPositions[pos];
- std::string modelFileName = getModNameFromModPosName(modelPosString);
+ // ---- vectors
+ READ_OR_RETURN(&blockId, 4);
+ CMP_OR_RETURN(blockId, "VERT");
+ READ_OR_RETURN(&blocksize, sizeof(int));
+ uint32 nvectors;
+ READ_OR_RETURN(&nvectors, sizeof(uint32));
- if(!fillModelIntoTree(mainTree, basepos, modelPosString, modelFileName))
+ if (nvectors >0)
{
- result = false;
- break;
+ vectorarray = new float[nvectors*3];
+ READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3);
+ }
+ else
+ {
+ std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
+ return false;
}
- ++pos;
- }
- if(result && mainTree->size() > 0)
- {
- mainTree->balance();
- modelContainer = new ModelContainer(mainTree);
- modelContainer->writeFile(pDestFileName);
- }
- removeEntriesFromTree(mainTree);
- delete mainTree;
+ for (uint32 i=0, indexNo=0; indexNo<nvectors; indexNo++, i+=3)
+ {
+ Vector3 v = Vector3(vectorarray[i+0], vectorarray[i+1], vectorarray[i+2]);
+ v = modelPosition.transform(v);
- return(modelContainer);
+ if (boundEmpty)
+ modelBound = AABox(v, v), boundEmpty=false;
+ else
+ modelBound.merge(v);
+ }
+ delete[] vectorarray;
+ // drop of temporary use defines
+ #undef READ_OR_RETURN
+ #undef CMP_OR_RETURN
+ }
+ spawn.iBound = modelBound + spawn.iPos;
+ spawn.flags |= MOD_HAS_BOUND;
+ fclose(rf);
+ return true;
}
+ struct WMOLiquidHeader
+ {
+ int xverts, yverts, xtiles, ytiles;
+ float pos_x;
+ float pos_y;
+ float pos_z;
+ short type;
+ };
//=================================================================
- bool TileAssembler::readRawFile(std::string& pModelFilename, ModelPosition& pModelPosition, AABSPTree<SubModel *> *pMainTree)
+ bool TileAssembler::convertRawFile(const std::string& pModelFilename)
{
+ bool success = true;
std::string filename = iSrcDir;
- if(filename.length() >0)
+ if (filename.length() >0)
filename.append("/");
filename.append(pModelFilename);
FILE *rf = fopen(filename.c_str(), "rb");
- if(!rf)
- {
- // depending on the extractor version, the data could be located in the root dir
- std::string baseModelFilename = pModelFilename.substr((pModelFilename.find_first_of("/")+1),pModelFilename.length());
- filename = iSrcDir;
- if(filename.length() >0)
- filename.append("/");
- filename.append(baseModelFilename);
- rf = fopen(filename.c_str(), "rb");
- }
- if(!rf)
+ if (!rf)
{
printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str());
printf("... or form: %s",filename.c_str() );
@@ -379,95 +363,74 @@ namespace VMAP
char ident[8];
- int trianglecount =0;
-
- #ifdef _ASSEMBLER_DEBUG
- int startgroup = 0; //2;
- int endgroup = INT_MAX; //2;
- fprintf(::g_df,"-------------------------------------------------\n");
- fprintf(::g_df,"%s\n", pModelFilename.c_str());
- fprintf(::g_df,"-------------------------------------------------\n");
- #else
- int startgroup = 0;
- int endgroup = INT_MAX;
- #endif
+ int readOperation = 1;
// temporary use defines to simplify read/check code (close file and return at fail)
#define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
- fclose(rf); return(false); }
+ fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }readOperation++;
#define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
- fclose(rf); return(false); }
+ fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
READ_OR_RETURN(&ident, 8);
- if(strcmp(ident, "VMAP001") == 0)
- {
- // OK, do nothing
- }
- else if(strcmp(ident, "VMAP002") == 0)
- {
- // we have to read one int. This is needed during the export and we have to skip it here
- int tempNVectors;
- READ_OR_RETURN(&tempNVectors, sizeof(int));
+ CMP_OR_RETURN(ident, "VMAP003");
- }
- else
- {
- // wrong version
- fclose(rf);
- return(false);
- }
- G3D::uint32 groups;
+ // we have to read one int. This is needed during the export and we have to skip it here
+ uint32 tempNVectors;
+ READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors));
+
+ uint32 groups;
+ uint32 RootWMOID;
char blockId[5];
blockId[4] = 0;
int blocksize;
- READ_OR_RETURN(&groups, sizeof(G3D::uint32));
+ READ_OR_RETURN(&groups, sizeof(uint32));
+ READ_OR_RETURN(&RootWMOID, sizeof(uint32));
- for (int g=0; g<(int)groups; g++)
+ std::vector<GroupModel> groupsArray;
+
+ for (uint32 g=0; g<groups; ++g)
{
- // group MUST NOT have more then 65536 indexes !! Array will have a problem with that !! (strange ...)
- Array<int> tempIndexArray;
- Array<Vector3> tempVertexArray;
+ std::vector<MeshTriangle> triangles;
+ std::vector<Vector3> vertexArray;
- AABSPTree<Triangle> *gtree = new AABSPTree<Triangle>();
+ uint32 mogpflags, GroupWMOID;
+ READ_OR_RETURN(&mogpflags, sizeof(uint32));
+ READ_OR_RETURN(&GroupWMOID, sizeof(uint32));
- // add free gtree at fail
- #undef READ_OR_RETURN
- #undef CMP_OR_RETURN
- #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
- fclose(rf); delete gtree; return(false); }
- #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
- fclose(rf); delete gtree; return(false); }
+ float bbox1[3], bbox2[3];
+ READ_OR_RETURN(bbox1, sizeof(float)*3);
+ READ_OR_RETURN(bbox2, sizeof(float)*3);
- G3D::uint32 flags;
- READ_OR_RETURN(&flags, sizeof(G3D::uint32));
+ uint32 liquidflags;
+ READ_OR_RETURN(&liquidflags, sizeof(uint32));
- G3D::uint32 branches;
+ // will this ever be used? what is it good for anyway??
+ uint32 branches;
READ_OR_RETURN(&blockId, 4);
CMP_OR_RETURN(blockId, "GRP ");
READ_OR_RETURN(&blocksize, sizeof(int));
- READ_OR_RETURN(&branches, sizeof(G3D::uint32));
- for (int b=0; b<(int)branches; b++)
+ READ_OR_RETURN(&branches, sizeof(uint32));
+ for (uint32 b=0; b<branches; ++b)
{
- G3D::uint32 indexes;
+ uint32 indexes;
// indexes for each branch (not used jet)
- READ_OR_RETURN(&indexes, sizeof(G3D::uint32));
+ READ_OR_RETURN(&indexes, sizeof(uint32));
}
// ---- indexes
READ_OR_RETURN(&blockId, 4);
CMP_OR_RETURN(blockId, "INDX");
READ_OR_RETURN(&blocksize, sizeof(int));
- unsigned int nindexes;
- READ_OR_RETURN(&nindexes, sizeof(G3D::uint32));
- if(nindexes >0)
+ uint32 nindexes;
+ READ_OR_RETURN(&nindexes, sizeof(uint32));
+ if (nindexes >0)
{
- unsigned short *indexarray = new unsigned short[nindexes*sizeof(unsigned short)];
- READ_OR_RETURN(indexarray, nindexes*sizeof(unsigned short));
- for (int i=0; i<(int)nindexes; i++)
+ uint16 *indexarray = new uint16[nindexes];
+ READ_OR_RETURN(indexarray, nindexes*sizeof(uint16));
+ for (uint32 i=0; i<nindexes; i+=3)
{
- unsigned short val = indexarray[i];
- tempIndexArray.append(val);
+ triangles.push_back(MeshTriangle(indexarray[i], indexarray[i+1], indexarray[i+2]));
}
delete[] indexarray;
}
@@ -476,127 +439,56 @@ namespace VMAP
READ_OR_RETURN(&blockId, 4);
CMP_OR_RETURN(blockId, "VERT");
READ_OR_RETURN(&blocksize, sizeof(int));
- unsigned int nvectors;
- READ_OR_RETURN(&nvectors, sizeof(int));
-
- float *vectorarray = 0;
-
- // add vectorarray free
- #undef READ_OR_RETURN
- #undef CMP_OR_RETURN
- #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
- fclose(rf); delete gtree; delete[] vectorarray; return(false); }
- #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
- fclose(rf); delete gtree; delete[] vectorarray; return(false); }
+ uint32 nvectors;
+ READ_OR_RETURN(&nvectors, sizeof(uint32));
- if(nvectors >0)
+ if (nvectors >0)
{
- vectorarray = new float[nvectors*sizeof(float)*3];
+ float *vectorarray = new float[nvectors*3];
READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3);
+ for (uint32 i=0; i<nvectors; ++i)
+ {
+ vertexArray.push_back( Vector3(vectorarray + 3*i) );
+ }
+ delete[] vectorarray;
}
- // ----- liquit
- if(flags & 1)
+ // ----- liquid
+ WmoLiquid *liquid = 0;
+ if (liquidflags& 1)
{
- // we have liquit -> not handled yet ... skip
+ WMOLiquidHeader hlq;
READ_OR_RETURN(&blockId, 4);
CMP_OR_RETURN(blockId, "LIQU");
READ_OR_RETURN(&blocksize, sizeof(int));
- fseek(rf, blocksize, SEEK_CUR);
+ READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader));
+ liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type);
+ uint32 size = hlq.xverts*hlq.yverts;
+ READ_OR_RETURN(liquid->GetHeightStorage(), size*sizeof(float));
+ size = hlq.xtiles*hlq.ytiles;
+ READ_OR_RETURN(liquid->GetFlagsStorage(), size);
}
- for (unsigned int i=0, indexNo=0; indexNo<nvectors; indexNo++)
- {
- Vector3 v = Vector3(vectorarray[i+2], vectorarray[i+1], vectorarray[i+0]);
- i+=3;
- v = pModelPosition.transform(v);
-
- float swapy = v.y;
- v.y = v.x;
- v.x = swapy;
-
- tempVertexArray.append(v);
- }
-
- // ---- calculate triangles
- int rest = nindexes%3;
- if(rest != 0)
- {
- nindexes -= rest;
- }
-
- for (unsigned int i=0; i<(nindexes);)
- {
- Triangle t = Triangle(tempVertexArray[tempIndexArray[i+2]], tempVertexArray[tempIndexArray[i+1]], tempVertexArray[tempIndexArray[i+0]] );
- i+=3;
- ++trianglecount;
- if(g>= startgroup && g <= endgroup)
- {
- gtree->insert(t);
- }
- }
+ groupsArray.push_back(GroupModel(mogpflags, GroupWMOID, AABox(Vector3(bbox1), Vector3(bbox2))));
+ groupsArray.back().setMeshData(vertexArray, triangles);
+ groupsArray.back().setLiquidData(liquid);
// drop of temporary use defines
#undef READ_OR_RETURN
#undef CMP_OR_RETURN
- if(vectorarray != 0)
- {
- delete[] vectorarray;
- }
-
- if(gtree->size() >0)
- {
- gtree->balance();
- SubModel *sm = new SubModel(gtree);
- #ifdef _ASSEMBLER_DEBUG
- if(::g_df) fprintf(::g_df,"group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size());
- if(sm->getNTriangles() != gtree->memberTable.size())
- {
- if(::g_df) fprintf(::g_df,"ERROR !!!! group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size());
- }
- #endif
- sm->setBasePosition(pModelPosition.iPos);
- pMainTree->insert(sm);
- }
- delete gtree;
}
fclose(rf);
- return true;
- }
-
- //=================================================================
-
- bool TileAssembler::fillModelIntoTree(AABSPTree<SubModel *> *pMainTree, const Vector3& pBasePos, std::string& pPos, std::string& pModelFilename)
- {
- ModelPosition modelPosition;
- getModelPosition(pPos, modelPosition);
- // all should be relative to object base position
- modelPosition.moveToBasePos(pBasePos);
- modelPosition.init();
-
- return readRawFile(pModelFilename, modelPosition, pMainTree);
- }
-
- //=================================================================
- void TileAssembler::getModelPosition(std::string& pPosString, ModelPosition& pModelPosition)
- {
- float vposarray[3];
- float vdirarray[3];
- float scale;
-
- size_t spos = pPosString.find_first_of('#');
- std::string stripedPosString = pPosString.substr(spos+1,pPosString.length());
-
- sscanf(stripedPosString.c_str(), "%f,%f,%f_%f,%f,%f_%f",
- &vposarray[0],&vposarray[1],&vposarray[2],
- &vdirarray[0],&vdirarray[1],&vdirarray[2],
- &scale);
-
- pModelPosition.iPos = Vector3(vposarray[0], vposarray[1], vposarray[2]);
- pModelPosition.iDir = Vector3(vdirarray[0], vdirarray[1], vdirarray[2]);
- pModelPosition.iScale = scale;
+ // write WorldModel
+ WorldModel model;
+ model.setRootWmoID(RootWMOID);
+ if (groupsArray.size())
+ {
+ model.setGroupModels(groupsArray);
+ success = model.writeFile(iDestDir + "/" + pModelFilename + ".vmo");
+ }
+ //std::cout << "readRawFile2: '" << pModelFilename << "' tris: " << nElements << " nodes: " << nNodes << std::endl;
+ return success;
}
- //==========================================
-} // VMAP
+}
diff --git a/src/shared/vmap/TileAssembler.h b/src/shared/vmap/TileAssembler.h
index aa21a93dd1a..b26735708af 100644
--- a/src/shared/vmap/TileAssembler.h
+++ b/src/shared/vmap/TileAssembler.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
@@ -10,25 +8,22 @@
*
* 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _TILEASSEMBLER_H_
#define _TILEASSEMBLER_H_
-// load our modified version first !!
-#include "AABSPTree.h"
-
#include <G3D/Vector3.h>
+#include <G3D/Matrix3.h>
+#include <map>
-#include "CoordModelMapping.h"
-#include "SubModel.h"
-#include "ModelContainer.h"
+#include "ModelInstance.h"
namespace VMAP
{
@@ -41,56 +36,54 @@ namespace VMAP
class ModelPosition
{
private:
- G3D::Matrix3 ixMatrix;
- G3D::Matrix3 iyMatrix;
- G3D::Matrix3 izMatrix;
+ G3D::Matrix3 iRotation;
public:
G3D::Vector3 iPos;
G3D::Vector3 iDir;
float iScale;
void init()
{
-
- // Swap x and y the raw data uses the axis differently
- ixMatrix = G3D::Matrix3::fromAxisAngle(G3D::Vector3::unitY(),-(G3D::pi()*iDir.x/180.0));
- iyMatrix = G3D::Matrix3::fromAxisAngle(G3D::Vector3::unitX(),-(G3D::pi()*iDir.y/180.0));
- izMatrix = G3D::Matrix3::fromAxisAngle(G3D::Vector3::unitZ(),-(G3D::pi()*iDir.z/180.0));
-
+ iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iDir.y/180.f, G3D::pi()*iDir.x/180.f, G3D::pi()*iDir.z/180.f);
}
G3D::Vector3 transform(const G3D::Vector3& pIn) const;
void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; }
};
+
+ typedef std::map<uint32, ModelSpawn> UniqueEntryMap;
+ typedef std::multimap<uint32, uint32> TileMap;
+
+ struct MapSpawns
+ {
+ UniqueEntryMap UniqueEntries;
+ TileMap TileEntries;
+ };
+
+ typedef std::map<uint32, MapSpawns*> MapData;
//===============================================
class TileAssembler
{
private:
- CoordModelMapping *iCoordModelMapping;
std::string iDestDir;
std::string iSrcDir;
bool (*iFilterMethod)(char *pName);
G3D::Table<std::string, unsigned int > iUniqueNameIds;
unsigned int iCurrentUniqueNameId;
+ MapData mapData;
public:
TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
virtual ~TileAssembler();
- bool fillModelContainerArray(const std::string& pDirFileName, unsigned int pMapId, int pXPos, int pYPos, G3D::Array<ModelContainer*>& pMC);
- ModelContainer* processNames(const G3D::Array<std::string>& pPosFileNames, const char* pDestFileName);
-
- void init();
- bool convertWorld();
+ bool convertWorld2();
+ bool readMapSpawns();
+ bool calculateTransformedBound(ModelSpawn &spawn);
- bool fillModelIntoTree(G3D::AABSPTree<SubModel *> *pMainTree, const G3D::Vector3& pBasePos, std::string& pPosFilename, std::string& pModelFilename);
- void getModelPosition(std::string& pPosString, ModelPosition& pModelPosition);
- bool readRawFile(std::string& pModelFilename, ModelPosition& pModelPosition, G3D::AABSPTree<SubModel *> *pMainTree);
- void addWorldAreaMapId(unsigned int pMapId) { iCoordModelMapping->addWorldAreaMap(pMapId); }
+ bool convertRawFile(const std::string& pModelFilename);
void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
unsigned int getUniqueNameId(const std::string pName);
};
- //===============================================
+
} // VMAP
#endif /*_TILEASSEMBLER_H_*/
-
diff --git a/src/shared/vmap/TreeNode.cpp b/src/shared/vmap/TreeNode.cpp
deleted file mode 100644
index e3edb2fe087..00000000000
--- a/src/shared/vmap/TreeNode.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include "TreeNode.h"
-
-using namespace G3D;
-
-namespace VMAP
-{
-
- TreeNode const* TreeNode::getChild(TreeNode const* pValueArray,int pNo) const
- {
- if(iChilds[pNo] != -1)
- return(&pValueArray[iChilds[pNo]]);
- else
- return(NULL);
- }
-
- //=================================================================
- //=================================================================
- //=================================================================
-}
-
diff --git a/src/shared/vmap/TreeNode.h b/src/shared/vmap/TreeNode.h
deleted file mode 100644
index 2aa943573da..00000000000
--- a/src/shared/vmap/TreeNode.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
-* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
-*
-* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _TREENODE_H
-#define _TREENODE_H
-
-#include "ShortVector.h"
-#include "ShortBox.h"
-#include "NodeValueAccess.h"
-#include "VMapTools.h"
-
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-
-namespace VMAP
-{
- /**
- This Class is mainly taken from G3D/AABSPTree.h and modified to match our data structure.
- It is the node within our static BSP-Trees.
- It does not use pointers but indexes to access the values and other nodes.
- */
-
- //=====================================================
-
- class TreeNode
- {
- private:
- /** Location along the specified axis */
- float iSplitLocation;
- // Offest or the clients
- int iChilds[2];
- //Position within the TriangleBox array
- unsigned int iStartPosition;
- G3D::Vector3::Axis iSplitAxis;
- G3D::AABox iBounds;
- unsigned short iNumberOfValues;
- public:
- TreeNode() {}
- TreeNode(unsigned short pNValues, unsigned int pStartPosition)
- {
- iChilds[0] = -1;
- iChilds[1] = -1;
- iStartPosition = pStartPosition;
- iNumberOfValues = pNValues;
- }
-
- bool hasChilds() const { return(iChilds[0] >= 0 || iChilds[1] >= 0); }
-
- TreeNode const* getChild(TreeNode const* pValueArray, int pNo) const;
- // pChildNo = 0 or 1
- inline void setChildPos(int pChildNo, int pChildPosInTreeNodeArray) { iChilds[pChildNo] = pChildPosInTreeNodeArray; }
-
- inline G3D::Vector3::Axis getSplitAxis() const { return(iSplitAxis); }
-
- inline void setSplitAxis(G3D::Vector3::Axis a) { iSplitAxis = a; }
- inline void setSplitLocation(float l) { iSplitLocation = l; }
-
- inline void setBounds(const G3D::AABox& pBox) { iBounds = pBox; }
-
- inline void setBounds(const G3D::Vector3& lo, const G3D::Vector3& hi) { iBounds.set(lo,hi); }
-
- inline void getBounds(G3D::AABox& pBox) const { pBox.set(iBounds.low(),iBounds.high()); }
-
- inline float getSplitLocation() const { return(iSplitLocation); }
-
- inline unsigned short getNValues() const { return (iNumberOfValues); }
-
- inline unsigned int getStartPosition() const { return(iStartPosition); }
-
- inline bool operator==(const TreeNode& n) const
- {
- return ((iSplitLocation == n.iSplitLocation) &&
- (iChilds[0] == n.iChilds[0]) && (iChilds[1] == n.iChilds[1]) &&
- (iStartPosition == n.iStartPosition) &&
- (iSplitAxis == n.iSplitAxis) &&
- (iBounds == n.iBounds) &&
- (iNumberOfValues == n.iNumberOfValues));
- }
-
- inline bool operator!=(const TreeNode& n) const
- {
- return !((iSplitLocation == n.iSplitLocation) &&
- (iChilds[0] == n.iChilds[0]) && (iChilds[1] == n.iChilds[1]) &&
- (iStartPosition == n.iStartPosition) &&
- (iSplitAxis == n.iSplitAxis) &&
- (iBounds == n.iBounds) &&
- (iNumberOfValues == n.iNumberOfValues));
- }
-
- /** Returns true if the ray intersects this node */
- bool intersects(const G3D::Ray& ray, float distance) const {
- // See if the ray will ever hit this node or its children
- G3D::Vector3 location;
- bool alreadyInsideBounds = false;
- bool rayWillHitBounds =
- MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
- ray.origin, ray.direction, iBounds, location, alreadyInsideBounds);
-
- bool canHitThisNode = (alreadyInsideBounds ||
- (rayWillHitBounds && ((location - ray.origin).squaredLength() < (distance*distance))));
-
- return canHitThisNode;
- }
-
- template<typename RayCallback, typename TNode, typename TValue>
- void intersectRay(
- const G3D::Ray& ray,
- RayCallback& intersectCallback,
- float& distance,
- const NodeValueAccess<TNode, TValue>& pNodeValueAccess,
- bool pStopAtFirstHit,
- bool intersectCallbackIsFast) const {
- float enterDistance = distance;
- if (! intersects(ray, distance)) {
- // The ray doesn't hit this node, so it can't hit the children of the node.
- return;
- }
-
- // Test for intersection against every object at this node.
- for (unsigned int v = iStartPosition; v < (iNumberOfValues+iStartPosition); ++v) {
- const TValue& nodeValue = pNodeValueAccess.getValue(v);
- bool canHitThisObject = true;
- if (! intersectCallbackIsFast) {
- // See if
- G3D::Vector3 location;
- const G3D::AABox& bounds = nodeValue.getAABoxBounds();
- bool alreadyInsideBounds = false;
- bool rayWillHitBounds =
- MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
- ray.origin, ray.direction, bounds, location, alreadyInsideBounds);
-
- canHitThisObject = (alreadyInsideBounds ||
- (rayWillHitBounds && ((location - ray.origin).squaredLength() < (distance*distance))));
- }
-
- if (canHitThisObject) {
- // It is possible that this ray hits this object. Look for the intersection using the
- // callback.
- intersectCallback(ray, &nodeValue, pStopAtFirstHit, distance);
- }
- if(pStopAtFirstHit && distance < enterDistance)
- return;
- }
-
- // There are three cases to consider next:
- //
- // 1. the ray can start on one side of the splitting plane and never enter the other,
- // 2. the ray can start on one side and enter the other, and
- // 3. the ray can travel exactly down the splitting plane
-
- enum {NONE = -1};
- int firstChild = NONE;
- int secondChild = NONE;
-
- if (ray.origin[iSplitAxis] < iSplitLocation) {
-
- // The ray starts on the small side
- firstChild = 0;
-
- if (ray.direction[iSplitAxis] > 0) {
- // The ray will eventually reach the other side
- secondChild = 1;
- }
-
- } else if (ray.origin[iSplitAxis] > iSplitLocation) {
-
- // The ray starts on the large side
- firstChild = 1;
-
- if (ray.direction[iSplitAxis] < 0) {
- secondChild = 0;
- }
- } else {
- // The ray starts on the splitting plane
- if (ray.direction[iSplitAxis] < 0) {
- // ...and goes to the small side
- firstChild = 0;
- } else if (ray.direction[iSplitAxis] > 0) {
- // ...and goes to the large side
- firstChild = 1;
- }
- }
-
- // Test on the side closer to the ray origin.
- if ((firstChild != NONE) && iChilds[firstChild]>0) {
- getChild(pNodeValueAccess.getNodePtr() , firstChild)->intersectRay(ray, intersectCallback, distance, pNodeValueAccess, pStopAtFirstHit,intersectCallbackIsFast);
- if(pStopAtFirstHit && distance < enterDistance)
- return;
- }
- if (ray.direction[iSplitAxis] != 0) {
- // See if there was an intersection before hitting the splitting plane.
- // If so, there is no need to look on the far side and recursion terminates.
- float distanceToSplittingPlane = (iSplitLocation - ray.origin[iSplitAxis]) / ray.direction[iSplitAxis];
- if (distanceToSplittingPlane > distance) {
- // We aren't going to hit anything else before hitting the splitting plane,
- // so don't bother looking on the far side of the splitting plane at the other
- // child.
- return;
- }
- }
- // Test on the side farther from the ray origin.
- if ((secondChild != NONE) && iChilds[secondChild]>0) {
- getChild(pNodeValueAccess.getNodePtr() , secondChild)->intersectRay(ray, intersectCallback, distance, pNodeValueAccess, pStopAtFirstHit,intersectCallbackIsFast);
- }
- }
- };
-}
-#endif
-
diff --git a/src/shared/vmap/VMapDefinitions.h b/src/shared/vmap/VMapDefinitions.h
index 51743782526..e4a34cc1397 100644
--- a/src/shared/vmap/VMapDefinitions.h
+++ b/src/shared/vmap/VMapDefinitions.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
@@ -10,31 +8,35 @@
*
* 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _VMAPDEFINITIONS_H
#define _VMAPDEFINITIONS_H
#include <cstring>
+#define LIQUID_TILE_SIZE (533.333f / 128.f)
+
namespace VMAP
{
//=====================================
- #define MAX_CAN_FALL_DISTANCE 10.0
- const char VMAP_MAGIC[] = "VMAP_2.0";
+ #define MAX_CAN_FALL_DISTANCE 10.0f
+ const char VMAP_MAGIC[] = "VMAP_3.0";
class VMapDefinitions
{
public:
- static const double getMaxCanFallDistance() { return(MAX_CAN_FALL_DISTANCE); }
+ static float getMaxCanFallDistance() { return MAX_CAN_FALL_DISTANCE; }
};
//======================================
+
+ // defined in TileAssembler.cpp currently...
+ bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len);
}
#endif
-
diff --git a/src/shared/vmap/VMapFactory.cpp b/src/shared/vmap/VMapFactory.cpp
index 2c5cd19d5dd..331acbace47 100644
--- a/src/shared/vmap/VMapFactory.cpp
+++ b/src/shared/vmap/VMapFactory.cpp
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
@@ -10,25 +8,51 @@
*
* 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/types.h>
#include "VMapFactory.h"
-#include "VMapManager.h"
+#include "VMapManager2.h"
using namespace G3D;
namespace VMAP
{
- extern void chompAndTrim(std::string& str);
+ void chompAndTrim(std::string& str)
+ {
+ while(str.length() >0)
+ {
+ char lc = str[str.length()-1];
+ if(lc == '\r' || lc == '\n' || lc == ' ' || lc == '"' || lc == '\'')
+ {
+ str = str.substr(0,str.length()-1);
+ }
+ else
+ {
+ break;
+ }
+ }
+ while(str.length() >0)
+ {
+ char lc = str[0];
+ if(lc == ' ' || lc == '"' || lc == '\'')
+ {
+ str = str.substr(1,str.length()-1);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
- VMapManager *gVMapManager = 0;
+ IVMapManager *gVMapManager = 0;
Table<unsigned int , bool>* iIgnoreSpellIds=0;
//===============================================
@@ -38,7 +62,7 @@ namespace VMAP
{
bool result = false;
unsigned int i;
- for (i=pStartPos; i<pString.size(); ++i)
+ for(i=pStartPos;i<pString.size(); ++i)
{
if(pString[i] == ',')
{
@@ -90,7 +114,7 @@ namespace VMAP
IVMapManager* VMapFactory::createOrGetVMapManager()
{
if(gVMapManager == 0)
- gVMapManager= new VMapManager(); // should be taken from config ... Please change if you like :-)
+ gVMapManager= new VMapManager2(); // should be taken from config ... Please change if you like :-)
return gVMapManager;
}
@@ -110,4 +134,3 @@ namespace VMAP
}
}
}
-
diff --git a/src/shared/vmap/VMapFactory.h b/src/shared/vmap/VMapFactory.h
index fa015841f8d..8dc2c01938a 100644
--- a/src/shared/vmap/VMapFactory.h
+++ b/src/shared/vmap/VMapFactory.h
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
@@ -10,12 +8,12 @@
*
* 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _VMAPFACTORY_H
@@ -43,4 +41,3 @@ namespace VMAP
}
#endif
-
diff --git a/src/shared/vmap/VMapManager.cpp b/src/shared/vmap/VMapManager.cpp
deleted file mode 100644
index 4c651484616..00000000000
--- a/src/shared/vmap/VMapManager.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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
- */
-
-#include "VMapManager.h"
-#include "VMapDefinitions.h"
-
-using namespace G3D;
-
-namespace VMAP
-{
-
- //=========================================================
-
- VMapManager::VMapManager()
- {
-#ifdef _VMAP_LOG_DEBUG
- iCommandLogger.setFileName("vmapcmd.log");
- iCommandLogger.setResetFile();
-#endif
- }
-
- //=========================================================
-
- VMapManager::~VMapManager(void)
- {
- Array<unsigned int > keyArray = iInstanceMapTrees.getKeys();
- for (int i=0; i<keyArray.size(); ++i)
- {
- delete iInstanceMapTrees.get(keyArray[i]);
- iInstanceMapTrees.remove(keyArray[i]);
- }
- }
-
- //=========================================================
-
- Vector3 VMapManager::convertPositionToInternalRep(float x, float y, float z) const
- {
- float pos[3];
- pos[0] = y;
- pos[1] = z;
- pos[2] = x;
- double full = 64.0*533.33333333;
- double mid = full/2.0;
- pos[0] = full- (pos[0] + mid);
- pos[2] = full- (pos[2] + mid);
-
- return(Vector3(pos));
- }
-
- //=========================================================
-
- Vector3 VMapManager::convertPositionToTrinityRep(float x, float y, float z) const
- {
- float pos[3];
- pos[0] = z;
- pos[1] = x;
- pos[2] = y;
- double full = 64.0*533.33333333;
- double mid = full/2.0;
- pos[0] = -((mid+pos[0])-full);
- pos[1] = -((mid+pos[1])-full);
-
- return(Vector3(pos));
- }
- //=========================================================
-
- std::string VMapManager::getDirFileName(unsigned int pMapId, int x, int y) const
- {
- char name[FILENAMEBUFFER_SIZE];
-
- sprintf(name, "%03u_%d_%d%s",pMapId, x, y, DIR_FILENAME_EXTENSION);
- return(std::string(name));
- }
-
- //=========================================================
- std::string VMapManager::getDirFileName(unsigned int pMapId) const
- {
- char name[FILENAMEBUFFER_SIZE];
-
- sprintf(name, "%03d%s",pMapId, DIR_FILENAME_EXTENSION);
- return(std::string(name));
- }
- //=========================================================
- // remote last return or LF
- void chomp(std::string& str)
- {
- while(str.length() >0)
- {
- char lc = str[str.length()-1];
- if(lc == '\r' || lc == '\n')
- {
- str = str.substr(0,str.length()-1);
- }
- else
- {
- break;
- }
- }
- }
- //=========================================================
-
- void chompAndTrim(std::string& str)
- {
- while(str.length() >0)
- {
- char lc = str[str.length()-1];
- if(lc == '\r' || lc == '\n' || lc == ' ' || lc == '"' || lc == '\'')
- {
- str = str.substr(0,str.length()-1);
- }
- else
- {
- break;
- }
- }
- while(str.length() >0)
- {
- char lc = str[0];
- if(lc == ' ' || lc == '"' || lc == '\'')
- {
- str = str.substr(1,str.length()-1);
- }
- else
- {
- break;
- }
- }
- }
-
- //=========================================================
- // result false, if no more id are found
-
- bool getNextMapId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId)
- {
- bool result = false;
- unsigned int i;
- for (i=pStartPos; i<pString.size(); ++i)
- {
- if(pString[i] == ',')
- {
- break;
- }
- }
- if(i>pStartPos)
- {
- std::string idString = pString.substr(pStartPos, i-pStartPos);
- pStartPos = i+1;
- chompAndTrim(idString);
- pId = atoi(idString.c_str());
- result = true;
- }
- return(result);
- }
-
- //=========================================================
- /**
- Block maps from being used.
- parameter: String of map ids. Delimiter = ","
- e.g.: "0,1,590"
- */
-
- void VMapManager::preventMapsFromBeingUsed(const char* pMapIdString)
- {
- if(pMapIdString != NULL)
- {
- unsigned int pos =0;
- unsigned int id;
- std::string confString(pMapIdString);
- chompAndTrim(confString);
- while(getNextMapId(confString, pos, id))
- {
- iIgnoreMapIds.set(id, true);
- }
- }
- }
-
- //=========================================================
-
- int VMapManager::loadMap(const char* pBasePath, unsigned int pMapId, int x, int y)
- {
- int result = VMAP_LOAD_RESULT_IGNORED;
- if(isMapLoadingEnabled() && !iIgnoreMapIds.containsKey(pMapId))
- {
- bool loaded = _loadMap(pBasePath, pMapId, x, y, false);
- if(!loaded)
- {
- // if we can't load the map it might be splitted into tiles. Try that one and store the result
- loaded = _loadMap(pBasePath, pMapId, x, y, true);
- if(loaded)
- {
- iMapsSplitIntoTiles.set(pMapId, true);
- }
- }
- if(loaded)
- {
- result = VMAP_LOAD_RESULT_OK;
- // just for debugging
-#ifdef _VMAP_LOG_DEBUG
- Command c = Command();
- c.fillLoadTileCmd(x, y, pMapId);
- iCommandLogger.appendCmd(c);
-#endif
- }
- else
- {
- result = VMAP_LOAD_RESULT_ERROR;
- }
- }
- return result;
- }
-
- //=========================================================
- // load one tile (internal use only)
-
- bool VMapManager::_loadMap(const char* pBasePath, unsigned int pMapId, int x, int y, bool pForceTileLoad)
- {
- bool result = false;
- std::string dirFileName;
- if(pForceTileLoad || iMapsSplitIntoTiles.containsKey(pMapId))
- {
- dirFileName = getDirFileName(pMapId,x,y);
- }
- else
- {
- dirFileName = getDirFileName(pMapId);
- }
- MapTree* instanceTree;
- if(!iInstanceMapTrees.containsKey(pMapId))
- {
- instanceTree = new MapTree(pBasePath);
- iInstanceMapTrees.set(pMapId, instanceTree);
- }
- else
- instanceTree = iInstanceMapTrees.get(pMapId);
-
- unsigned int mapTileIdent = MAP_TILE_IDENT(x,y);
- result = instanceTree->loadMap(dirFileName, mapTileIdent);
- if(!result) // remove on fail
- {
- if(instanceTree->size() == 0)
- {
- iInstanceMapTrees.remove(pMapId);
- delete instanceTree;
- }
- }
- return(result);
- }
-
- //=========================================================
-
- bool VMapManager::_existsMap(const std::string& pBasePath, unsigned int pMapId, int x, int y, bool pForceTileLoad)
- {
- bool result = false;
- std::string dirFileName;
- if(pForceTileLoad || iMapsSplitIntoTiles.containsKey(pMapId))
- {
- dirFileName = getDirFileName(pMapId,x,y);
- }
- else
- {
- dirFileName = getDirFileName(pMapId);
- }
- std::string fb = pBasePath + dirFileName;
- FILE* df = fopen(fb.c_str(), "rb");
- if(df)
- {
- char lineBuffer[FILENAMEBUFFER_SIZE];
- if (fgets(lineBuffer, FILENAMEBUFFER_SIZE-1, df) != 0)
- {
- std::string name = std::string(lineBuffer);
- chomp(name);
- if(name.length() >1)
- {
- std::string fb2 = pBasePath + name;
- FILE* df2 = fopen(fb2.c_str(), "rb");
- if(df2)
- {
- char magic[8];
- fread(magic,1,8,df2);
- if(!strncmp(VMAP_MAGIC,magic,8))
- result = true;
- fclose(df2);
- }
- }
- }
- fclose(df);
- }
- return result;
- }
-
- //=========================================================
-
- bool VMapManager::existsMap(const char* pBasePath, unsigned int pMapId, int x, int y)
- {
- std::string basePath = std::string(pBasePath);
- if(basePath.length() > 0 && (basePath[basePath.length()-1] != '/' || basePath[basePath.length()-1] != '\\'))
- {
- basePath.append("/");
- }
- bool found = _existsMap(basePath, pMapId, x, y, false);
- if(!found)
- {
- // if we can't load the map it might be splitted into tiles. Try that one and store the result
- found = _existsMap(basePath, pMapId, x, y, true);
- if(found)
- {
- iMapsSplitIntoTiles.set(pMapId, true);
- }
- }
- return found;
- }
-
- //=========================================================
-
- void VMapManager::unloadMap(unsigned int pMapId, int x, int y)
- {
- _unloadMap(pMapId, x, y);
-
-#ifdef _VMAP_LOG_DEBUG
- Command c = Command();
- c.fillUnloadTileCmd(pMapId, x,y);
- iCommandLogger.appendCmd(c);
-#endif
- }
-
- //=========================================================
-
- void VMapManager::_unloadMap(unsigned int pMapId, int x, int y)
- {
- if(iInstanceMapTrees.containsKey(pMapId))
- {
- MapTree* instanceTree = iInstanceMapTrees.get(pMapId);
- std::string dirFileName;
- if(iMapsSplitIntoTiles.containsKey(pMapId))
- {
- dirFileName = getDirFileName(pMapId,x,y);
- }
- else
- {
- dirFileName = getDirFileName(pMapId);
- }
- unsigned int mapTileIdent = MAP_TILE_IDENT(x,y);
- instanceTree->unloadMap(dirFileName, mapTileIdent);
- if(instanceTree->size() == 0)
- {
- iInstanceMapTrees.remove(pMapId);
- delete instanceTree;
- }
- }
- }
-
- //=========================================================
-
- void VMapManager::unloadMap(unsigned int pMapId)
- {
- if(iInstanceMapTrees.containsKey(pMapId))
- {
- MapTree* instanceTree = iInstanceMapTrees.get(pMapId);
- std::string dirFileName = getDirFileName(pMapId);
- instanceTree->unloadMap(dirFileName, 0, true);
- if(instanceTree->size() == 0)
- {
- iInstanceMapTrees.remove(pMapId);
- delete instanceTree;
- }
-#ifdef _VMAP_LOG_DEBUG
- Command c = Command();
- c.fillUnloadTileCmd(pMapId);
- iCommandLogger.appendCmd(c);
-#endif
- }
- }
- //==========================================================
-
- bool VMapManager::isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2)
- {
- bool result = true;
- if(isLineOfSightCalcEnabled() && iInstanceMapTrees.containsKey(pMapId))
- {
- Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
- Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
- if(pos1 != pos2)
- {
- MapTree* mapTree = iInstanceMapTrees.get(pMapId);
- result = mapTree->isInLineOfSight(pos1, pos2);
-#ifdef _VMAP_LOG_DEBUG
- Command c = Command();
- // save the orig vectors
- c.fillTestVisCmd(pMapId,Vector3(x1,y1,z1),Vector3(x2,y2,z2),result);
- iCommandLogger.appendCmd(c);
-#endif
- }
- }
- return(result);
- }
- //=========================================================
- /**
- get the hit position and return true if we hit something
- otherwise the result pos will be the dest pos
- */
- bool VMapManager::getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist)
- {
- bool result = false;
- rx=x2;
- ry=y2;
- rz=z2;
- if(isLineOfSightCalcEnabled())
- {
- if(iInstanceMapTrees.containsKey(pMapId))
- {
- Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
- Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
- Vector3 resultPos;
- MapTree* mapTree = iInstanceMapTrees.get(pMapId);
- result = mapTree->getObjectHitPos(pos1, pos2, resultPos, pModifyDist);
- resultPos = convertPositionToTrinityRep(resultPos.x,resultPos.y,resultPos.z);
- rx = resultPos.x;
- ry = resultPos.y;
- rz = resultPos.z;
-#ifdef _VMAP_LOG_DEBUG
- Command c = Command();
- c.fillTestObjectHitCmd(pMapId, pos1, pos2, resultPos, result);
- iCommandLogger.appendCmd(c);
-#endif
- }
- }
- return result;
- }
-
- //=========================================================
- /**
- get height or INVALID_HEIGHT if to height was calculated
- */
-
- //int gGetHeightCounter = 0;
- float VMapManager::getHeight(unsigned int pMapId, float x, float y, float z, float ray_lenght)
- {
- float height = VMAP_INVALID_HEIGHT_VALUE; //no height
- if(isHeightCalcEnabled() && iInstanceMapTrees.containsKey(pMapId))
- {
- Vector3 pos = convertPositionToInternalRep(x,y,z);
- MapTree* mapTree = iInstanceMapTrees.get(pMapId);
- height = mapTree->getHeight(pos, ray_lenght);
- if(!(height < inf()))
- {
- height = VMAP_INVALID_HEIGHT_VALUE; //no height
- }
-#ifdef _VMAP_LOG_DEBUG
- Command c = Command();
- c.fillTestHeightCmd(pMapId,Vector3(x,y,z),height);
- iCommandLogger.appendCmd(c);
-#endif
- }
- return(height);
- }
-
- //=========================================================
- /**
- used for debugging
- */
- bool VMapManager::processCommand(char *pCommand)
- {
- bool result = false;
- std::string cmd = std::string(pCommand);
- if(cmd == "startlog")
- {
-#ifdef _VMAP_LOG_DEBUG
-
- iCommandLogger.enableWriting(true);
-#endif
- result = true;
- }
- else if(cmd == "stoplog")
- {
-#ifdef _VMAP_LOG_DEBUG
- iCommandLogger.appendCmd(Command()); // Write stop command
- iCommandLogger.enableWriting(false);
-#endif
- result = true;
- }
- else if(cmd.find_first_of("pos ") == 0)
- {
- float x,y,z;
- sscanf(pCommand, "pos %f,%f,%f",&x,&y,&z);
-#ifdef _VMAP_LOG_DEBUG
- Command c = Command();
- c.fillSetPosCmd(convertPositionToInternalRep(x,y,z));
- iCommandLogger.appendCmd(c);
- iCommandLogger.enableWriting(false);
-#endif
- result = true;
- }
- return result;
- }
-
- //=========================================================
- //=========================================================
- //=========================================================
-
- MapTree::MapTree(const char* pBaseDir)
- {
- iBasePath = std::string(pBaseDir);
- if(iBasePath.length() > 0 && (iBasePath[iBasePath.length()-1] != '/' || iBasePath[iBasePath.length()-1] != '\\'))
- {
- iBasePath.append("/");
- }
- iTree = new AABSPTree<ModelContainer *>();
- }
-
- //=========================================================
- MapTree::~MapTree()
- {
- Array<ModelContainer *> mcArray;
- iTree->getMembers(mcArray);
- int no = mcArray.size();
- while(no >0)
- {
- --no;
- delete mcArray[no];
- }
- delete iTree;
- }
- //=========================================================
-
- // just for visual debugging with an external debug class
- #ifdef _DEBUG_VMAPS
- #ifndef gBoxArray
- extern Vector3 p1,p2,p3,p4,p5,p6,p7;
- extern Array<AABox>gBoxArray;
- extern int gCount1, gCount2, gCount3, gCount4;
- extern bool myfound;
- #endif
- #endif
-
- //=========================================================
- /**
- return dist to hit or inf() if no hit
- */
-
- float MapTree::getIntersectionTime(const Ray& pRay, float pMaxDist, bool pStopAtFirstHit)
- {
- float firstDistance = inf();
- IntersectionCallBack<ModelContainer> intersectionCallBack;
- float t = pMaxDist;
- iTree->intersectRay(pRay, intersectionCallBack, t, pStopAtFirstHit, false);
-#ifdef _DEBUG_VMAPS
- {
- if(t < pMaxDist)
- {
- myfound = true;
- p4 = pRay.origin + pRay.direction*t;
- }
- }
-#endif
- if(t > 0 && t < inf() && pMaxDist > t)
- {
- firstDistance = t;
- }
- return firstDistance;
- }
- //=========================================================
-
- bool MapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2)
- {
- bool result = true;
- float maxDist = abs((pos2 - pos1).magnitude());
- // direction with length of 1
- Ray ray = Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
- float resultDist = getIntersectionTime(ray, maxDist, true);
- if(resultDist < maxDist)
- {
- result = false;
- }
- return result;
- }
- //=========================================================
- /**
- When moving from pos1 to pos2 check if we hit an object. Return true and the position if we hit one
- Return the hit pos or the original dest pos
- */
-
- bool MapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist)
- {
- bool result;
- float maxDist = abs((pPos2 - pPos1).magnitude());
- Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
- Ray ray = Ray::fromOriginAndDirection(pPos1, dir);
- float dist = getIntersectionTime(ray, maxDist, false);
- if(dist < maxDist)
- {
- pResultHitPos = pPos1 + dir * dist;
- if(pModifyDist < 0)
- {
- if(abs((pResultHitPos - pPos1).magnitude()) > -pModifyDist)
- {
- pResultHitPos = pResultHitPos + dir*pModifyDist;
- }
- else
- {
- pResultHitPos = pPos1;
- }
- }
- else
- {
- pResultHitPos = pResultHitPos + dir*pModifyDist;
- }
- result = true;
- }
- else
- {
- pResultHitPos = pPos2;
- result = false;
- }
- return result;
- }
-
- //=========================================================
-
- float MapTree::getHeight(const Vector3& pPos, float ray_lenght)
- {
- float height = inf();
- Vector3 dir = Vector3(0,-1,0);
- Ray ray = Ray::fromOriginAndDirection(pPos, dir); // direction with length of 1
- float dist = getIntersectionTime(ray, ray_lenght, false);
- if(dist < inf())
- {
- height = (pPos + dir * dist).y;
- }
- return(height);
- }
-
- //=========================================================
-
- bool MapTree::PrepareTree()
- {
- iTree->balance();
- return true;
- }
-
- bool MapTree::loadMap(const std::string& pDirFileName, unsigned int pMapTileIdent)
- {
- bool result = true;
- if(!hasDirFile(pDirFileName))
- {
- FilesInDir filesInDir;
- result = false;
- std::string fb = iBasePath + pDirFileName;
- FILE* df = fopen(fb.c_str(), "rb");
- if(df)
- {
- char lineBuffer[FILENAMEBUFFER_SIZE];
- result = true;
- bool newModelLoaded = false;
- while(result && (fgets(lineBuffer, FILENAMEBUFFER_SIZE-1, df) != 0))
- {
- std::string name = std::string(lineBuffer);
- chomp(name);
- if(name.length() >1)
- {
- filesInDir.append(name);
- ManagedModelContainer *mc;
- if(!isAlreadyLoaded(name))
- {
- std::string fname = iBasePath;
- fname.append(name);
- mc = new ManagedModelContainer();
- result = mc->readFile(fname.c_str());
- if(result)
- {
- addModelContainer(name, mc);
- newModelLoaded = true;
- }
- }
- else
- {
- mc = getModelContainer(name);
- }
- mc->incRefCount();
- }
- }
- if(result && newModelLoaded)
- {
- iTree->balance();
- }
- if(result && ferror(df) != 0)
- {
- result = false;
- }
- fclose(df);
- if(result)
- {
- filesInDir.incRefCount();
- addDirFile(pDirFileName, filesInDir);
- setLoadedMapTile(pMapTileIdent);
- }
- }
- }
- else
- {
- // Already loaded, so just inc. the ref count if mapTileIdent is new
- if(!containsLoadedMapTile(pMapTileIdent))
- {
- setLoadedMapTile(pMapTileIdent);
- FilesInDir& filesInDir = getDirFiles(pDirFileName);
- filesInDir.incRefCount();
- }
- }
- return (result);
- }
-
- //=========================================================
-
- void MapTree::unloadMap(const std::string& dirFileName, unsigned int pMapTileIdent, bool pForce)
- {
- if(hasDirFile(dirFileName) && (pForce || containsLoadedMapTile(pMapTileIdent)))
- {
- if(containsLoadedMapTile(pMapTileIdent))
- removeLoadedMapTile(pMapTileIdent);
- FilesInDir& filesInDir = getDirFiles(dirFileName);
- filesInDir.decRefCount();
- if(filesInDir.getRefCount() <= 0)
- {
- Array<std::string> fileNames = filesInDir.getFiles();
- bool treeChanged = false;
- for (int i=0; i<fileNames.size(); ++i)
- {
- std::string name = fileNames[i];
- ManagedModelContainer* mc = getModelContainer(name);
- mc->decRefCount();
- if(mc->getRefCount() <= 0)
- {
- iLoadedModelContainer.remove(name);
- iTree->remove(mc);
- delete mc;
- treeChanged = true;
- }
- }
- iLoadedDirFiles.remove(dirFileName);
- if(treeChanged)
- {
- iTree->balance();
- }
- }
- }
- }
-
- //=========================================================
- //=========================================================
-
- void MapTree::addModelContainer(const std::string& pName, ManagedModelContainer *pMc)
- {
- iLoadedModelContainer.set(pName, pMc);
- iTree->insert(pMc);
- }
- //=========================================================
- //=========================================================
- //=========================================================
-}
-
diff --git a/src/shared/vmap/VMapManager.h b/src/shared/vmap/VMapManager.h
deleted file mode 100644
index 8fe38400882..00000000000
--- a/src/shared/vmap/VMapManager.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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 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 _VMAPMANAGER_H
-#define _VMAPMANAGER_H
-
-// load our modified version first !!
-#include "AABSPTree.h"
-#include "ManagedModelContainer.h"
-#include "IVMapManager.h"
-#ifdef _VMAP_LOG_DEBUG
-#include "DebugCmdLogger.h"
-#endif
-#include <G3D/Table.h>
-
-//===========================================================
-
-#define DIR_FILENAME_EXTENSION ".vmdir"
-
-#define FILENAMEBUFFER_SIZE 500
-
-/**
-This is the main Class to manage loading and unloading of maps, line of sight, height calculation and so on.
-For each map or map tile to load it reads a directory file that contains the ModelContainer files used by this map or map tile.
-Each global map or instance has its own dynamic BSP-Tree.
-The loaded ModelContainers are included in one of these BSP-Trees.
-Additionally a table to match map ids and map names is used.
-*/
-
-// Create a value describing the map tile
-#define MAP_TILE_IDENT(x,y) ((x<<8) + y)
-//===========================================================
-
-namespace VMAP
-{
- //===========================================================
-
- class FilesInDir
- {
- private:
- int iRefCount;
- G3D::Array<std::string> iFiles;
- public:
-
- FilesInDir() { iRefCount = 0; }
- void append(const std::string& pName) { iFiles.append(pName); }
- void incRefCount() { ++iRefCount; }
- void decRefCount() { if(iRefCount > 0) --iRefCount; }
- int getRefCount() { return iRefCount; }
- const G3D::Array<std::string>& getFiles() const { return iFiles; }
- };
-
- //===========================================================
- //===========================================================
- //===========================================================
- //===========================================================
-
- class MapTree
- {
- private:
- G3D::AABSPTree<ModelContainer *> *iTree;
-
- // Key: filename, value ModelContainer
- G3D::Table<std::string, ManagedModelContainer *> iLoadedModelContainer;
-
- // Key: dir file name, value FilesInDir
- G3D::Table<std::string, FilesInDir> iLoadedDirFiles;
-
- // Store all the map tile idents that are loaded for that map
- // some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
- G3D::Table<unsigned int, bool> iLoadedMapTiles;
- std::string iBasePath;
-
- private:
- float getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit);
- bool isAlreadyLoaded(const std::string& pName) { return(iLoadedModelContainer.containsKey(pName)); }
- void setLoadedMapTile(unsigned int pTileIdent) { iLoadedMapTiles.set(pTileIdent, true); }
- void removeLoadedMapTile(unsigned int pTileIdent) { iLoadedMapTiles.remove(pTileIdent); }
- bool hasLoadedMapTiles() { return(iLoadedMapTiles.size() > 0); }
- bool containsLoadedMapTile(unsigned int pTileIdent) { return(iLoadedMapTiles.containsKey(pTileIdent)); }
- public:
- ManagedModelContainer *getModelContainer(const std::string& pName) { return(iLoadedModelContainer.get(pName)); }
- const bool hasDirFile(const std::string& pDirName) const { return(iLoadedDirFiles.containsKey(pDirName)); }
- FilesInDir& getDirFiles(const std::string& pDirName) const { return(iLoadedDirFiles.get(pDirName)); }
- public:
- MapTree(const char *pBasePath);
- ~MapTree();
-
- bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2);
- bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist);
- float getHeight(const G3D::Vector3& pPos, float ray_lenght);
-
- bool PrepareTree();
- bool loadMap(const std::string& pDirFileName, unsigned int pMapTileIdent);
- void addModelContainer(const std::string& pName, ManagedModelContainer *pMc);
- void unloadMap(const std::string& dirFileName, unsigned int pMapTileIdent, bool pForce=false);
-
- void getModelContainer(G3D::Array<ModelContainer *>& pArray ) { iTree->getMembers(pArray); }
- const void addDirFile(const std::string& pDirName, const FilesInDir& pFilesInDir) { iLoadedDirFiles.set(pDirName, pFilesInDir); }
- size_t size() { return(iTree->size()); }
- };
-
- //===========================================================
- class MapIdNames
- {
- public:
- std::string iDirName;
- std::string iMapGroupName;
- };
-
- //===========================================================
- class VMapManager : public IVMapManager
- {
- private:
- // Tree to check collision
- G3D::Table<unsigned int , MapTree *> iInstanceMapTrees;
- G3D::Table<unsigned int , bool> iMapsSplitIntoTiles;
- G3D::Table<unsigned int , bool> iIgnoreMapIds;
-
-#ifdef _VMAP_LOG_DEBUG
- CommandFileRW iCommandLogger;
-#endif
- private:
- bool _loadMap(const char* pBasePath, unsigned int pMapId, int x, int y, bool pForceTileLoad=false);
- void _unloadMap(unsigned int pMapId, int x, int y);
- bool _existsMap(const std::string& pBasePath, unsigned int pMapId, int x, int y, bool pForceTileLoad);
-
- public:
- // public for debug
- G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
- G3D::Vector3 convertPositionToTrinityRep(float x, float y, float z) const;
- std::string getDirFileName(unsigned int pMapId) const;
- std::string getDirFileName(unsigned int pMapId, int x, int y) const;
- MapTree* getInstanceMapTree(int pMapId) { return(iInstanceMapTrees.get(pMapId)); }
- public:
- VMapManager();
- ~VMapManager(void);
-
- int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y);
-
- bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y);
-
- void unloadMap(unsigned int pMapId, int x, int y);
- void unloadMap(unsigned int pMapId);
-
- bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
- /**
- fill the hit pos and return true, if an object was hit
- */
- bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist);
- float getHeight(unsigned int pMapId, float x, float y, float z, float ray_lenght);
-
- bool processCommand(char *pCommand); // for debug and extensions
-
- void preventMapsFromBeingUsed(const char* pMapIdString);
- };
-}
-#endif
-
diff --git a/src/shared/vmap/VMapManager2.cpp b/src/shared/vmap/VMapManager2.cpp
new file mode 100644
index 00000000000..c4c13fe7957
--- /dev/null
+++ b/src/shared/vmap/VMapManager2.cpp
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include "VMapManager2.h"
+#include "MapTree.h"
+#include "ModelInstance.h"
+#include "WorldModel.h"
+#include "VMapDefinitions.h"
+
+using G3D::Vector3;
+
+namespace VMAP
+{
+
+ //=========================================================
+
+ VMapManager2::VMapManager2()
+ {
+ }
+
+ //=========================================================
+
+ VMapManager2::~VMapManager2(void)
+ {
+ for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i)
+ {
+ delete i->second;
+ }
+ for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i)
+ {
+ delete i->second.getModel();
+ }
+ }
+
+ //=========================================================
+
+ Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const
+ {
+ Vector3 pos;
+ const float mid = 0.5 * 64.0 * 533.33333333;
+ pos.x = mid - x;
+ pos.y = mid - y;
+ pos.z = z;
+
+ return pos;
+ }
+
+ //=========================================================
+
+ Vector3 VMapManager2::convertPositionToMangosRep(float x, float y, float z) const
+ {
+ Vector3 pos;
+ const float mid = 0.5 * 64.0 * 533.33333333;
+ pos.x = mid - x;
+ pos.y = mid - y;
+ pos.z = z;
+
+ return pos;
+ }
+ //=========================================================
+
+ // move to MapTree too?
+ std::string VMapManager2::getMapFileName(unsigned int pMapId)
+ {
+ std::stringstream fname;
+ fname.width(3);
+ fname << std::setfill('0') << pMapId << std::string(MAP_FILENAME_EXTENSION2);
+ return fname.str();
+ }
+
+ //=========================================================
+ /**
+ Block maps from being used.
+ parameter: String of map ids. Delimiter = ","
+ e.g.: "0,1,590"
+ */
+
+ void VMapManager2::preventMapsFromBeingUsed(const char* pMapIdString)
+ {
+ iIgnoreMapIds.clear();
+ if (pMapIdString != NULL)
+ {
+ std::string map_str;
+ std::stringstream map_ss;
+ map_ss.str(std::string(pMapIdString));
+ while (std::getline(map_ss, map_str, ','))
+ {
+ std::stringstream ss2(map_str);
+ int map_num = -1;
+ ss2 >> map_num;
+ if (map_num >= 0)
+ {
+ std::cout << "ingoring Map " << map_num << " for VMaps\n";
+ iIgnoreMapIds[map_num] = true;
+ // unload map in case it is loaded
+ unloadMap(map_num);
+ }
+ }
+ }
+ }
+
+ //=========================================================
+
+ int VMapManager2::loadMap(const char* pBasePath, unsigned int pMapId, int x, int y)
+ {
+ int result = VMAP_LOAD_RESULT_IGNORED;
+ if (isMapLoadingEnabled() && !iIgnoreMapIds.count(pMapId))
+ {
+ if (_loadMap(pMapId, pBasePath, x, y))
+ result = VMAP_LOAD_RESULT_OK;
+ else
+ result = VMAP_LOAD_RESULT_ERROR;
+ }
+ return result;
+ }
+
+ //=========================================================
+ // load one tile (internal use only)
+
+ bool VMapManager2::_loadMap(unsigned int pMapId, const std::string &basePath, uint32 tileX, uint32 tileY)
+ {
+ InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree == iInstanceMapTrees.end())
+ {
+ std::string mapFileName = getMapFileName(pMapId);
+ StaticMapTree *newTree = new StaticMapTree(pMapId, basePath);
+ if (!newTree->InitMap(mapFileName, this))
+ return false;
+ instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(pMapId, newTree)).first;
+ }
+ return instanceTree->second->LoadMapTile(tileX, tileY, this);
+ }
+
+ //=========================================================
+
+ void VMapManager2::unloadMap(unsigned int pMapId)
+ {
+ InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ instanceTree->second->UnloadMap(this);
+ if (instanceTree->second->numLoadedTiles() == 0)
+ {
+ delete instanceTree->second;
+ iInstanceMapTrees.erase(pMapId);
+ }
+ }
+ }
+
+ //=========================================================
+
+ void VMapManager2::unloadMap(unsigned int pMapId, int x, int y)
+ {
+ InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ instanceTree->second->UnloadMapTile(x, y, this);
+ if (instanceTree->second->numLoadedTiles() == 0)
+ {
+ delete instanceTree->second;
+ iInstanceMapTrees.erase(pMapId);
+ }
+ }
+ }
+
+ //==========================================================
+
+ bool VMapManager2::isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2)
+ {
+ if (!isLineOfSightCalcEnabled()) return true;
+ bool result = true;
+ InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
+ Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
+ if (pos1 != pos2)
+ {
+ result = instanceTree->second->isInLineOfSight(pos1, pos2);
+ }
+ }
+ return result;
+ }
+ //=========================================================
+ /**
+ get the hit position and return true if we hit something
+ otherwise the result pos will be the dest pos
+ */
+ bool VMapManager2::getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist)
+ {
+ bool result = false;
+ rx=x2;
+ ry=y2;
+ rz=z2;
+ if (isLineOfSightCalcEnabled())
+ {
+ InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
+ Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
+ Vector3 resultPos;
+ result = instanceTree->second->getObjectHitPos(pos1, pos2, resultPos, pModifyDist);
+ resultPos = convertPositionToMangosRep(resultPos.x,resultPos.y,resultPos.z);
+ rx = resultPos.x;
+ ry = resultPos.y;
+ rz = resultPos.z;
+ }
+ }
+ return result;
+ }
+
+ //=========================================================
+ /**
+ get height or INVALID_HEIGHT if no height available
+ */
+
+ float VMapManager2::getHeight(unsigned int pMapId, float x, float y, float z)
+ {
+ float height = VMAP_INVALID_HEIGHT_VALUE; //no height
+ if (isHeightCalcEnabled())
+ {
+ InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ Vector3 pos = convertPositionToInternalRep(x,y,z);
+ height = instanceTree->second->getHeight(pos);
+ if (!(height < G3D::inf()))
+ {
+ height = VMAP_INVALID_HEIGHT_VALUE; //no height
+ }
+ }
+ }
+ return height;
+ }
+
+ //=========================================================
+
+ bool VMapManager2::getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
+ {
+ bool result=false;
+ InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ Vector3 pos = convertPositionToInternalRep(x, y, z);
+ result = instanceTree->second->getAreaInfo(pos, flags, adtId, rootId, groupId);
+ // z is not touched by convertPositionToMangosRep(), so just copy
+ z = pos.z;
+ }
+ return(result);
+ }
+
+ bool VMapManager2::GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const
+ {
+ InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(pMapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ LocationInfo info;
+ Vector3 pos = convertPositionToInternalRep(x, y, z);
+ if (instanceTree->second->GetLocationInfo(pos, info))
+ {
+ floor = info.ground_Z;
+ type = info.hitModel->GetLiquidType();
+ if (ReqLiquidType && !(type & ReqLiquidType))
+ return false;
+ if (info.hitInstance->GetLiquidLevel(pos, info, level))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //=========================================================
+
+ WorldModel* VMapManager2::acquireModelInstance(const std::string &basepath, const std::string &filename)
+ {
+ ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
+ if (model == iLoadedModelFiles.end())
+ {
+ WorldModel *worldmodel = new WorldModel();
+ if (!worldmodel->readFile(basepath + filename + ".vmo"))
+ {
+ std::cout << "VMapManager2: could not load '" << basepath << filename << ".vmo'!\n";
+ delete worldmodel;
+ return NULL;
+ }
+ std::cout << "VMapManager2: loading file '" << basepath << filename << "'.\n";
+ model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
+ model->second.setModel(worldmodel);
+ }
+ model->second.incRefCount();
+ return model->second.getModel();
+ }
+
+ void VMapManager2::releaseModelInstance(const std::string &filename)
+ {
+ ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
+ if (model == iLoadedModelFiles.end())
+ {
+ std::cout << "VMapManager2: trying to unload non-loaded file '" << filename << "'!\n";
+ return;
+ }
+ if( model->second.decRefCount() == 0)
+ {
+ std::cout << "VMapManager2: unloading file '" << filename << "'.\n";
+ delete model->second.getModel();
+ iLoadedModelFiles.erase(model);
+ }
+ }
+ //=========================================================
+
+ bool VMapManager2::existsMap(const char* pBasePath, unsigned int pMapId, int x, int y)
+ {
+ return StaticMapTree::CanLoadMap(std::string(pBasePath), pMapId, x, y);
+ }
+
+} // namespace VMAP
diff --git a/src/shared/vmap/VMapManager2.h b/src/shared/vmap/VMapManager2.h
new file mode 100644
index 00000000000..5f03b87b07f
--- /dev/null
+++ b/src/shared/vmap/VMapManager2.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#ifndef _VMAPMANAGER2_H
+#define _VMAPMANAGER2_H
+
+#include "IVMapManager.h"
+#include "Utilities/UnorderedMap.h"
+#include "Platform/Define.h"
+#include <G3D/Vector3.h>
+
+//===========================================================
+
+#define MAP_FILENAME_EXTENSION2 ".vmtree"
+
+#define FILENAMEBUFFER_SIZE 500
+
+/**
+This is the main Class to manage loading and unloading of maps, line of sight, height calculation and so on.
+For each map or map tile to load it reads a directory file that contains the ModelContainer files used by this map or map tile.
+Each global map or instance has its own dynamic BSP-Tree.
+The loaded ModelContainers are included in one of these BSP-Trees.
+Additionally a table to match map ids and map names is used.
+*/
+
+//===========================================================
+
+namespace VMAP
+{
+ class StaticMapTree;
+ class WorldModel;
+
+ class ManagedModel
+ {
+ public:
+ ManagedModel(): iModel(0), iRefCount(0) {}
+ void setModel(WorldModel *model) { iModel = model; }
+ WorldModel *getModel() { return iModel; }
+ void incRefCount() { ++iRefCount; }
+ int decRefCount() { return --iRefCount; }
+ protected:
+ WorldModel *iModel;
+ int iRefCount;
+ };
+
+ typedef UNORDERED_MAP<uint32 , StaticMapTree *> InstanceTreeMap;
+ typedef UNORDERED_MAP<std::string, ManagedModel> ModelFileMap;
+
+ class VMapManager2 : public IVMapManager
+ {
+ protected:
+ // Tree to check collision
+ ModelFileMap iLoadedModelFiles;
+ InstanceTreeMap iInstanceMapTrees;
+ // UNORDERED_MAP<unsigned int , bool> iMapsSplitIntoTiles;
+ UNORDERED_MAP<unsigned int , bool> iIgnoreMapIds;
+
+ bool _loadMap(uint32 pMapId, const std::string &basePath, uint32 tileX, uint32 tileY);
+ /* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
+
+ public:
+ // public for debug
+ G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
+ G3D::Vector3 convertPositionToMangosRep(float x, float y, float z) const;
+ static std::string getMapFileName(unsigned int pMapId);
+
+ VMapManager2();
+ ~VMapManager2(void);
+
+ int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y);
+
+ void unloadMap(unsigned int pMapId, int x, int y);
+ void unloadMap(unsigned int pMapId);
+
+ bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
+ /**
+ fill the hit pos and return true, if an object was hit
+ */
+ bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist);
+ float getHeight(unsigned int pMapId, float x, float y, float z);
+
+ bool processCommand(char *pCommand) { return false; } // for debug and extensions
+
+ void preventMapsFromBeingUsed(const char* pMapIdString);
+ bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
+ bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const;
+
+ WorldModel* acquireModelInstance(const std::string &basepath, const std::string &filename);
+ void releaseModelInstance(const std::string &filename);
+
+ // what's the use of this? o.O
+ virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const
+ {
+ return getMapFileName(pMapId);
+ }
+ virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y);
+ };
+}
+#endif
diff --git a/src/shared/vmap/VMapTools.h b/src/shared/vmap/VMapTools.h
index 86e3367773e..dbbd9af9271 100644
--- a/src/shared/vmap/VMapTools.h
+++ b/src/shared/vmap/VMapTools.h
@@ -1,7 +1,5 @@
/*
-* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
-*
-* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
@@ -10,12 +8,12 @@
*
* 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
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You 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
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _VMAPTOOLS_H
@@ -64,7 +62,7 @@ namespace VMAP
{
// Integer representation of a floating-point value.
-#define IR(x) ((G3D::uint32&)x)
+#define IR(x) (reinterpret_cast<G3D::uint32 const&>(x))
Inside = true;
const G3D::Vector3& MinB = box.low();
@@ -150,4 +148,3 @@ namespace VMAP
};
}
#endif
-
diff --git a/src/shared/vmap/WorldModel.cpp b/src/shared/vmap/WorldModel.cpp
new file mode 100644
index 00000000000..690c77577ae
--- /dev/null
+++ b/src/shared/vmap/WorldModel.cpp
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#include "WorldModel.h"
+#include "VMapDefinitions.h"
+#include "MapTree.h"
+
+using G3D::Vector3;
+using G3D::Ray;
+
+template<> struct BoundsTrait<VMAP::GroupModel>
+{
+ static void getBounds(const VMAP::GroupModel& obj, G3D::AABox& out) { out = obj.GetBound(); }
+};
+
+
+namespace VMAP
+{
+ bool IntersectTriangle(const MeshTriangle &tri, std::vector<Vector3>::const_iterator points, const G3D::Ray &ray, float &distance)
+ {
+ static const float EPS = 1e-5f;
+
+ // See RTR2 ch. 13.7 for the algorithm.
+
+ const Vector3 e1 = points[tri.idx1] - points[tri.idx0];
+ const Vector3 e2 = points[tri.idx2] - points[tri.idx0];
+ const Vector3 p(ray.direction().cross(e2));
+ const float a = e1.dot(p);
+
+ if (abs(a) < EPS) {
+ // Determinant is ill-conditioned; abort early
+ return false;
+ }
+
+ const float f = 1.0f / a;
+ const Vector3 s(ray.origin() - points[tri.idx0]);
+ const float u = f * s.dot(p);
+
+ if ((u < 0.0f) || (u > 1.0f)) {
+ // We hit the plane of the m_geometry, but outside the m_geometry
+ return false;
+ }
+
+ const Vector3 q(s.cross(e1));
+ const float v = f * ray.direction().dot(q);
+
+ if ((v < 0.0f) || ((u + v) > 1.0f)) {
+ // We hit the plane of the triangle, but outside the triangle
+ return false;
+ }
+
+ const float t = f * e2.dot(q);
+
+ if ((t > 0.0f) && (t < distance))
+ {
+ // This is a new hit, closer than the previous one
+ distance = t;
+
+ /* baryCoord[0] = 1.0 - u - v;
+ baryCoord[1] = u;
+ baryCoord[2] = v; */
+
+ return true;
+ }
+ // This hit is after the previous hit, so ignore it
+ return false;
+ }
+
+ class TriBoundFunc
+ {
+ public:
+ TriBoundFunc(std::vector<Vector3> &vert): vertices(vert.begin()) {}
+ void operator()(const MeshTriangle &tri, G3D::AABox &out) const
+ {
+ G3D::Vector3 lo = vertices[tri.idx0];
+ G3D::Vector3 hi = lo;
+
+ lo = (lo.min(vertices[tri.idx1])).min(vertices[tri.idx2]);
+ hi = (hi.max(vertices[tri.idx1])).max(vertices[tri.idx2]);
+
+ out = G3D::AABox(lo, hi);
+ }
+ protected:
+ const std::vector<Vector3>::const_iterator vertices;
+ };
+
+ // ===================== WmoLiquid ==================================
+
+ WmoLiquid::WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type):
+ iTilesX(width), iTilesY(height), iCorner(corner), iType(type)
+ {
+ iHeight = new float[(width+1)*(height+1)];
+ iFlags = new uint8[width*height];
+ }
+
+ WmoLiquid::WmoLiquid(const WmoLiquid &other): iHeight(0), iFlags(0)
+ {
+ *this = other; // use assignment operator...
+ }
+
+ WmoLiquid::~WmoLiquid()
+ {
+ delete[] iHeight;
+ delete[] iFlags;
+ }
+
+ WmoLiquid& WmoLiquid::operator=(const WmoLiquid &other)
+ {
+ if (this == &other)
+ return *this;
+ iTilesX = other.iTilesX;
+ iTilesY = other.iTilesY;
+ iCorner = other.iCorner;
+ iType = other.iType;
+ delete iHeight;
+ delete iFlags;
+ if (other.iHeight)
+ {
+ iHeight = new float[(iTilesX+1)*(iTilesY+1)];
+ memcpy(iHeight, other.iHeight, (iTilesX+1)*(iTilesY+1)*sizeof(float));
+ }
+ else
+ iHeight = 0;
+ if (other.iFlags)
+ {
+ iFlags = new uint8[iTilesX * iTilesY];
+ memcpy(iFlags, other.iFlags, iTilesX * iTilesY);
+ }
+ else
+ iFlags = 0;
+ return *this;
+ }
+
+ bool WmoLiquid::GetLiquidHeight(const Vector3 &pos, float &liqHeight) const
+ {
+ uint32 tx = (pos.x - iCorner.x)/LIQUID_TILE_SIZE;
+ if (tx<0 || tx >= iTilesX) return false;
+ uint32 ty = (pos.y - iCorner.y)/LIQUID_TILE_SIZE;
+ if (ty<0 || ty >= iTilesY) return false;
+ // checking for 0x08 *might* be enough, but disabled tiles always are 0x?F:
+ if ((iFlags[tx + ty*iTilesX] & 0x0F) == 0x0F)
+ return false;
+ //placeholder...use only lower left corner vertex
+ liqHeight = /* iCorner.z + */ iHeight[tx + ty*(iTilesX+1)];
+ return true;
+ }
+
+ uint32 WmoLiquid::GetFileSize()
+ {
+ return 2 * sizeof(uint32) +
+ sizeof(Vector3) +
+ (iTilesX + 1)*(iTilesY + 1) * sizeof(float) +
+ iTilesX * iTilesY;
+ }
+
+ bool WmoLiquid::writeToFile(FILE *wf)
+ {
+ bool result = true;
+ if (result && fwrite(&iTilesX, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&iTilesY, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&iCorner, sizeof(Vector3), 1, wf) != 1) result = false;
+ if (result && fwrite(&iType, sizeof(uint32), 1, wf) != 1) result = false;
+ uint32 size = (iTilesX + 1)*(iTilesY + 1);
+ if (result && fwrite(iHeight, sizeof(float), size, wf) != size) result = false;
+ size = iTilesX*iTilesY;
+ if (result && fwrite(iFlags, sizeof(uint8), size, wf) != size) result = false;
+ return result;
+ }
+
+ bool WmoLiquid::readFromFile(FILE *rf, WmoLiquid *&out)
+ {
+ bool result = true;
+ WmoLiquid *liquid = new WmoLiquid();
+ if (result && fread(&liquid->iTilesX, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result && fread(&liquid->iTilesY, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result && fread(&liquid->iCorner, sizeof(Vector3), 1, rf) != 1) result = false;
+ if (result && fread(&liquid->iType, sizeof(uint32), 1, rf) != 1) result = false;
+ uint32 size = (liquid->iTilesX + 1)*(liquid->iTilesY + 1);
+ liquid->iHeight = new float[size];
+ if (result && fread(liquid->iHeight, sizeof(float), size, rf) != size) result = false;
+ size = liquid->iTilesX * liquid->iTilesY;
+ liquid->iFlags = new uint8[size];
+ if (result && fread(liquid->iFlags, sizeof(uint8), size, rf) != size) result = false;
+ if (!result)
+ delete liquid;
+ out = liquid;
+ return result;
+ }
+
+ // ===================== GroupModel ==================================
+
+ GroupModel::GroupModel(const GroupModel &other):
+ iBound(other.iBound), iMogpFlags(other.iMogpFlags), iGroupWMOID(other.iGroupWMOID),
+ vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(0)
+ {
+ if (other.iLiquid)
+ iLiquid = new WmoLiquid(*other.iLiquid);
+ }
+
+ void GroupModel::setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri)
+ {
+ vertices.swap(vert);
+ triangles.swap(tri);
+ TriBoundFunc bFunc(vertices);
+ meshTree.build(triangles, bFunc);
+ }
+
+ bool GroupModel::writeToFile(FILE *wf)
+ {
+ bool result = true;
+ uint32 chunkSize, count;
+
+ if (result && fwrite(&iBound, sizeof(G3D::AABox), 1, wf) != 1) result = false;
+ if (result && fwrite(&iMogpFlags, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&iGroupWMOID, sizeof(uint32), 1, wf) != 1) result = false;
+
+ // write vertices
+ if (result && fwrite("VERT", 1, 4, wf) != 4) result = false;
+ count = vertices.size();
+ chunkSize = sizeof(uint32)+ sizeof(Vector3)*count;
+ if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
+ if (!count) // models without (collision) geometry end here, unsure if they are useful
+ return result;
+ if (result && fwrite(&vertices[0], sizeof(Vector3), count, wf) != count) result = false;
+
+ // write triangle mesh
+ if (result && fwrite("TRIM", 1, 4, wf) != 4) result = false;
+ count = triangles.size();
+ chunkSize = sizeof(uint32)+ sizeof(MeshTriangle)*count;
+ if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&triangles[0], sizeof(MeshTriangle), count, wf) != count) result = false;
+
+ // write mesh BIH
+ if (result && fwrite("MBIH", 1, 4, wf) != 4) result = false;
+ if (result) result = meshTree.writeToFile(wf);
+
+ // write liquid data
+ if (result && fwrite("LIQU", 1, 4, wf) != 4) result = false;
+ if (!iLiquid)
+ {
+ chunkSize = 0;
+ if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
+ return result;
+ }
+ chunkSize = iLiquid->GetFileSize();
+ if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result) result = iLiquid->writeToFile(wf);
+
+ return result;
+ }
+
+ bool GroupModel::readFromFile(FILE *rf)
+ {
+ char chunk[8];
+ bool result = true;
+ uint32 chunkSize, count;
+ triangles.clear();
+ vertices.clear();
+ delete iLiquid;
+ iLiquid = 0;
+
+ if (result && fread(&iBound, sizeof(G3D::AABox), 1, rf) != 1) result = false;
+ if (result && fread(&iMogpFlags, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result && fread(&iGroupWMOID, sizeof(uint32), 1, rf) != 1) result = false;
+
+ // read vertices
+ if (result && !readChunk(rf, chunk, "VERT", 4)) result = false;
+ if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
+ if (!count) // models without (collision) geometry end here, unsure if they are useful
+ return result;
+ if (result) vertices.resize(count);
+ if (result && fread(&vertices[0], sizeof(Vector3), count, rf) != count) result = false;
+
+ // read triangle mesh
+ if (result && !readChunk(rf, chunk, "TRIM", 4)) result = false;
+ if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result) triangles.resize(count);
+ if (result && fread(&triangles[0], sizeof(MeshTriangle), count, rf) != count) result = false;
+
+ // read mesh BIH
+ if (result && !readChunk(rf, chunk, "MBIH", 4)) result = false;
+ if (result) result = meshTree.readFromFile(rf);
+
+ // write liquid data
+ if (result && !readChunk(rf, chunk, "LIQU", 4)) result = false;
+ if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result && chunkSize > 0)
+ result = WmoLiquid::readFromFile(rf, iLiquid);
+ return result;
+ }
+
+ struct GModelRayCallback
+ {
+ GModelRayCallback(const std::vector<MeshTriangle> &tris, const std::vector<Vector3> &vert):
+ vertices(vert.begin()), triangles(tris.begin()), hit(false) {}
+ bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit)
+ {
+ bool result = IntersectTriangle(triangles[entry], vertices, ray, distance);
+ if (result) hit=true;
+ return hit;
+ }
+ std::vector<Vector3>::const_iterator vertices;
+ std::vector<MeshTriangle>::const_iterator triangles;
+ bool hit;
+ };
+
+ bool GroupModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
+ {
+ if (!triangles.size())
+ return false;
+ GModelRayCallback callback(triangles, vertices);
+ meshTree.intersectRay(ray, callback, distance, stopAtFirstHit);
+ return callback.hit;
+ }
+
+ bool GroupModel::IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const
+ {
+ if (!triangles.size() || !iBound.contains(pos))
+ return false;
+ GModelRayCallback callback(triangles, vertices);
+ Vector3 rPos = pos - 0.1f * down;
+ float dist = G3D::inf();
+ G3D::Ray ray(rPos, down);
+ bool hit = IntersectRay(ray, dist, false);
+ if (hit)
+ z_dist = dist - 0.1f;
+ return hit;
+ }
+
+ bool GroupModel::GetLiquidLevel(const Vector3 &pos, float &liqHeight) const
+ {
+ if (iLiquid)
+ return iLiquid->GetLiquidHeight(pos, liqHeight);
+ return false;
+ }
+
+ uint32 GroupModel::GetLiquidType() const
+ {
+ // convert to type mask, matching MAP_LIQUID_TYPE_* defines in Map.h
+ if (iLiquid)
+ return (1 << iLiquid->GetType());
+ return 0;
+ }
+
+ // ===================== WorldModel ==================================
+
+ void WorldModel::setGroupModels(std::vector<GroupModel> &models)
+ {
+ groupModels.swap(models);
+ groupTree.build(groupModels, BoundsTrait<GroupModel>::getBounds, 1);
+ }
+
+ struct WModelRayCallBack
+ {
+ WModelRayCallBack(const std::vector<GroupModel> &mod): models(mod.begin()), hit(false) {}
+ bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit)
+ {
+ bool result = models[entry].IntersectRay(ray, distance, pStopAtFirstHit);
+ if (result) hit=true;
+ return hit;
+ }
+ std::vector<GroupModel>::const_iterator models;
+ bool hit;
+ };
+
+ bool WorldModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
+ {
+ // small M2 workaround, maybe better make separate class with virtual intersection funcs
+ // in any case, there's no need to use a bound tree if we only have one submodel
+ if (groupModels.size() == 1)
+ return groupModels[0].IntersectRay(ray, distance, stopAtFirstHit);
+
+ WModelRayCallBack isc(groupModels);
+ groupTree.intersectRay(ray, isc, distance, stopAtFirstHit);
+ return isc.hit;
+ }
+
+ class WModelAreaCallback {
+ public:
+ WModelAreaCallback(const std::vector<GroupModel> &vals, const Vector3 &down):
+ prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) {}
+ std::vector<GroupModel>::const_iterator prims;
+ std::vector<GroupModel>::const_iterator hit;
+ float minVol;
+ float zDist;
+ Vector3 zVec;
+ void operator()(const Vector3& point, uint32 entry)
+ {
+ float group_Z;
+ //float pVol = prims[entry].GetBound().volume();
+ //if(pVol < minVol)
+ //{
+ /* if (prims[entry].iBound.contains(point)) */
+ if (prims[entry].IsInsideObject(point, zVec, group_Z))
+ {
+ //minVol = pVol;
+ //hit = prims + entry;
+ if (group_Z < zDist)
+ {
+ zDist = group_Z;
+ hit = prims + entry;
+ }
+#ifdef VMAP_DEBUG
+ const GroupModel &gm = prims[entry];
+ printf("%10u %8X %7.3f,%7.3f,%7.3f | %7.3f,%7.3f,%7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(),
+ gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
+ gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
+#endif
+ }
+ //}
+ //std::cout << "trying to intersect '" << prims[entry].name << "'\n";
+ }
+ };
+
+ bool WorldModel::IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const
+ {
+ if (!groupModels.size())
+ return false;
+ WModelAreaCallback callback(groupModels, down);
+ groupTree.intersectPoint(p, callback);
+ if (callback.hit != groupModels.end())
+ {
+ info.rootId = RootWMOID;
+ info.groupId = callback.hit->GetWmoID();
+ info.flags = callback.hit->GetMogpFlags();
+ info.result = true;
+ dist = callback.zDist;
+ return true;
+ }
+ return false;
+ }
+
+ bool WorldModel::GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const
+ {
+ if (!groupModels.size())
+ return false;
+ WModelAreaCallback callback(groupModels, down);
+ groupTree.intersectPoint(p, callback);
+ if (callback.hit != groupModels.end())
+ {
+ info.hitModel = &(*callback.hit);
+ dist = callback.zDist;
+ return true;
+ }
+ return false;
+ }
+
+ bool WorldModel::writeFile(const std::string &filename)
+ {
+ FILE *wf = fopen(filename.c_str(), "wb");
+ if (!wf)
+ return false;
+
+ bool result = true;
+ uint32 chunkSize, count;
+ result = fwrite(VMAP_MAGIC,1,8,wf) == 8;
+ if (result && fwrite("WMOD", 1, 4, wf) != 4) result = false;
+ chunkSize = sizeof(uint32) + sizeof(uint32);
+ if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&RootWMOID, sizeof(uint32), 1, wf) != 1) result = false;
+
+ // write group models
+ count=groupModels.size();
+ if (count)
+ {
+ if (result && fwrite("GMOD", 1, 4, wf) != 4) result = false;
+ //chunkSize = sizeof(uint32)+ sizeof(GroupModel)*count;
+ //if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
+ if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
+ for (uint32 i=0; i<groupModels.size() && result; ++i)
+ result = groupModels[i].writeToFile(wf);
+
+ // write group BIH
+ if (result && fwrite("GBIH", 1, 4, wf) != 4) result = false;
+ if (result) result = groupTree.writeToFile(wf);
+ }
+
+ fclose(wf);
+ return result;
+ }
+
+ bool WorldModel::readFile(const std::string &filename)
+ {
+ FILE *rf = fopen(filename.c_str(), "rb");
+ if (!rf)
+ return false;
+
+ bool result = true;
+ uint32 chunkSize, count;
+ char chunk[8]; // Ignore the added magic header
+ if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) result = false;
+
+ if (result && !readChunk(rf, chunk, "WMOD", 4)) result = false;
+ if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result && fread(&RootWMOID, sizeof(uint32), 1, rf) != 1) result = false;
+
+ // read group models
+ if (result && readChunk(rf, chunk, "GMOD", 4))
+ {
+ //if (fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
+
+ if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
+ if (result) groupModels.resize(count);
+ //if (result && fread(&groupModels[0], sizeof(GroupModel), count, rf) != count) result = false;
+ for (uint32 i=0; i<count && result; ++i)
+ result = groupModels[i].readFromFile(rf);
+
+ // read group BIH
+ if (result && !readChunk(rf, chunk, "GBIH", 4)) result = false;
+ if (result) result = groupTree.readFromFile(rf);
+ }
+
+ fclose(rf);
+ return result;
+ }
+}
diff --git a/src/shared/vmap/WorldModel.h b/src/shared/vmap/WorldModel.h
new file mode 100644
index 00000000000..f12efed4f5d
--- /dev/null
+++ b/src/shared/vmap/WorldModel.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.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
+ */
+
+#ifndef _WORLDMODEL_H
+#define _WORLDMODEL_H
+
+#include <G3D/HashTrait.h>
+#include <G3D/Vector3.h>
+#include <G3D/AABox.h>
+#include <G3D/Ray.h>
+#include "BIH.h"
+
+#include "Platform/Define.h"
+
+namespace VMAP
+{
+ class TreeNode;
+ struct AreaInfo;
+ struct LocationInfo;
+
+ class MeshTriangle
+ {
+ public:
+ MeshTriangle(){};
+ MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) {};
+
+ uint32 idx0;
+ uint32 idx1;
+ uint32 idx2;
+ };
+
+ class WmoLiquid
+ {
+ public:
+ WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type);
+ WmoLiquid(const WmoLiquid &other);
+ ~WmoLiquid();
+ WmoLiquid& operator=(const WmoLiquid &other);
+ bool GetLiquidHeight(const Vector3 &pos, float &liqHeight) const;
+ uint32 GetType() const { return iType; }
+ float *GetHeightStorage() { return iHeight; }
+ uint8 *GetFlagsStorage() { return iFlags; }
+ uint32 GetFileSize();
+ bool writeToFile(FILE *wf);
+ static bool readFromFile(FILE *rf, WmoLiquid *&liquid);
+ private:
+ WmoLiquid(): iHeight(0), iFlags(0) {};
+ uint32 iTilesX; //!< number of tiles in x direction, each
+ uint32 iTilesY;
+ Vector3 iCorner; //!< the lower corner
+ uint32 iType; //!< liquid type
+ float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
+ uint8 *iFlags; //!< info if liquid tile is used
+ };
+
+ /*! holding additional info for WMO group files */
+ class GroupModel
+ {
+ public:
+ GroupModel(): iLiquid(0) {}
+ GroupModel(const GroupModel &other);
+ GroupModel(uint32 mogpFlags, uint32 groupWMOID, const AABox &bound):
+ iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) {}
+ ~GroupModel() { delete iLiquid; }
+
+ //! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
+ void setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri);
+ void setLiquidData(WmoLiquid *liquid) { iLiquid = liquid; }
+ bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
+ bool IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const;
+ bool GetLiquidLevel(const Vector3 &pos, float &liqHeight) const;
+ uint32 GetLiquidType() const;
+ bool writeToFile(FILE *wf);
+ bool readFromFile(FILE *rf);
+ const G3D::AABox& GetBound() const { return iBound; }
+ uint32 GetMogpFlags() const { return iMogpFlags; }
+ uint32 GetWmoID() const { return iGroupWMOID; }
+ protected:
+ G3D::AABox iBound;
+ uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
+ uint32 iGroupWMOID;
+ std::vector<Vector3> vertices;
+ std::vector<MeshTriangle> triangles;
+ BIH meshTree;
+ WmoLiquid *iLiquid;
+ };
+ /*! Holds a model (converted M2 or WMO) in its original coordinate space */
+ class WorldModel
+ {
+ public:
+ WorldModel(): RootWMOID(0) {}
+
+ //! pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
+ void setGroupModels(std::vector<GroupModel> &models);
+ void setRootWmoID(uint32 id) { RootWMOID = id; }
+ bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
+ bool IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const;
+ bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const;
+ bool writeFile(const std::string &filename);
+ bool readFile(const std::string &filename);
+ protected:
+ uint32 RootWMOID;
+ std::vector<GroupModel> groupModels;
+ BIH groupTree;
+ };
+} // namespace VMAP
+
+#endif // _WORLDMODEL_H
diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist
index cdc563bcf2d..3b6d20e093d 100644
--- a/src/trinitycore/trinitycore.conf.dist
+++ b/src/trinitycore/trinitycore.conf.dist
@@ -174,7 +174,11 @@ EAIErrorLevel = 2
# Check LOS for pets, to avoid them going through walls etc.
# Default: 0 (disable, less CPU usage)
# 1 (enable, each pet attack command will check for LOS)
-#
+#
+# vmap.enableIndoorCheck
+# Enable/Disable VMap based indoor check to remove outdoor-only auras (mounts etc.)
+# Default: 0 (disabled)
+#
# DetectPosCollision
# Check final move position, summon position, etc for visible collision
# with other objects or wall (wall only if vmaps are enabled)
@@ -243,6 +247,7 @@ vmap.enableHeight = 0
vmap.ignoreMapIds = "369"
vmap.ignoreSpellIds = "7720"
vmap.petLOS = 0
+vmap.enableIndoorCheck = 0
DetectPosCollision = 1
TargetPosRecalculateRange = 1.5
UpdateUptimeInterval = 10